Grails(7)Guide Book Chapter 8 The Web Layer Controller

Grails(7)Guide Book Chapter 8 The Web Layer Controller
7.1.4 Redirects and Chaining
Redirects
Actions can be redirected using redirect controller method:
class OverviewController {
     def login() {}
     def find(){
          if(!session.user){
               redirect(action: 'login')
               return
          }
          ...
     }
}

Call the action in the same controller class:
redirect(action: login)

Redirect to another controller
redirect(controller: 'home', action: 'index')

A URI for a resource relative the application context path:
redirect(uri: "/login.html")

Or redirect to a full URL:
redirect(url: "http://grails.org")

Parameters can optionally be passed from one action to the next using the params argument of the method:
redirect(action: 'myaction', params: [myparam: "myvalue"]

Since the params object is a Map, we can use it to pass the current request parameters from one action to the next:
redirect(action: "next", params: params)

Fragment
redirect(controller: "test", action: "show", fragment: "profile")

Chaining

7.1.5 Controller Interceptors
Before Interception
The beforeInterceptor intercepts processing before the action is executed. If it returns false, then the intercepted action will not be executed.
def beforeInterceptor = {
     println "Tracing action ${actionUri}"
}

The above is declared inside the body of the controller definition.

def beforeInterceptor = [action: this.&auth, exempt: 'login']

private auth(){
     if(!session.user){
          redirect(action: 'login')
          return false   // the original action will not execute
     }
}

def login(){}

The above code defines a method called auth. A private method is used so that it is not exposed as an action to the outside world. The beforeInterceptor then defines an interceptor that is used on all actions except the login action.

After Interception
def afterInterceptor = { model ->
     println "Tracing action ${actionUri}"
}

The after interceptor takes the resulting model as an argument and can hence manipulate the model or response.

def afterInterceptor = { model, modelAndView ->
     println "Current view is ${modelAndview.viewname}"
     if(model.someVar) modelAndView.viewName = "/mycontroller/someotherview"
     println "View is now ${modelAndView.viewName}"
}

Interception Conditions
def beforeInterceptor = [action: this.&auth, except: ['login', 'register']]

except if for exception for our interceptors for all the other actions.

only is the only condition for the only action we intercept.
def beforeInterceptor = [action: this.&auth, only: ['secure']]

7.1.6 Data Binding
Binding Request Data to the Model
def save(){
     def b = new Book(params)
     b.save()
}

That is magic, the data binding happens within the code new Book(params). By passing the params object to the domain class constructor Grails automatically recognizes that you are trying to bind from request parameters.

We can also use properties to bind the parameters to existing instance:
def save(){
     def b = Book.get(params.id)
     b.properties = params
     b.save()
}

Data binding and Single-ended Associations
…snip…

Data binding with Multiple domain classes
/book/save?book.title=booktitle&author.name=Carl

def b = new Book(params.book)
def a = new Author(params.author)

Data Binding and Action Arguments
class AccountingController {
     //accountNumber will be initialized with the value of params.accountNumber
     //accountType will be initialized with params.accountType
     def displayInvoice(String accountNumber, int accountType){
     }
}

Data Binding and Security concerns
def p = Person.get(1)
p.properties['firstName', 'lastName'] = params

In this case, only the firstName and lastName properties will be bound.

Or, we can exclude some params

def p = new Person()
bindData(p, params, [exclude: 'dateOfBirth'])

Or, including some certain properties:

def p = new Person()
bindData(p, params, [include: ['firstName', 'lastName']])

7.1.7 XML and JSON Responses
Using the render method to output XML
def list(){
     def results = Book.list()
     render(contentType: "text/xml") {
          books {
               for (b in results){
                    book(title: b.title)
               }
          }
     }
}

<books>
     <book title="The Stand" />
     <book title="The God" />
</books>

Using the render method to output JSON
def list(){
     def results = Book.list()
     render(contentType: "text/json"){
          books = array {
               for(b in results){
                    book title: b.title
               }
          }
     }
}

[
     {title: "The Stand"},
     {title: "The God"}
]

Automatic XML Marshalling
import grails.converters.*
render Book.list() as XML

Or

def xml = Book.list().encodeAsXML()
render xml

Automatic JSON Marshalling
render Book.list(0 as JSON

Or encodeAsJSON

7.1.8 More on JSONBuilder

7.1.9 Uploading Files
Programmatic File Uploads
Grails supports file uploads using Spring's MultipartHttpServletRequest interface.
Upload Form: <br />
<g:uploadForm action="upload">
     <input type="file" name="myFile" />
     <input type="submit" />
</g:uploadForm>

uploadForm tag conveniently adds the enctype="multipart/form-data"

def upload(){
     def f = request.getFile('myFile')
     if(f.empty) {
          flash.message = 'file cannot be empty'
          render(view: 'uploadForm')
          return
     }
     f.transferTo(new File('/some/local/dir/myfile.txt'))
     response.sendError(200,'Done')
}

File Uploads through Data Binding
class Image {
     byte[] myFile
    
     static constraints = {
          myFile maxSize: 1024 * 1024 *2
     }
}

def img = new Image(params)

7.1.10 Command Objects
7.1.11 Handling Duplicate Form Submissions
<g:form useToken="true" …>

withForm {
     //good request
}.invalidToken {
     //bad request
}

<g:if test="${flash.invalidToken}" >
     Don't click the button twice!
</g:if>

7.1.12 Simple Type Converters
Type Conversion Method
def total = params.int('total')

def total = params.int('total', 42)

Handling Multi Parameters
for (name in params.list('name')){
     println name
}

References:
http://grails.org/doc/latest/guide/index.html
http://grails.org/doc/latest/guide/theWebLayer.html#redirectsAndChaining


猜你喜欢

转载自sillycat.iteye.com/blog/1758119
今日推荐