Why is the HttpServletRequest input stream empty?

I have this code where I read the input from the request input stream and use JacksonMapper to convert to POJO. His work is in container 7 with cover.

@Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { try { RequestType requestType = mapper.readValue(req.getInputStream(), RequestType.class); } Catch(Exception ex) { .... } } 

However, sometimes the following exception is thrown under load. I checked my client and I'm sure it will send a valid json string. What is going wrong? Is Jetty 7 expected to be under load?

 java.io.EOFException: No content to map to Object due to end of input at org.codehaus.jackson.map.ObjectMapper._initForReading(ObjectMapper.java:2433) at org.codehaus.jackson.map.ObjectMapper._readMapAndClose(ObjectMapper.java:2385) at org.codehaus.jackson.map.ObjectMapper.readValue(ObjectMapper.java:1637) at com.ea.wsop.user.LoginServlet.processRequest(LoginServlet.java:69) at com.ea.wsop.user.LoginServlet.doPost(LoginServlet.java:63) at com.ea.wsop.user.LoginServlet$$EnhancerByGuice$$a91c2ebd.CGLIB$doPost$0(<generated>) at com.ea.wsop.user.LoginServlet$$EnhancerByGuice$$a91c2ebd$$FastClassByGuice$$c6f479ee.invoke(<generated>) at com.google.inject.internal.cglib.proxy.$MethodProxy.invokeSuper(MethodProxy.java:228) at com.google.inject.internal.InterceptorStackCallback$InterceptedMethodInvocation.proceed(InterceptorStackCallback.java:72) at com.ea.monitor.MethodExecutionTimer.invoke(MethodExecutionTimer.java:130) at com.google.inject.internal.InterceptorStackCallback$InterceptedMethodInvocation.proceed(InterceptorStackCallback.java:72) at com.google.inject.internal.InterceptorStackCallback.intercept(InterceptorStackCallback.java:52) at com.ea.wsop.user.LoginServlet$$EnhancerByGuice$$a91c2ebd.doPost(<generated>) at javax.servlet.http.HttpServlet.service(HttpServlet.java:727) at com.ea.wsop.user.LoginServlet$$EnhancerByGuice$$a91c2ebd.CGLIB$service$8(<generated>) at com.ea.wsop.user.LoginServlet$$EnhancerByGuice$$a91c2ebd$$FastClassByGuice$$c6f479ee.invoke(<generated>) at com.google.inject.internal.cglib.proxy.$MethodProxy.invokeSuper(MethodProxy.java:228) at com.google.inject.internal.InterceptorStackCallback$InterceptedMethodInvocation.proceed(InterceptorStackCallback.java:72) at com.ea.monitor.MethodExecutionTimer.invoke(MethodExecutionTimer.java:130) at com.google.inject.internal.InterceptorStackCallback$InterceptedMethodInvocation.proceed(InterceptorStackCallback.java:72) at com.google.inject.internal.InterceptorStackCallback.intercept(InterceptorStackCallback.java:52) at com.ea.wsop.user.LoginServlet$$EnhancerByGuice$$a91c2ebd.service(<generated>) at javax.servlet.http.HttpServlet.service(HttpServlet.java:820) at com.ea.wsop.user.LoginServlet$$EnhancerByGuice$$a91c2ebd.CGLIB$service$9(<generated>) at com.ea.wsop.user.LoginServlet$$EnhancerByGuice$$a91c2ebd$$FastClassByGuice$$c6f479ee.invoke(<generated>) at com.google.inject.internal.cglib.proxy.$MethodProxy.invokeSuper(MethodProxy.java:228) at com.google.inject.internal.InterceptorStackCallback$InterceptedMethodInvocation.proceed(InterceptorStackCallback.java:72) at com.ea.monitor.MethodExecutionTimer.invoke(MethodExecutionTimer.java:130) at com.google.inject.internal.InterceptorStackCallback$InterceptedMethodInvocation.proceed(InterceptorStackCallback.java:72) at com.google.inject.internal.InterceptorStackCallback.intercept(InterceptorStackCallback.java:52) at com.ea.wsop.user.LoginServlet$$EnhancerByGuice$$a91c2ebd.service(<generated>) at com.google.inject.servlet.ServletDefinition.doService(ServletDefinition.java:263) 
+14
java servlets jetty guice
Dec 15 '11 at 15:34
source share
5 answers

It will be empty if it is already consumed in advance. This will be done implicitly when you call getParameter() , getParameterValues() , getParameterMap() , getReader() , etc. On the HttpServletRequest . Make sure that you do not call any of those methods, which themselves should collect information from the request body before calling getInputStream() . If your servlet does not do this, start checking for servlet filters that appear on the same URL pattern.




Update: this seems to be a GAE 1.5 value. See also

I am afraid there is no solution / workaround until they are fixed. You can try to check if this is available inside the Filter , and if so, copy and save it as a request attribute. But this may affect further processing by some GAE servlet.

+12
Dec 15 '11 at 15:37
source
— -

I had a similar problem with the Spring Boot application. My Spring Boot application is a simple Dispatcher servlet that reads the request body and processes it.

In my case, the client ( curl ) sets the header of the application content type / x -www-form-urlencoded if -d {some-data} used on the curl command line and does not set the header of a specific content type via -Hcontent-type=some-other-media-type .

Inside the Apache Catalina servlet that Spring starts, the Request class performs the following test in parseParameters()

  if (!("application/x-www-form-urlencoded".equals(contentType))) { success = true; return; } 

For other values, the content-type Request returns here by executing.

However, if the content type matches application/x-www-form-urlencoded , the Request continues:

  try { if (readPostBody(formData, len) != len) { parameters.setParseFailedReason(FailReason.REQUEST_BODY_INCOMPLETE); return; } } catch (....) 

which will consume the body . So in my case, although my servlet does nothing but call request.getInputStream() , and try read() from it, it's too late - the Request runtime already reads the input and makes it not buffer or unread. The only workaround is to set a different content-type .

Criminal OrderedHiddenHttpMethodFilter(HiddenHttpMethodFilter).doFilterInternal(HttpServletRequest, HttpServletResponse, FilterChain) line 70

which searches for the query parameter "_method" .

I managed to disable the filter by adding

 @Bean public FilterRegistrationBean registration(HiddenHttpMethodFilter filter) { FilterRegistrationBean registration = new FilterRegistrationBean(filter); registration.setEnabled(false); return registration; } 

(which was used to solve another problem )

+10
Dec 15 '15 at 3:19
source

I had a problem that my InputStream request was always empty with Jetty 6.1.15 and found out that it was caused by a missing or incorrect "Content-Type" header.

I am generating queries in another Java program using HttpUrlConnection. When I did not specify the Content-Type header explicitly, the InputStream returned by request.getInputStream() in the receiving program was always empty. When I set the content type to "binary / octet stream", the InputStream request contains the correct data.

The only method that is called for the request object before getInputStream() is getContentLength() .

+6
Jul 11 2018-12-12T00:
source

I used mod_jk 1.2.39, which had an error causing this problem. After upgrading to 1.2.40, it began to work.

0
Apr 21 '14 at 15:19
source

I had this problem with a message. I solved this by first reading the input stream and putting it in the cache before reading the parameters. It seems to be a trick

0
Apr 26 '17 at 21:22
source



All Articles