SPR-6877 - AnnotationMethodHandlerAdapter.handleResponseBody prioritizes messageConverter over MediaType
This commit is contained in:
parent
894875ce8d
commit
62f9f477f5
|
|
@ -871,10 +871,9 @@ public class AnnotationMethodHandlerAdapter extends WebContentGenerator
|
|||
HttpOutputMessage outputMessage = new ServletServerHttpResponse(webRequest.getResponse());
|
||||
Class<?> returnValueType = returnValue.getClass();
|
||||
List<MediaType> allSupportedMediaTypes = new ArrayList<MediaType>();
|
||||
if (messageConverters != null) {
|
||||
for (HttpMessageConverter messageConverter : messageConverters) {
|
||||
allSupportedMediaTypes.addAll(messageConverter.getSupportedMediaTypes());
|
||||
for (MediaType acceptedMediaType : acceptedMediaTypes) {
|
||||
if (getMessageConverters() != null) {
|
||||
for (MediaType acceptedMediaType : acceptedMediaTypes) {
|
||||
for (HttpMessageConverter messageConverter : getMessageConverters()) {
|
||||
if (messageConverter.canWrite(returnValueType, acceptedMediaType)) {
|
||||
messageConverter.write(returnValue, acceptedMediaType, outputMessage);
|
||||
this.responseArgumentUsed = true;
|
||||
|
|
@ -882,6 +881,9 @@ public class AnnotationMethodHandlerAdapter extends WebContentGenerator
|
|||
}
|
||||
}
|
||||
}
|
||||
for (HttpMessageConverter messageConverter : messageConverters) {
|
||||
allSupportedMediaTypes.addAll(messageConverter.getSupportedMediaTypes());
|
||||
}
|
||||
}
|
||||
throw new HttpMediaTypeNotAcceptableException(allSupportedMediaTypes);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ import java.lang.annotation.Target;
|
|||
import java.lang.reflect.Method;
|
||||
import java.security.Principal;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
|
|
@ -1037,7 +1038,7 @@ public class ServletAnnotationControllerTests {
|
|||
String requestBody = "Hello World";
|
||||
request.setContent(requestBody.getBytes("UTF-8"));
|
||||
request.addHeader("Content-Type", "text/plain; charset=utf-8");
|
||||
request.addHeader("Accept", "text/*");
|
||||
request.addHeader("Accept", "text/*, */*");
|
||||
MockHttpServletResponse response = new MockHttpServletResponse();
|
||||
servlet.service(request, response);
|
||||
assertEquals(200, response.getStatus());
|
||||
|
|
@ -1137,7 +1138,7 @@ public class ServletAnnotationControllerTests {
|
|||
GenericWebApplicationContext wac = new GenericWebApplicationContext();
|
||||
wac.registerBeanDefinition("controller", new RootBeanDefinition(RequestBodyController.class));
|
||||
RootBeanDefinition adapterDef = new RootBeanDefinition(AnnotationMethodHandlerAdapter.class);
|
||||
adapterDef.getPropertyValues().add("messageConverters", new MyMessageConverter());
|
||||
adapterDef.getPropertyValues().add("messageConverters", new NotReadableMessageConverter());
|
||||
wac.registerBeanDefinition("handlerAdapter", adapterDef);
|
||||
wac.refresh();
|
||||
return wac;
|
||||
|
|
@ -1154,6 +1155,38 @@ public class ServletAnnotationControllerTests {
|
|||
assertEquals("Invalid response status code", HttpServletResponse.SC_BAD_REQUEST, response.getStatus());
|
||||
}
|
||||
|
||||
/*
|
||||
* See SPR-6877
|
||||
*/
|
||||
@Test
|
||||
public void overlappingMesssageConvertersRequestBody() throws ServletException, IOException {
|
||||
@SuppressWarnings("serial") DispatcherServlet servlet = new DispatcherServlet() {
|
||||
@Override
|
||||
protected WebApplicationContext createWebApplicationContext(WebApplicationContext parent) {
|
||||
GenericWebApplicationContext wac = new GenericWebApplicationContext();
|
||||
wac.registerBeanDefinition("controller", new RootBeanDefinition(RequestBodyController.class));
|
||||
RootBeanDefinition adapterDef = new RootBeanDefinition(AnnotationMethodHandlerAdapter.class);
|
||||
List<HttpMessageConverter> messageConverters = new ArrayList<HttpMessageConverter>();
|
||||
messageConverters.add(new StringHttpMessageConverter());
|
||||
messageConverters
|
||||
.add(new SimpleMessageConverter(new MediaType("application","json"), MediaType.ALL));
|
||||
adapterDef.getPropertyValues().add("messageConverters", messageConverters);
|
||||
wac.registerBeanDefinition("handlerAdapter", adapterDef);
|
||||
wac.refresh();
|
||||
return wac;
|
||||
}
|
||||
};
|
||||
servlet.init(new MockServletConfig());
|
||||
|
||||
MockHttpServletRequest request = new MockHttpServletRequest("PUT", "/something");
|
||||
request.setContent("Hello World".getBytes("UTF-8"));
|
||||
request.addHeader("Content-Type", "text/plain; charset=utf-8");
|
||||
request.addHeader("Accept", "application/json, text/javascript, */*");
|
||||
MockHttpServletResponse response = new MockHttpServletResponse();
|
||||
servlet.service(request, response);
|
||||
assertEquals("Invalid response status code", "application/json", response.getHeader("Content-Type"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void headers() throws ServletException, IOException {
|
||||
initServlet(HeadersController.class);
|
||||
|
|
@ -2123,7 +2156,7 @@ public class ServletAnnotationControllerTests {
|
|||
}
|
||||
}
|
||||
|
||||
public static class MyMessageConverter implements HttpMessageConverter {
|
||||
public static class NotReadableMessageConverter implements HttpMessageConverter {
|
||||
|
||||
public boolean canRead(Class clazz, MediaType mediaType) {
|
||||
return true;
|
||||
|
|
@ -2148,6 +2181,37 @@ public class ServletAnnotationControllerTests {
|
|||
}
|
||||
}
|
||||
|
||||
public static class SimpleMessageConverter implements HttpMessageConverter {
|
||||
|
||||
private final List<MediaType> supportedMediaTypes;
|
||||
|
||||
public SimpleMessageConverter(MediaType... supportedMediaTypes) {
|
||||
this.supportedMediaTypes = Arrays.asList(supportedMediaTypes);
|
||||
}
|
||||
|
||||
public boolean canRead(Class clazz, MediaType mediaType) {
|
||||
return supportedMediaTypes.contains(mediaType);
|
||||
}
|
||||
|
||||
public boolean canWrite(Class clazz, MediaType mediaType) {
|
||||
return supportedMediaTypes.contains(mediaType);
|
||||
}
|
||||
|
||||
public List getSupportedMediaTypes() {
|
||||
return supportedMediaTypes;
|
||||
}
|
||||
|
||||
public Object read(Class clazz, HttpInputMessage inputMessage)
|
||||
throws IOException, HttpMessageNotReadableException {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void write(Object o, MediaType contentType, HttpOutputMessage outputMessage)
|
||||
throws IOException, HttpMessageNotWritableException {
|
||||
outputMessage.getHeaders().setContentType(contentType);
|
||||
}
|
||||
}
|
||||
|
||||
@Controller
|
||||
public static class HeadersController {
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue