diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestResponseBodyMethodProcessor.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestResponseBodyMethodProcessor.java index c6569b77fa..9b320cedb9 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestResponseBodyMethodProcessor.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestResponseBodyMethodProcessor.java @@ -17,16 +17,21 @@ package org.springframework.web.servlet.mvc.method.annotation; import java.io.IOException; +import java.io.InputStream; +import java.io.PushbackInputStream; import java.lang.annotation.Annotation; import java.lang.reflect.Type; import java.util.List; +import javax.servlet.http.HttpServletRequest; + import org.springframework.core.Conventions; import org.springframework.core.MethodParameter; import org.springframework.core.annotation.AnnotationUtils; import org.springframework.http.HttpInputMessage; import org.springframework.http.converter.HttpMessageConverter; import org.springframework.http.converter.HttpMessageNotReadableException; +import org.springframework.http.server.ServletServerHttpRequest; import org.springframework.validation.BindingResult; import org.springframework.validation.Errors; import org.springframework.web.HttpMediaTypeNotAcceptableException; @@ -134,18 +139,45 @@ public class RequestResponseBodyMethodProcessor extends AbstractMessageConverter } @Override - protected Object readWithMessageConverters(HttpInputMessage inputMessage, - MethodParameter methodParam, Type paramType) throws IOException, HttpMediaTypeNotSupportedException { + protected Object readWithMessageConverters(NativeWebRequest webRequest, + MethodParameter methodParam, Type paramType) throws IOException, HttpMediaTypeNotSupportedException { - if (inputMessage.getBody() != null) { - return super.readWithMessageConverters(inputMessage, methodParam, paramType); - } + final HttpServletRequest servletRequest = webRequest.getNativeRequest(HttpServletRequest.class); + HttpInputMessage inputMessage = new ServletServerHttpRequest(servletRequest); RequestBody annot = methodParam.getParameterAnnotation(RequestBody.class); if (!annot.required()) { - return null; + InputStream inputStream = inputMessage.getBody(); + if (inputStream == null) { + return null; + } + else if (inputStream.markSupported()) { + inputStream.mark(1); + if (inputStream.read() == -1) { + return null; + } + inputStream.reset(); + } + else { + final PushbackInputStream pushbackInputStream = new PushbackInputStream(inputStream); + int b = pushbackInputStream.read(); + if (b == -1) { + return null; + } + else { + pushbackInputStream.unread(b); + } + inputMessage = new ServletServerHttpRequest(servletRequest) { + @Override + public InputStream getBody() throws IOException { + // Form POST should not get here + return pushbackInputStream; + } + }; + } } - throw new HttpMessageNotReadableException("Required request body content is missing: " + methodParam.toString()); + + return super.readWithMessageConverters(inputMessage, methodParam, paramType); } public void handleReturnValue(Object returnValue, MethodParameter returnType,