HttpEntityMethodProcessor supports custom HttpEntity subclasses again

Issue: SPR-12242
This commit is contained in:
Juergen Hoeller 2014-09-24 17:56:07 +02:00
parent 5b1cbf0306
commit 281b243b88
3 changed files with 53 additions and 36 deletions

View File

@ -67,7 +67,7 @@ public class HttpEntityMethodProcessor extends AbstractMessageConverterMethodPro
}
@Override
@Override
public boolean supportsParameter(MethodParameter parameter) {
return HttpEntity.class.equals(parameter.getParameterType()) ||
RequestEntity.class.equals(parameter.getParameterType());
@ -75,8 +75,8 @@ public class HttpEntityMethodProcessor extends AbstractMessageConverterMethodPro
@Override
public boolean supportsReturnType(MethodParameter returnType) {
return HttpEntity.class.equals(returnType.getParameterType()) ||
ResponseEntity.class.equals(returnType.getParameterType());
return HttpEntity.class.isAssignableFrom(returnType.getParameterType()) &&
!RequestEntity.class.isAssignableFrom(returnType.getParameterType());
}
@Override
@ -94,7 +94,6 @@ public class HttpEntityMethodProcessor extends AbstractMessageConverterMethodPro
}
else {
return new HttpEntity<Object>(body, inputMessage.getHeaders());
}
}
@ -152,4 +151,5 @@ public class HttpEntityMethodProcessor extends AbstractMessageConverterMethodPro
return ResolvableType.forMethodParameter(returnType, type).resolve(Object.class);
}
}
}

View File

@ -20,11 +20,11 @@ import java.lang.reflect.Method;
import java.net.URI;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import org.junit.Before;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.springframework.core.MethodParameter;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
@ -41,7 +41,6 @@ import org.springframework.mock.web.test.MockHttpServletResponse;
import org.springframework.web.HttpMediaTypeNotAcceptableException;
import org.springframework.web.HttpMediaTypeNotSupportedException;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.context.request.ServletWebRequest;
import org.springframework.web.method.support.ModelAndViewContainer;
@ -66,21 +65,22 @@ public class HttpEntityMethodProcessorMockTests {
private HttpMessageConverter<String> messageConverter;
private MethodParameter paramHttpEntity;
private MethodParameter paramRequestEntity;
private MethodParameter paramResponseEntity;
private MethodParameter paramInt;
private MethodParameter returnTypeResponseEntity;
private MethodParameter returnTypeHttpEntity;
private MethodParameter returnTypeInt;
private MethodParameter paramRequestEntity;
private MethodParameter returnTypeResponseEntityProduces;
private MethodParameter returnTypeHttpEntity;
private MethodParameter returnTypeHttpEntitySubclass;
private MethodParameter returnTypeInt;
private ModelAndViewContainer mavContainer;
private ServletWebRequest webRequest;
private MockHttpServletRequest servletRequest;
private MockHttpServletResponse servletResponse;
private MockHttpServletRequest servletRequest;
private ServletWebRequest webRequest;
@SuppressWarnings("unchecked")
@ -92,27 +92,24 @@ public class HttpEntityMethodProcessorMockTests {
processor = new HttpEntityMethodProcessor(Collections.<HttpMessageConverter<?>>singletonList(messageConverter));
reset(messageConverter);
Method handle1 = getClass().getMethod("handle1", HttpEntity.class, ResponseEntity.class, Integer.TYPE, RequestEntity.class);
paramHttpEntity = new MethodParameter(handle1, 0);
paramRequestEntity = new MethodParameter(handle1, 3);
paramResponseEntity = new MethodParameter(handle1, 1);
paramInt = new MethodParameter(handle1, 2);
paramRequestEntity = new MethodParameter(handle1, 3);
returnTypeResponseEntity = new MethodParameter(handle1, -1);
returnTypeResponseEntityProduces = new MethodParameter(getClass().getMethod("handle4"), -1);
returnTypeHttpEntity = new MethodParameter(getClass().getMethod("handle2", HttpEntity.class), -1);
returnTypeHttpEntitySubclass = new MethodParameter(getClass().getMethod("handle2x", HttpEntity.class), -1);
returnTypeInt = new MethodParameter(getClass().getMethod("handle3"), -1);
returnTypeResponseEntityProduces = new MethodParameter(getClass().getMethod("handle4"), -1);
mavContainer = new ModelAndViewContainer();
servletRequest = new MockHttpServletRequest();
servletResponse = new MockHttpServletResponse();
webRequest = new ServletWebRequest(servletRequest, servletResponse);
}
@Test
public void supportsParameter() {
assertTrue("HttpEntity parameter not supported", processor.supportsParameter(paramHttpEntity));
@ -125,6 +122,7 @@ public class HttpEntityMethodProcessorMockTests {
public void supportsReturnType() {
assertTrue("ResponseEntity return type not supported", processor.supportsReturnType(returnTypeResponseEntity));
assertTrue("HttpEntity return type not supported", processor.supportsReturnType(returnTypeHttpEntity));
assertTrue("Custom HttpEntity subclass not supported", processor.supportsReturnType(returnTypeHttpEntitySubclass));
assertFalse("RequestEntity parameter supported",
processor.supportsReturnType(paramRequestEntity));
assertFalse("non-ResponseBody return type supported", processor.supportsReturnType(returnTypeInt));
@ -328,6 +326,10 @@ public class HttpEntityMethodProcessorMockTests {
return entity;
}
public CustomHttpEntity handle2x(HttpEntity<?> entity) {
return new CustomHttpEntity();
}
public int handle3() {
return 42;
}
@ -338,4 +340,7 @@ public class HttpEntityMethodProcessorMockTests {
}
public static class CustomHttpEntity extends HttpEntity<Object> {
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -15,8 +15,6 @@
*/
package org.springframework.web.servlet.mvc.method.annotation;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import java.io.Serializable;
import java.lang.reflect.Method;
@ -25,6 +23,7 @@ import java.util.List;
import org.junit.Before;
import org.junit.Test;
import org.springframework.core.MethodParameter;
import org.springframework.http.HttpEntity;
import org.springframework.http.MediaType;
@ -40,6 +39,8 @@ import org.springframework.web.context.request.ServletWebRequest;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.method.support.ModelAndViewContainer;
import static org.junit.Assert.*;
/**
* Test fixture with {@link HttpEntityMethodProcessor} delegating to
* actual {@link HttpMessageConverter} instances.
@ -51,32 +52,31 @@ import org.springframework.web.method.support.ModelAndViewContainer;
public class HttpEntityMethodProcessorTests {
private MethodParameter paramList;
private MethodParameter paramSimpleBean;
private ModelAndViewContainer mavContainer;
private ServletWebRequest webRequest;
private MockHttpServletResponse servletResponse;
private WebDataBinderFactory binderFactory;
private MockHttpServletRequest servletRequest;
private WebDataBinderFactory binderFactory;
private MockHttpServletResponse servletResponse;
private ServletWebRequest webRequest;
@Before
public void setUp() throws Exception {
Method method = getClass().getMethod("handle", HttpEntity.class, HttpEntity.class);
paramList = new MethodParameter(method, 0);
paramSimpleBean = new MethodParameter(method, 1);
mavContainer = new ModelAndViewContainer();
binderFactory = new ValidatingBinderFactory();
servletRequest = new MockHttpServletRequest();
servletResponse = new MockHttpServletResponse();
webRequest = new ServletWebRequest(servletRequest, servletResponse);
binderFactory = new ValidatingBinderFactory();
}
@Test
@ -118,7 +118,6 @@ public class HttpEntityMethodProcessorTests {
@Test
public void resolveArgumentTypeVariable() throws Exception {
Method method = MySimpleParameterizedController.class.getMethod("handleDto", HttpEntity.class);
HandlerMethod handlerMethod = new HandlerMethod(new MySimpleParameterizedController(), method);
MethodParameter methodParam = handlerMethod.getMethodParameters()[0];
@ -132,31 +131,42 @@ public class HttpEntityMethodProcessorTests {
HttpEntityMethodProcessor processor = new HttpEntityMethodProcessor(converters);
@SuppressWarnings("unchecked")
HttpEntity<SimpleBean> result = (HttpEntity<SimpleBean>) processor.resolveArgument(methodParam, mavContainer, webRequest, binderFactory);
HttpEntity<SimpleBean> result = (HttpEntity<SimpleBean>)
processor.resolveArgument(methodParam, mavContainer, webRequest, binderFactory);
assertNotNull(result);
assertEquals("Jad", result.getBody().getName());
}
public void handle(HttpEntity<List<SimpleBean>> arg1, HttpEntity<SimpleBean> arg2) {
}
private static abstract class MyParameterizedController<DTO extends Identifiable> {
@SuppressWarnings("unused")
public void handleDto(HttpEntity<DTO> dto) {}
public void handleDto(HttpEntity<DTO> dto) {
}
}
private static class MySimpleParameterizedController extends MyParameterizedController<SimpleBean> {
}
private static class MySimpleParameterizedController extends MyParameterizedController<SimpleBean> { }
private interface Identifiable extends Serializable {
public Long getId();
public void setId(Long id);
}
@SuppressWarnings({ "serial" })
private static class SimpleBean implements Identifiable {
private Long id;
private String name;
@Override
@ -179,9 +189,11 @@ public class HttpEntityMethodProcessorTests {
}
}
private final class ValidatingBinderFactory implements WebDataBinderFactory {
@Override
public WebDataBinder createBinder(NativeWebRequest webRequest, Object target, String objectName) throws Exception {
public WebDataBinder createBinder(NativeWebRequest webRequest, Object target, String objectName) {
LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean();
validator.afterPropertiesSet();
WebDataBinder dataBinder = new WebDataBinder(target, objectName);
@ -190,4 +202,4 @@ public class HttpEntityMethodProcessorTests {
}
}
}
}