8 Creating controllers - Reference Documentation
Authors: Alejandro GarcĂa Granados
Version: 0.4
8 Creating controllers
The Optimus plugin generates views for you in a similar way that Grails does, but the first one uses the 3.0.0 version of the Twitter Bootstrap framework and the Grails AJAX support, so controllers should be a bit different.You can use the create-controller-class command:grails create-controller-class [domainClass]
mypackage.Person
. The class generated in grails-app/controllers/mypackage/PersonController.groovy
will look like this:
package mypackageclass PersonController { static allowedMethods = [ index:'GET', content:'GET', list:'GET', create:'GET', save:'POST', edit:'GET', update:'POST', delete:'POST' ] def personService def crackingService def index() { redirect( action:'content', params:params ) } def content() { renderList( 'content' ) } def list() { renderList( 'list' ) } def create() { def model = [ personInstance:new Person( params ) ] render( template:'form', model:model ) } def save() { def person = new Person( params ) saveOnDb( person, 'create', 'person.created.message' ) } def edit( Long id ) { def map = get( id ) if ( !map ) return map.edit = true render( template:'form', model:map ) } def update( Long id ) { def map = get( id ) if ( !map ) return map.personInstance.properties = params map.edit = true saveOnDb( map.personInstance, 'update', 'person.updated.message', true ) } def delete( Long id ) { def map = get( id ) if ( !map ) return personService.delete( map.personInstance ) flash.listMessage = message( code:'default.deleted.message', args:[ message( code:'person.label', default:'Person' ), id ] ) redirect( action:'content' ) } private void renderList( template ) { def model = [:] def result = personService.list( params ) model.items = result.items model.total = result.total render( template:template, model:model ) } private Map get( Long id ) { if ( id == null ) { notifyCrack() return null } def person = personService.get( id ) if ( !person ) { notifyCrack() return null } [ personInstance:person ] } private void saveOnDb( person, method, msg, edit = false ) { try { personService."${method}"( person ) } catch ( IllegalArgumentException e ) { render( template:'form', model:[ personInstance:person, edit:edit ] ) return } flash.formMessage = message( code:"default.${edit?'updated':'created'}.message", args:[ message( code:'person.label', default:'Person' ), person.id]) redirect( action:'edit', id:person.id ) } private void notifyCrack() { crackingService.notify( request, params ) redirect( controller:'logout' ) }}
CrackingService
. This one is automatically generated and it is invoked when the application tries to get an instance that doesn't exists (get
method). Generally, this can be reached by cracking the web application, which is always unavoidable but you can handle it. The default implementation of the CrackingService
is shown in the following lines:
package mypackageimport javax.servlet.http.HttpServletRequestclass CrackingService { void notify( HttpServletRequest request, Map params ) { def message = "Request ${request.requestURL}" message << " from ${request.remoteAddr}" message << " and params ${params}" message << " has been detected as unusual activity" println message.toString() }}
You realized that thenotifyCrack
method in thePersonController
makes a redirect to theLogout
controller. This is due to the compatibility with the Spring Security Plugin in the near future, but you can of course modify this functionality.