在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),但不能两者都做。
所以,你想要达到的是不可能直接实现的。但是,你可以做一些不同的事情。在您的过滤器中,读取传入的请求体并将其存储到params
或session
中(如果过滤器将请求传递给控制器),然后手动绑定操作中的参数:
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主体中丢失参数