可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I have an application with Spring 3.0.5.RELEASE trying to get the full content of a post using @RequestBody. The method is called, but the string passed is always empty. I have checked, by placing breakpoints, that the StringHttpMessageConverter is called, but the inner HttpInputMessage is empty.
I've seen this issue with both Jetty and Tomcat, so I'm discarding it's a problem with the container.
Here is my sample controller:
@Controller @RequestMapping("/") public class SubscriptionController { @RequestMapping(value = "/requestbody", method = RequestMethod.POST) public ModelAndView mycustomAction(@RequestBody String body) { // body is always empty Logger.getLogger(this.getClass()).debug("REQUEST BODY '" + body + "'"); return new ModelAndView("empty"); } }
My application context is defined as follows:
/WEB-INF/general.xml
I'm testing this using curl as follows:
curl -d asd=123 -d qwe=456 http://localhost:8080/requestbody
Any ideas or help is more than welcomed!
回答1:
Here is a code snippet of ServletServerHttpRequest
, which extends HttpInputMessage
. I am pretty positive this is the implementation that you are using in your code:
public InputStream getBody() throws IOException { return this.servletRequest.getInputStream(); }
In other words, the request body is meant to be read as the input stream of the HttpServletRequest
object.
The request's input stream is not valid in several situations, but I can't find the correct documentation for it at the moment. For example, if you call request.getParameter()
on a post request, tomcat has to read the input stream in order to interpret the parameters, thus afterwards when you read the input stream, it is empty because it has reached the end already.
Perhaps you are invoking getParameter
somewhere in an interceptor or perhaps a filter defined in web.xml. Another option is that Spring is doing that for you, for example, if your controller has some other method with complex @RequestMapping
s (such as reading param values, or header values).
I have two suggestions for you:
Add a servlet filter (before spring gets a chance to act), and wrap the request with your own wrapper (just extend HttpServletRequestWrapper). This way you can put breakpoints or log messages at some methods of the request object and see who's calling them.
Use a pojo object parameter, and setup the bindings. It seems like a much cleaner way to read post data.
回答2:
How are you POSTing messages to this URL? Are you positive that the HTTP request contains what you think it does? I suggest removing any web browsers from the picture and drop down to something low-level like curl
which lets you send any type of HTTP message yourself.
回答3:
Had a similar problem - the string received by spring controller was always empty. Tinkered with my spring config but with no result. Finally the problem was that the client was actually was not sending anything body!(due to some typo of mine)
If found with a similar error, its worth checking once if the client's payload is actually non-empty.