Grails-重定向是如何工作的?
在执行“保存”操作的段落中,有以下代码片段:Grails-重定向是如何工作的?,grails,grails-2.0,grails-controller,Grails,Grails 2.0,Grails Controller,在执行“保存”操作的段落中,有以下代码片段: book.save flush:true withFormat { html { flash.message = message(code: 'default.created.message', args: [message(code: 'book.label', default: 'Book'), book.id]) redirect book }
book.save flush:true
withFormat {
html {
flash.message = message(code: 'default.created.message', args: [message(code: 'book.label', default: 'Book'), book.id])
redirect book
}
'*' { render status: CREATED }
}
还有人注意到:
在HTML的情况下,向原始资源发出重定向,对于其他格式,返回状态代码201(已创建)
我对重定向部分和HTML很好奇。在代码中,有一个域对象(book)作为参数传递给重定向方法。执行时,我们将重定向到已保存书本的详细信息
我假设上述重定向代码相当于:
redirect(action: "show", id: book.id)
那么Grails如何知道什么是“原始资源”?对于响应方法和内容协商是否有类似的行为
不幸的是,我在上找不到答案。该信息可在为每个请求创建的
org.codehaus.groovy.grails.web.servlet.mvc.GrailsWebRequest
中找到,部分由grails创建,部分由Spring创建(Grails类扩展了Spring的org.springframework.web.servlet.handler.DispatcherServletWebRequest
)实例在ThreadLocal
中可用。因此,由于每个请求都在其自己的线程上,因此它们都彼此隔离,如果您知道线程局部变量的位置,则可以方便地访问数据。Spring Security的SecurityContext
、Hibernate的会话、任何当前正在运行的事务以及活动的JDBC连接(如果借用了一个)是存储在已知线程本地键下的数据的其他示例,以方便访问
GrailsWebRequest
有一个GrailsParameterMap
实例-这是您在控制器中看到的params
映射,如果从控制器操作运行println params
,您将看到除了参数值之外,还有控制器和操作名称。它还包含对请求的引用,响应,会话等。因此,很容易从中了解当前状态。在对Grails代码进行了一段时间的去bug和灰显后,我找到了答案。我还发现了以下帖子:这很有帮助
重定向方法重载,有两种形式:
- 首先,
采用参数映射,并有很好的文档记录公共对象重定向(对象实例,映射参数)
- 第二个
接受一个对象,如果它是一个域类,那么grails会重定向以显示相应控制器的视图。我一直在寻找这个方法。它是在commit 750b360bb242605c1e701a78af9d1bb7e42eeca中引入的public Object redirect(Object instance,Object Object)
最新(2.4.3)版本的重定向方法的实现可在重定向之前运行
println params
时找到,我看到[操作:保存,控制器:书籍]
。所以我很好奇下一步如何将“保存”操作替换为“显示”我从未去过的地方,因为实体现在已经创建。例如,为什么它是“显示”而不是“索引”?我知道重定向到“显示”是一种惯例,但当我调用重定向图书列表时会发生什么?编译时会添加控制器方法,主要从org.codehaus.groovy.grails.plugins.web.api.ControllersApi
混合而成。公共对象重定向(对象实例,对象对象)
就是在这种情况下调用的;AST转换合并代码集this
(当前控制器)在第一个参数中,域类在第二个参数中。从这里开始,您将到达org.codehaus.groovy.grails.web.metaclass.RedirectDynamicMethod
,它做了更多的工作,并将其交给ResponseDirector
发送重定向。谢谢。在调试过程中,我第一次跳过了ControllersApi
,感觉到在RedirectDynamicMethod
和responseeredirector
上,我甚至看到了DefaultLinkGenerator
。所以我错误地忽略了ControllersApi
中最重要的部分。