mrice00 2013-01-01
Grails(6)GuideBookChapter7TheWebLayer
7TheWebLayer
7.1Controllers
Acontrollercangeneratetheresponsedirectlyordelegatetoaview.
Tocreateacontroller,simplycreateaclasswhosenameendswithControllerinthegrails-app/controllersdirectory.
ThedefaultURLMappingconfigurationensuresthatthefirstpartofyourcontrollernameismappedtoaURIandeachactiondefinedwithinyourcontrollermapstotheURIswithinthecontrollernameURI.
7.1.1UnderstandingControllersandActions
Creatingacontroller
Thereare2commandscreate-controllerandgenerate-controller
>grailscreate-controllerbook
Tocreateafile/grails-app/controllers/myapp/BookController.groovy
CreatingActions
Acontrollercanhavemultiplepublicactionmethods,eachonemapstoaURI
classBookController{
deflist(){
//docontrollerlogic,getamodel
returnmodel
}
}
ThismethodwillmaptotheURI/book/list
PublicMethodsasActions
TheDefaultAction
ThedefaultactionoftheController,forexample,if/bookishit,theactionthatiscalledwhenthedefaultURIisrequestedisdictatedbythefollowingrules.
1.Ifthereisonlyoneaction,itisthedefault
2.Ifyouhaveanactionnamedindex,itisthedefault
3.AlternativelyyoucansetitexplicitlywiththedefaultActionproperty.
staticdefaultAction="list"
7.1.2ControllersandScopes
AvailableScopes
Scopesarehash-likeobjectswhereyoucanstorevariables.
servletContext-applicationscope,instanceofSevletContent
session-aninstanceofHttpSession
request-aninstanceofHttpServletRequest
params-mutablemapofincomingrequestquerystringorPOSTparameters
flash-
AccessingScopes
classBookController{
deffind(){
deffindBy=params["findBy"]
defappContext=request["foo"]
defloggedUser=session["logged_user"]
}
}
Orwecanvisittheparameterslikethis
deffind(){
deffindBy=params.findBy
defappContext=request.foo
defloggedUser=session.logged_user
}
UsingFlashScope
Flashscopeasatemporarystoretomakeattributesavailableforthisrequestandthenextrequestonly.Afterwardstheattributesarecleared.
Thisisreallyusefulforsettingamessagedirectlybeforeredirecting.
defdelete(){
defb=Book.get(params.id)
if(!b){
flash.message="Usernotfoundforid${params.id}"
redirect(action:list)
}
…snip...
}
ScopedControllers
Thereareseveralscopessupportedbygrails:
prototype(default)-Anewcontrollerwillbecreatedforeachrequest.
session-Onecontrolleriscreatedforthescopeofausersession
singleton-Onlyoneinstanceofthecontrollereverexists
Toconfigurethatincontroller
staticscope="singleton"
ToconfigurethatforallthecontrollersinConfig.groovy
grails.controllers.defaultScope="singleton"
7.1.3ModelsandViews
ReturningtheModel
AmodelisaMapthattheviewuseswhenrendering.
defshow(){
[book:Book.get(params.id)]
}
classBookController{
Listbooks
Listauthors
deflist(){
books=Book.list()
authors=Author.list()
}
}
Thesearefordefaultsettings,wecanuseModelAndViewdirectly.
defindex(){
deffavoriteBooks=…
returnnewModelAndView("/book/list",[bookList:favoriteBooks])
}
Onethingtobearinmindisthatcertainvariablenamescannotbeused
attributes,application
SelectingtheView
FortheshowAction,
classBookController{
defshow(){
[book:Book.get(params.id)]
}
}
Grailswilllookforaviewatthelocationgrails-app/views/book/show.gsp
Ifwewanttocontrolthat,weneedtorendertoadifferentview,weuserendermethod:
defshow(){
defmap=[book:Book.get(params.id)]
render(view:"display",model:map)//grails-app/views/book/display.gsp
}
defshow(){
defmap=[book:Book.get(params.id)]
render(view:"/shared/display",model:map)//grails-app/views/shared/display.gsp
}
RenderingaResponse
Rendersnippetsoftextorcodestotheresponsedirectlyfromthecontroller.
render"HelloSillycat!"
render(text:"<xml>SomeXml</xml>",contentType:"text/xml",encoding:"UTF-8")
References:
http://grails.org/doc/latest/guide/index.html
http://grails.org/doc/latest/guide/theWebLayer.html