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

@@ -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<HttpMethod> 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);
ServletServerHttpRequest 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());
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;
}