在过滤器中访问 request.JSON 后的 Grails 2.5.0 控制器命令对象绑定
Grails 2.5.0 controller command object binding after accessing request.JSON in a filter
在 Grails 2.5.0 控制器操作方法中,如果在过滤器中访问 request.JSON
,HTTP JSON 主体中的属性似乎不会用于命令对象绑定。
这是为什么?这对我来说没有任何意义。
有什么方法可以让 request.JSON
在过滤器中使用,也可以用于命令对象绑定?
是的,这是 Grails 在与请求进行数据绑定时的默认行为 body。当您在过滤器中通过 request.JSON
读取请求 body 时,相应的输入流将关闭或变空。因此,现在 Grails 无法进一步访问该请求 body 以绑定到命令 object.
因此,您可以在过滤器中自行访问请求 body,也可以将其与命令 object 一起使用,但不能同时使用。
从绑定请求Body到命令Objects标题http://grails.github.io/grails-doc/2.5.0/guide/theWebLayer.html#dataBinding:
Note that the body of the request is being parsed to make that work.
Any attempt to read the body of the request after that will fail since
the corresponding input stream will be empty. The controller action
can either use a command object or it can parse the body of the
request on its own (either directly, or by referring to something like
request.JSON), but cannot do both.
那么,您想要实现的目标是不可能直接实现的。但是,您可以做一些不同的事情。在你的过滤器中,读取传入的请求 body 并存储到 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
}
}
更新:我提供的上述解决方案可以正常工作但不干净。 @JoshuaMoore 提供了一个 link 更干净的解决方案 Http Servlet request lose params from POST body after read it once.
在 Grails 2.5.0 控制器操作方法中,如果在过滤器中访问 request.JSON
,HTTP JSON 主体中的属性似乎不会用于命令对象绑定。
这是为什么?这对我来说没有任何意义。
有什么方法可以让 request.JSON
在过滤器中使用,也可以用于命令对象绑定?
是的,这是 Grails 在与请求进行数据绑定时的默认行为 body。当您在过滤器中通过 request.JSON
读取请求 body 时,相应的输入流将关闭或变空。因此,现在 Grails 无法进一步访问该请求 body 以绑定到命令 object.
因此,您可以在过滤器中自行访问请求 body,也可以将其与命令 object 一起使用,但不能同时使用。
从绑定请求Body到命令Objects标题http://grails.github.io/grails-doc/2.5.0/guide/theWebLayer.html#dataBinding:
Note that the body of the request is being parsed to make that work. Any attempt to read the body of the request after that will fail since the corresponding input stream will be empty. The controller action can either use a command object or it can parse the body of the request on its own (either directly, or by referring to something like request.JSON), but cannot do both.
那么,您想要实现的目标是不可能直接实现的。但是,您可以做一些不同的事情。在你的过滤器中,读取传入的请求 body 并存储到 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
}
}
更新:我提供的上述解决方案可以正常工作但不干净。 @JoshuaMoore 提供了一个 link 更干净的解决方案 Http Servlet request lose params from POST body after read it once.