【问题标题】:Grails - how redirect works?Grails - 重定向如何工作?
【发布时间】:2014-10-08 09:41:28
【问题描述】:

grails documentation段落实现“保存”操作中有以下sn-p代码:

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 (CREATED)。

我对重定向部分和 HTML 很好奇。在代码中有域对象(书)作为参数传递给重定向方法。执行时,我们将被重定向到已保存图书的详细信息。

我想上面的重定向代码相当于:

redirect(action: "show", id: book.id)

那么 Grails 是如何知道什么是“原始资源”呢?响应方法和内容协商有类似的行为吗?

很遗憾,我在redirect method documentation 找不到答案。

【问题讨论】:

    标签: grails grails-2.0 grails-controller


    【解决方案1】:

    经过一段时间的调试和 grepping Grails 代码,我找到了答案。我还发现了这篇文章:http://www.bl-nk.net/2014/04/explicit-redirect-grails/,这很有帮助。

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

    • 第一个 public Object redirect(Object instance,Map args) 获取参数映射并且有据可查。
    • 第二个public Object redirect(Object instance,Object object) 接受一个对象,如果它是一个域类,则grails 重定向以显示相应控制器的视图。这是我一直在寻找的方法。它是在提交 750b360bb242605c1e701a78af9d1bb7e42eeeca 中引入的

    最新(2.4.3)版本的重定向方法的实现可以找到here

    【讨论】:

      【解决方案2】:

      该信息在为每个请求创建的org.codehaus.groovy.grails.web.servlet.mvc.GrailsWebRequest 中可用,部分由 Grails 和部分由 Spring(Grails 类扩展 Spring 的 org.springframework.web.servlet.handler.DispatcherServletWebRequest)提供,并且实例在 ThreadLocal 中可用。因此,由于每个请求都在自己的线程上,它们都是相互隔离的,如果您知道线程局部变量在哪里,访问数据就很方便。 Spring Security 的SecurityContext、Hibernate 的 Session、任何当前运行的事务以及活动的 JDBC 连接(如果借用了一个)是存储在众所周知的线程本地键下以便于访问的其他数据示例。

      GrailsWebRequest 有一个 GrailsParameterMap 实例 - 这是您在控制器中看到的 params 映射,如果您从控制器操作运行 println params,您会看到除了参数值之外,控制器和动作名称也在那里。它还包含对请求、响应、会话等的引用。因此很容易从中了解当前状态。

      【讨论】:

      • 当我在重定向之前运行println params 时,我看到[action:save, controller:book]。所以我很好奇这个动作“保存”如何在下一步被替换为“显示”我从未去过的地方,因为现在创建了实体。例如,为什么它是“节目”而不是“索引”?我了解重定向到“显示”的约定,但是当我调用 redirect bookList 时会发生什么?
      • 控制器方法在编译时添加,主要从org.codehaus.groovy.grails.plugins.web.api.ControllersApi混入。在这种情况下,public Object redirect(Object instance,Object object) 是您要调用的那个;将代码集this(当前控制器)合并到第一个 arg 中的 AST 转换,域类位于第二个。从那里你最终到达org.codehaus.groovy.grails.web.metaclass.RedirectDynamicMethod,它会做更多的工作并将其交给ResponseRedirector以发送重定向。
      • 谢谢。第一次在调试过程中,我跳过了ControllersApi,对RedirectDynamicMethodResponseRedirector 感到失望。然后我什至见过DefaultLinkGenerator。所以在ControllersApi 省略了最重要的部分是我的错误。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-09-08
      • 1970-01-01
      • 1970-01-01
      • 2011-04-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多