Last updated by admin 4 years ago
Grails ???????
??????????
{excerpt:hidden=true} A controller handles requests and creates or prepares the response. They can generate the response or delegate to a view. To create a controller simply create a class whose name ends with "Controller" and place it within the "grails-app/controllers" directory.{excerpt} ?????????????????????????????????????????????????????????????????????????????????????"Controller"???????????"grails-app/controllers"??????????????{excerpt:hidden=true} The first part of your controller name is mapped to a URI and each action defined within your controller maps to URI within the controller name URI.{excerpt} ????????????????URI????????????????????????????URI?????????????{excerpt:hidden=true} Controllers are request-scoped. A new instance is created for each request. {excerpt} ???????????????????? ??????????????????????? Grails??????????
{excerpt:hidden=true} If you're lazy you can create a controller using the "create-controller" target which will prompt for the name of your controller:{excerpt} ??????????"create-controller" ??????????????????????????????????????????grails create-controller
class BookController { … }????????
{excerpt:hidden=true} A controller can have multiple closure properties. Each of these properties maps to a URI:{excerpt} ??????????????????????????????????????????????URI?????????class BookController {
def list = { // do controller logic
// create model return model
};
}?????????????
{excerpt:hidden=true} There are 2 ways to set the default action (ie the action that is executed if no only the controller name is included in the uri), the simplest way is to merely create an action called index ??????????????????2?????????(????????uri??????????????????????)????????? "index" ??????????????????def index = {
redirect(action:list)
}def defaultAction = "list"????????????? {excerpt:hidden=true} Restricting Access To Actions {excerpt}
{excerpt:hidden=true} By default all controller actions are accessible using any HTTP request method (GET, PUT, POST, etc...). The documentation for HTTP Method Restrictions explains how to restrict access to certain actions. {excerpt} ???????????????????????????????????????HTTP?????????????????????????????????????????request??????session??????
{excerpt:hidden=true} Every controller has a number of properties inject into them at runtime, these make it possible to access the request, session etc. For a full reference on these please see the Dynamic Methods Reference {excerpt} ????????????????request?session?????????????????????????????????????? ????????????????????????????class BookController {
def find = {
def findBy = params["findBy"]
def appContext = servletContext["appContext"]
def loggedUser = session["logged_user"] // do stuff
// return model
return model
};
}????????????? {excerpt:hidden=true} Using Flash Scope {excerpt}
{excerpt:hidden=true} Flash scope is a concept introduction by Rails and essentially is a temporary store for attributes that should be available for the next request and the request only, after which they are cleared. This is useful for setting a message directly before redirection for example: {excerpt} ???????????Rails???????????????????????????????????????????????????????????(????????????????)????????????????????????????????????def delete = {
def b = Book.get( params['id'] )
if(!b) {
flash['message'] = "User not found for id ${params['id']}"
redirect(action:list)
}
… // remaining code
}???????????????????
{excerpt:hidden=true} Request parameters get passed into web applications as strings, causing a typical scenario of having to convert each string value into its equivalent object representation. With Grails domain classes this is made simple by the "properties" property: {excerpt} ????????????????????????????????????????????????????????????????Grails ????????? "properties" ????????????????????????def save = {
def b = new Book()
b.properties = params
b.save()
}def sc = new SaveCommand()
bindData(sc, params)?????? {excerpt:hidden=true} Returning the Model {excerpt}
{excerpt:hidden=true} A model is essentially a map that the view uses when rendering. There are a couple of ways to return a model, the first way is to explicity return a map instance: {excerpt} ????????????????????????????????????????????????????1??????Map????????????????def show = {
def b = Book.get( params['id'] )
return [ book : b ]
}class BookController {
List books
List authors
def list = {
books = Book.list()
authors = Author.list()
}
}??????????????
{excerpt:hidden=true} Sometimes its easier (typically with Ajax applications) to render snippets of text or code to the response directly from the controller. For this the highly flexible "render" method can be used: {excerpt} ????????????????????????????????????????????????(Ajax???)?????????? "render" ????????????render "Hello World!"// ???????????
render {
for(b in books) {
div(id:b.id, b.title)
}
}
// ?????????????
render(view:'show')
// ??????????????????????????????
render(template:'book_template', collection:Book.list())
// ??????????????????????????????
render(text:"<xml>some xml</xml>",contentType:"text/xml",encoding:"UTF-8")?????????????&?????? {excerpt:hidden=true} Action Redirection & Chaining {excerpt}
{excerpt:hidden=true} Actions can be redirected using the "redirect" method present in all controllers: {excerpt} ??????? "redirect" ????????????????????????????????class OverviewController {
def login = {} def find = {
if(!session["logged_user"])
redirect(action:login)
.....
};
}redirect(action:login)
// ??
redirect(action:"/another/action")
// ??
redirect(controller:'home',action:'index')redirect(action:"/another/action", params:["myparam":"myvalue"])
class ChainController {
def firstInChain = {
chain(action:secondInChain,model:["step1":new Object()])
}
def secondInChain = {
chain(action:thirdInChain,model:["step2":new Object()])
};
def thirdInChain= {
return ["step3":new Object()])
};
}["step1":object1, "step2":object2, "step3":object3]
class ChainController { def nextInChain = {
def model = chainModel["myModel"]
.....
};
}chain(action:"/another/action", model:["step1":object1], params:["myparam":"param1"])
????????????? {excerpt:hidden=true} Action Interceptors {excerpt}
?? {excerpt:hidden=true} Introduction {excerpt}
{excerpt:hidden=true} Often it is useful to intercept processing based on either request, session or application state. This can be achieved via action interceptors. There are currently 2 types of interceptors: before and after. {excerpt} ??????????????????????????????????????????????????????????????????????????2???????????????? before ? afterBefore ??????? {excerpt:hidden=true} Before Interception {excerpt}
{excerpt:hidden=true} The 'before' interceptor intercepts processing before the action is executed. If it returns 'false' then the following action will not be executed. The interceptor can be defined for all actions as follows: {excerpt} 'before' ???????????????????????????????"false" ?????????????????????????????????????????????????????def beforeInterceptor = {
println "Tracing action ${actionUri}"
}def beforeInterceptor = [action:this.&auth,except:'login'] // defined as a regular method so its private def auth() { if(!session.user) { redirect(action:'login') return false } } def login = { // display login page }
After ??????? {excerpt:hidden=true} After Interception {excerpt}
{excerpt:hidden=true} To define an interceptor that is executed after an action use the 'afterInterceptor' property: {excerpt} ?????????????????????????????????? 'afterInterceptor' ?????????????def afterInterceptor = { model ->
println "Tracing action ${actionUri}"
}????????? {excerpt:hidden=true} Interception Conditions {excerpt}
{excerpt:hidden=true} Rails users will be familiar with the authentication example and how the 'except' condition was used when executing the interceptor (interceptors are called 'filters' in Rails, this terminology conflicts with the servlet filter terminology in Java land): {excerpt} Rails???????????????????????????? 'except' ??????????????????????????(????????Rails?? 'filters' ??????????????Java?servlet?????????????)def beforeInterceptor = [action:this.&auth,except:'login']def beforeInterceptor = [action:this.&auth,except:['login','register']]def beforeInterceptor = [action:this.&auth,only:['secure']]???????????? {excerpt:hidden=true} Handling File Uploads {excerpt}
{excerpt:hidden=true} To upload a file the first step is to create a multipart form like the one below: {excerpt} ??????????????????????????????????????????Upload Form: <br /> <g:form action="upload" method="post" enctype="multipart/form-data"> <input type="file" name="myFile" /> <input type="submit" /> </g:form>
def upload = {
def f = request.getFile('myFile')
if(!f.empty) {
f.transferTo( new File('someotherloc') )
}
else {
flash.message = 'file cannot be empty'
redirect(action:'uploadForm')
}
}class Image {
byte[] myFile
}def img = new Image()
img.properties = paramsclass Image {
String myFile
}class UploadCommand {
byte[] myFile
}def upload = {
def uc = new UploadCommand()
bindData(uc, params)
assert uc.myFile != null
}?????????????? {excerpt:hidden=true} Injecting services into controllers {excerpt}
{excerpt:hidden=true} Controllers may use services to delegate requests to business logic. To have these resources injected add corresponding properties to the controller. {excerpt} ??????????????????????????????????????????????????????????????????????????????????CountryService countryService



