Fix @RequestBody argument processing for null Content-Type

Since the changes introduced in SPR-12778, some `@RequestBody` args
would not be properly processed in some cases:

* requests with an empty body
* no Content-Type header defined

This typically happens when GET requests are mapped on a handler dealing
with POST requests and HTTP bodies.

This change makes sure that the `RequestResponseBodyMethodProcessor` is
only involved for requests that:

* have a Content-Type defined
* OR are HTTP requests eligible for an HTTP body (PUT, POST, PATCH)

Issue: SPR-13176
Fixes spring-projects/spring-boot#3313
This commit is contained in:
Brian Clozel
2015-06-30 18:53:53 +02:00
parent 749bee4d58
commit 244c95b076
4 changed files with 29 additions and 16 deletions

View File

@@ -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"));

View File

@@ -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;

View File

@@ -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);