(快速参考)

withFormat

目的

根据传入请求的 Accept 标头、格式参数或 URI 扩展名渲染不同的响应。请参阅 内容协商 以了解更多信息。

示例

import grails.converters.XML

class BookController {

    def list() {
        def books = Book.list()

        withFormat {
            html bookList:books
            js { render "alert('hello')" }
            xml { render books as XML }
        }
    }
}

说明

withFormat 接受一个闭包,其中包含与您想要响应的不同内容类型相对应的方法。例如

withFormat {
    html bookList: books
    js { render "alert('hello')" }
    xml { render books as XML }
}

此处调用三个方法,分别为 htmljsxml,它们使用 grails-app/conf/application.yml 中配置的 MIME 类型名称(请参阅 内容协商 以了解更多信息)。调用 html 会接受一个模型(一个 Map),该模型会传递给视图。Grails 会搜索名为 grails-app/views/book/list.html.gsp 的视图,如果未找到,则会回退到 grails-app/views/book/list.gsp

请注意,如果请求格式为“all”(全部)或接受标头中有多个内容类型的“q”评级相同时,类型的顺序很重要。在第一种情况下,会执行代码块中的第一个类型处理程序(上例中的“html”)。后一种情况比较复杂,因为只有当存在多个“q”评级最高的内容类型且您有一个类型处理程序并且有多个类型处理程序与该“q”评级相匹配时,它才成立。例如,如果请求的“text/html”和“application/xml”的“q”评级为 1.0,则此代码

withFormat {
    xml { ... }
    html { ... }
}

将会对请求使用“xml”类型处理程序。

另一个需要注意的重要因素是 withFormat 方法处理的是响应格式,而不是请求格式。从 Grails 2.0 开始,request 上提供了另一个 withFormat 方法,可用于处理请求格式,该格式由请求的 CONTENT_TYPE 标头决定。

request.withFormat {
    form { .. }
    xml { .. }
    json { .. }
}
form 的请求格式用于处理内容协商中的表单提交,而不是 html

如果您需要模型被延迟执行,则可以传递 Closure,而不是 Map

withFormat {
    html { [bookList: Book.list()] }
    ...
}

这样,只有 html 格式匹配,html Closure 才会执行。

除非您向 application.groovy 文件添加 grails.mime.use.accept.header = true 设置,Grails 才会忽略 HTTP Accept 头。换句话说,没有该设置,withFormat() 完全不受 Accept 头影响。