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和灰显后,我找到了答案。我还发现了以下帖子:这很有帮助

重定向方法重载,有两种形式:

  • 首先,
    公共对象重定向(对象实例,映射参数)
    采用参数映射,并有很好的文档记录
  • 第二个
    public Object redirect(Object instance,Object Object)
    接受一个对象,如果它是一个域类,那么grails会重定向以显示相应控制器的视图。我一直在寻找这个方法。它是在commit 750b360bb242605c1e701a78af9d1bb7e42eeca中引入的

最新(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
中最重要的部分。