Fix regression with raw ResponseEntity type
This fix addresses a 4.1.1 regression where a raw ResponseEntity return value (used to return potentially a different kind of body) caused an exception. The regression came from the fact we now try to render a null body in order to give ResponseBodyAdvice a chance to substitute a different value. That in turn means we have to try to determine the body type from the method signature. This change improves the logic for extracting the generic parameter type to accommodate a raw ResponseEntity class. Also we avoid raising HttpMediaTypeNotAcceptableException if the value to be rendered is null. Issue: SPR-12287
This commit is contained in:
@@ -117,10 +117,6 @@ public abstract class AbstractMessageConverterMethodProcessor extends AbstractMe
|
||||
throws IOException, HttpMediaTypeNotAcceptableException {
|
||||
|
||||
Class<?> returnValueClass = getReturnValueType(returnValue, returnType);
|
||||
if (returnValue == null && Void.class.equals(returnValueClass)) {
|
||||
return;
|
||||
}
|
||||
|
||||
HttpServletRequest servletRequest = inputMessage.getServletRequest();
|
||||
List<MediaType> requestedMediaTypes = getAcceptableMediaTypes(servletRequest);
|
||||
List<MediaType> producibleMediaTypes = getProducibleMediaTypes(servletRequest, returnValueClass);
|
||||
@@ -134,7 +130,10 @@ public abstract class AbstractMessageConverterMethodProcessor extends AbstractMe
|
||||
}
|
||||
}
|
||||
if (compatibleMediaTypes.isEmpty()) {
|
||||
throw new HttpMediaTypeNotAcceptableException(producibleMediaTypes);
|
||||
if (returnValue != null) {
|
||||
throw new HttpMediaTypeNotAcceptableException(producibleMediaTypes);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
List<MediaType> mediaTypes = new ArrayList<MediaType>(compatibleMediaTypes);
|
||||
@@ -169,7 +168,10 @@ public abstract class AbstractMessageConverterMethodProcessor extends AbstractMe
|
||||
}
|
||||
}
|
||||
}
|
||||
throw new HttpMediaTypeNotAcceptableException(this.allSupportedMediaTypes);
|
||||
|
||||
if (returnValue != null) {
|
||||
throw new HttpMediaTypeNotAcceptableException(this.allSupportedMediaTypes);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -102,12 +102,17 @@ public class HttpEntityMethodProcessor extends AbstractMessageConverterMethodPro
|
||||
Type parameterType = parameter.getGenericParameterType();
|
||||
if (parameterType instanceof ParameterizedType) {
|
||||
ParameterizedType type = (ParameterizedType) parameterType;
|
||||
if (type.getActualTypeArguments().length == 1) {
|
||||
return type.getActualTypeArguments()[0];
|
||||
if (type.getActualTypeArguments().length != 1) {
|
||||
throw new IllegalArgumentException("Expected single generic parameter on '" +
|
||||
parameter.getParameterName() + "' in method " + parameter.getMethod());
|
||||
}
|
||||
return type.getActualTypeArguments()[0];
|
||||
}
|
||||
else if (parameterType instanceof Class) {
|
||||
return Object.class;
|
||||
}
|
||||
throw new IllegalArgumentException("HttpEntity parameter '" + parameter.getParameterName() +
|
||||
"' in method " + parameter.getMethod() + " is not parameterized or has more than one parameter");
|
||||
"' in method " + parameter.getMethod() + " is not parameterized");
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -134,9 +139,10 @@ public class HttpEntityMethodProcessor extends AbstractMessageConverterMethodPro
|
||||
}
|
||||
|
||||
Object body = responseEntity.getBody();
|
||||
if (body != null || getAdviceChain().hasAdvice()) {
|
||||
writeWithMessageConverters(body, returnType, inputMessage, outputMessage);
|
||||
}
|
||||
|
||||
// Try even with null body. ResponseBodyAdvice could get involved.
|
||||
writeWithMessageConverters(body, returnType, inputMessage, outputMessage);
|
||||
|
||||
// Ensure headers are flushed even if no body was written
|
||||
outputMessage.getBody();
|
||||
}
|
||||
|
||||
@@ -194,9 +194,9 @@ public class RequestResponseBodyMethodProcessor extends AbstractMessageConverter
|
||||
throws IOException, HttpMediaTypeNotAcceptableException {
|
||||
|
||||
mavContainer.setRequestHandled(true);
|
||||
if (returnValue != null || getAdviceChain().hasAdvice()) {
|
||||
writeWithMessageConverters(returnValue, returnType, webRequest);
|
||||
}
|
||||
|
||||
// Try even with null return value. ResponseBodyAdvice could get involved.
|
||||
writeWithMessageConverters(returnValue, returnType, webRequest);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user