Reputation: 4470
In a Grails 2.5.0 controller action method, it seems like the properties in the HTTP JSON body will not be used for command object binding if request.JSON
has been accessed in a filter.
Why is that? It doesn't make any sense to me.
Is there any way to allow request.JSON
to be used in a filter, and also for command object binding?
Upvotes: 4
Views: 1266
Reputation: 25797
Yes, this is the default behavior of Grails while it comes to data binding with request body. When you read the request body via request.JSON
in your filter then the corresponding input stream will be closed or gets empty. So, now Grails can't further access that request body to bind to the command object.
So, you can either access the request body on your own in the filter or can use it with the command object but can't both.
From Binding The Request Body To Command Objects heading 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.
So, what are you trying to achieve is not possible directly. But, you can do something different. In your filter, read the incoming request body and store into the params
or session
(if filter passes the request to controller) and then manually bind the parameter in action:
MyFilters.groovy
class MyFilters {
def filters = {
foo(/* your filter */) {
before = {
// Your checks
Map requestData = request.JSON as Map
session.requestData = requestData
return true
}
}
}
}
Now, in your controller action, instead of doing:
class MyController {
def fooAction(MyCommandObject object) {
}
}
Do something like this:
class MyController {
def fooAction() {
MyCommandObject object = new MyCommandObject(session.requestData)
// Clear from session to clear up the memory
session.requestData = null
}
}
Update: The above solution, I've provided will work well but is not clean. @JoshuaMoore provided a link with a cleaner solution Http Servlet request lose params from POST body after read it once.
Upvotes: 3