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 3bbf082e63..979a3aa49b 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 @@ -18,6 +18,7 @@ package org.springframework.web.servlet.mvc.method.annotation; import java.io.IOException; import java.lang.reflect.Type; +import java.util.Arrays; import java.util.List; import javax.servlet.http.HttpServletRequest; @@ -25,7 +26,7 @@ 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.HttpMethod; import org.springframework.http.converter.HttpMessageConverter; import org.springframework.http.converter.HttpMessageNotReadableException; import org.springframework.http.server.ServletServerHttpRequest; @@ -58,6 +59,9 @@ import org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolv */ public class RequestResponseBodyMethodProcessor extends AbstractMessageConverterMethodProcessor { + private static final List SUPPORTED_METHODS = + Arrays.asList(HttpMethod.POST, HttpMethod.PUT, HttpMethod.PATCH); + /** * Basic constructor with converters only. Suitable for resolving * {@code @RequestBody}. For handling {@code @ResponseBody} consider also @@ -143,16 +147,19 @@ public class RequestResponseBodyMethodProcessor extends AbstractMessageConverter Type paramType) throws IOException, HttpMediaTypeNotSupportedException { HttpServletRequest servletRequest = webRequest.getNativeRequest(HttpServletRequest.class); - HttpInputMessage inputMessage = new ServletServerHttpRequest(servletRequest); - - Object arg = readWithMessageConverters(inputMessage, methodParam, paramType); - if (arg == null) { - if (methodParam.getParameterAnnotation(RequestBody.class).required()) { - throw new HttpMessageNotReadableException("Required request body is missing: " + - methodParam.getMethod().toGenericString()); + ServletServerHttpRequest inputMessage = new ServletServerHttpRequest(servletRequest); + + Object arg = null; + if (webRequest.getHeader("Content-Type") != null || + SUPPORTED_METHODS.contains(inputMessage.getMethod())) { + arg = readWithMessageConverters(inputMessage, methodParam, paramType); + if (arg == null) { + if (methodParam.getParameterAnnotation(RequestBody.class).required()) { + throw new HttpMessageNotReadableException("Required request body is missing: " + + methodParam.getMethod().toGenericString()); + } } } - return arg; } diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerAdapterIntegrationTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerAdapterIntegrationTests.java index e9931b41a5..24b703572e 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerAdapterIntegrationTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerAdapterIntegrationTests.java @@ -212,6 +212,7 @@ public class RequestMappingHandlerAdapterIntegrationTests { Class[] parameterTypes = new Class[] { byte[].class }; + request.setMethod("POST"); request.addHeader("Content-Type", "text/plain; charset=utf-8"); request.setContent("Hello Server".getBytes("UTF-8")); diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/RequestResponseBodyMethodProcessorMockTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/RequestResponseBodyMethodProcessorMockTests.java index 543030050c..bffcdfa28e 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/RequestResponseBodyMethodProcessorMockTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/RequestResponseBodyMethodProcessorMockTests.java @@ -102,6 +102,7 @@ public class RequestResponseBodyMethodProcessorMockTests { mavContainer = new ModelAndViewContainer(); servletRequest = new MockHttpServletRequest(); + servletRequest.setMethod("POST"); webRequest = new ServletWebRequest(servletRequest, new MockHttpServletResponse()); } @@ -178,17 +179,11 @@ public class RequestResponseBodyMethodProcessorMockTests { processor.resolveArgument(paramRequestBodyString, mavContainer, webRequest, null); } - @Test + @Test(expected = HttpMediaTypeNotSupportedException.class) public void resolveArgumentNoContentType() throws Exception { servletRequest.setContent("payload".getBytes(Charset.forName("UTF-8"))); given(messageConverter.canRead(String.class, MediaType.APPLICATION_OCTET_STREAM)).willReturn(false); - try { - processor.resolveArgument(paramRequestBodyString, mavContainer, webRequest, null); - fail("Expected exception"); - } - catch (HttpMediaTypeNotSupportedException ex) { - // expected - } + processor.resolveArgument(paramRequestBodyString, mavContainer, webRequest, null); } @Test(expected = HttpMediaTypeNotSupportedException.class) @@ -217,6 +212,14 @@ public class RequestResponseBodyMethodProcessorMockTests { assertNull(processor.resolveArgument(paramStringNotRequired, mavContainer, webRequest, new ValidatingBinderFactory())); } + @Test + public void resolveArgumentNotGetRequests() throws Exception { + servletRequest.setMethod("GET"); + servletRequest.setContent(new byte[0]); + given(messageConverter.canRead(String.class, MediaType.APPLICATION_OCTET_STREAM)).willReturn(false); + assertNull(processor.resolveArgument(paramStringNotRequired, mavContainer, webRequest, new ValidatingBinderFactory())); + } + @Test public void handleReturnValue() throws Exception { MediaType accepted = MediaType.TEXT_PLAIN; diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/RequestResponseBodyMethodProcessorTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/RequestResponseBodyMethodProcessorTests.java index c4684f9ccd..f966df2159 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/RequestResponseBodyMethodProcessorTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/RequestResponseBodyMethodProcessorTests.java @@ -112,6 +112,7 @@ public class RequestResponseBodyMethodProcessorTests { mavContainer = new ModelAndViewContainer(); servletRequest = new MockHttpServletRequest(); + servletRequest.setMethod("POST"); servletResponse = new MockHttpServletResponse(); webRequest = new ServletWebRequest(servletRequest, servletResponse); @@ -140,6 +141,7 @@ public class RequestResponseBodyMethodProcessorTests { @Test public void resolveArgumentRawTypeFromParameterizedType() throws Exception { String content = "fruit=apple&vegetable=kale"; + this.servletRequest.setMethod("GET"); this.servletRequest.setContent(content.getBytes("UTF-8")); this.servletRequest.setContentType(MediaType.APPLICATION_FORM_URLENCODED_VALUE);