Grails 2.5.0控制器命令对象在访问请求后绑定.过滤器中的JSON



在Grails 2.5.0控制器动作方法中,如果在过滤器中访问了request.JSON,则HTTP JSON主体中的属性似乎不会用于命令对象绑定。

为什么?这对我来说毫无意义。

是否有任何方法允许request.JSON在过滤器中使用,也用于命令对象绑定?

是的,当涉及到请求体的数据绑定时,这是Grails的默认行为。当您通过过滤器中的request.JSON读取请求体时,相应的输入流将被关闭或为空。因此,现在Grails不能进一步访问该请求体以绑定到命令对象。

所以,你可以在过滤器中自己访问请求体,也可以将它与命令对象一起使用,但不能同时使用。

来自将请求体绑定到命令对象标题http://grails.github.io/grails-doc/2.5.0/guide/theWebLayer.html#dataBinding:

请注意,正在解析请求体以使其工作。在此之后读取请求体的任何尝试都将失败相应的输入流将为空。控制器动作可以使用command对象,也可以解析请求自己的请求(直接请求,或者通过引用类似于request.JSON),但不能两者都做。

所以,你想要达到的是不可能直接实现的。但是,你可以做一些不同的事情。在您的过滤器中,读取传入的请求体并将其存储到paramssession中(如果过滤器将请求传递给控制器),然后手动绑定操作中的参数:

MyFilters.groovy

class MyFilters {
    def filters = {
        foo(/* your filter */) {
            before = {
                // Your checks
                Map requestData = request.JSON as Map
                session.requestData = requestData
                return true
            }
        }
    }
}

现在,在你的控制器动作中,而不是做:

class MyController {
    def fooAction(MyCommandObject object) {
    }
}

像这样做:

class MyController {
    def fooAction() {
        MyCommandObject object = new MyCommandObject(session.requestData)
        // Clear from session to clear up the memory
        session.requestData = null
    }
}

Update:我提供的上述解决方案可以很好地工作,但不干净。@JoshuaMoore提供了一个链接,它提供了一个更干净的解决方案,Http Servlet请求在读取一次后从POST主体中丢失参数

最新更新