Skip to content

Commit 281b243

Browse files
committed
HttpEntityMethodProcessor supports custom HttpEntity subclasses again
Issue: SPR-12242
1 parent 5b1cbf0 commit 281b243

File tree

3 files changed

+51
-34
lines changed

3 files changed

+51
-34
lines changed

spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/HttpEntityMethodProcessor.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -67,16 +67,16 @@ public HttpEntityMethodProcessor(List<HttpMessageConverter<?>> messageConverters
6767
}
6868

6969

70-
@Override
70+
@Override
7171
public boolean supportsParameter(MethodParameter parameter) {
7272
return HttpEntity.class.equals(parameter.getParameterType()) ||
7373
RequestEntity.class.equals(parameter.getParameterType());
7474
}
7575

7676
@Override
7777
public boolean supportsReturnType(MethodParameter returnType) {
78-
return HttpEntity.class.equals(returnType.getParameterType()) ||
79-
ResponseEntity.class.equals(returnType.getParameterType());
78+
return HttpEntity.class.isAssignableFrom(returnType.getParameterType()) &&
79+
!RequestEntity.class.isAssignableFrom(returnType.getParameterType());
8080
}
8181

8282
@Override
@@ -94,7 +94,6 @@ public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer m
9494
}
9595
else {
9696
return new HttpEntity<Object>(body, inputMessage.getHeaders());
97-
9897
}
9998
}
10099

@@ -152,4 +151,5 @@ protected Class<?> getReturnValueType(Object returnValue, MethodParameter return
152151
return ResolvableType.forMethodParameter(returnType, type).resolve(Object.class);
153152
}
154153
}
154+
155155
}

spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/HttpEntityMethodProcessorMockTests.java

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,11 @@
2020
import java.net.URI;
2121
import java.util.Arrays;
2222
import java.util.Collections;
23-
import java.util.List;
2423

2524
import org.junit.Before;
2625
import org.junit.Test;
2726
import org.mockito.ArgumentCaptor;
27+
2828
import org.springframework.core.MethodParameter;
2929
import org.springframework.http.HttpEntity;
3030
import org.springframework.http.HttpHeaders;
@@ -41,7 +41,6 @@
4141
import org.springframework.web.HttpMediaTypeNotAcceptableException;
4242
import org.springframework.web.HttpMediaTypeNotSupportedException;
4343
import org.springframework.web.bind.annotation.RequestMapping;
44-
import org.springframework.web.bind.annotation.ResponseBody;
4544
import org.springframework.web.context.request.ServletWebRequest;
4645
import org.springframework.web.method.support.ModelAndViewContainer;
4746

@@ -66,21 +65,22 @@ public class HttpEntityMethodProcessorMockTests {
6665
private HttpMessageConverter<String> messageConverter;
6766

6867
private MethodParameter paramHttpEntity;
68+
private MethodParameter paramRequestEntity;
6969
private MethodParameter paramResponseEntity;
7070
private MethodParameter paramInt;
7171
private MethodParameter returnTypeResponseEntity;
72+
private MethodParameter returnTypeResponseEntityProduces;
7273
private MethodParameter returnTypeHttpEntity;
74+
private MethodParameter returnTypeHttpEntitySubclass;
7375
private MethodParameter returnTypeInt;
74-
private MethodParameter paramRequestEntity;
75-
private MethodParameter returnTypeResponseEntityProduces;
7676

7777
private ModelAndViewContainer mavContainer;
7878

79-
private ServletWebRequest webRequest;
79+
private MockHttpServletRequest servletRequest;
8080

8181
private MockHttpServletResponse servletResponse;
8282

83-
private MockHttpServletRequest servletRequest;
83+
private ServletWebRequest webRequest;
8484

8585

8686
@SuppressWarnings("unchecked")
@@ -92,27 +92,24 @@ public void setUp() throws Exception {
9292
processor = new HttpEntityMethodProcessor(Collections.<HttpMessageConverter<?>>singletonList(messageConverter));
9393
reset(messageConverter);
9494

95-
9695
Method handle1 = getClass().getMethod("handle1", HttpEntity.class, ResponseEntity.class, Integer.TYPE, RequestEntity.class);
9796
paramHttpEntity = new MethodParameter(handle1, 0);
97+
paramRequestEntity = new MethodParameter(handle1, 3);
9898
paramResponseEntity = new MethodParameter(handle1, 1);
9999
paramInt = new MethodParameter(handle1, 2);
100-
paramRequestEntity = new MethodParameter(handle1, 3);
101100
returnTypeResponseEntity = new MethodParameter(handle1, -1);
102-
101+
returnTypeResponseEntityProduces = new MethodParameter(getClass().getMethod("handle4"), -1);
103102
returnTypeHttpEntity = new MethodParameter(getClass().getMethod("handle2", HttpEntity.class), -1);
104-
103+
returnTypeHttpEntitySubclass = new MethodParameter(getClass().getMethod("handle2x", HttpEntity.class), -1);
105104
returnTypeInt = new MethodParameter(getClass().getMethod("handle3"), -1);
106105

107-
returnTypeResponseEntityProduces = new MethodParameter(getClass().getMethod("handle4"), -1);
108-
109106
mavContainer = new ModelAndViewContainer();
110-
111107
servletRequest = new MockHttpServletRequest();
112108
servletResponse = new MockHttpServletResponse();
113109
webRequest = new ServletWebRequest(servletRequest, servletResponse);
114110
}
115111

112+
116113
@Test
117114
public void supportsParameter() {
118115
assertTrue("HttpEntity parameter not supported", processor.supportsParameter(paramHttpEntity));
@@ -125,6 +122,7 @@ public void supportsParameter() {
125122
public void supportsReturnType() {
126123
assertTrue("ResponseEntity return type not supported", processor.supportsReturnType(returnTypeResponseEntity));
127124
assertTrue("HttpEntity return type not supported", processor.supportsReturnType(returnTypeHttpEntity));
125+
assertTrue("Custom HttpEntity subclass not supported", processor.supportsReturnType(returnTypeHttpEntitySubclass));
128126
assertFalse("RequestEntity parameter supported",
129127
processor.supportsReturnType(paramRequestEntity));
130128
assertFalse("non-ResponseBody return type supported", processor.supportsReturnType(returnTypeInt));
@@ -328,6 +326,10 @@ public HttpEntity<?> handle2(HttpEntity<?> entity) {
328326
return entity;
329327
}
330328

329+
public CustomHttpEntity handle2x(HttpEntity<?> entity) {
330+
return new CustomHttpEntity();
331+
}
332+
331333
public int handle3() {
332334
return 42;
333335
}
@@ -338,4 +340,7 @@ public ResponseEntity<String> handle4() {
338340
}
339341

340342

343+
public static class CustomHttpEntity extends HttpEntity<Object> {
344+
}
345+
341346
}

spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/HttpEntityMethodProcessorTests.java

Lines changed: 29 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2012 the original author or authors.
2+
* Copyright 2002-2014 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -15,8 +15,6 @@
1515
*/
1616

1717
package org.springframework.web.servlet.mvc.method.annotation;
18-
import static org.junit.Assert.assertEquals;
19-
import static org.junit.Assert.assertNotNull;
2018

2119
import java.io.Serializable;
2220
import java.lang.reflect.Method;
@@ -25,6 +23,7 @@
2523

2624
import org.junit.Before;
2725
import org.junit.Test;
26+
2827
import org.springframework.core.MethodParameter;
2928
import org.springframework.http.HttpEntity;
3029
import org.springframework.http.MediaType;
@@ -40,6 +39,8 @@
4039
import org.springframework.web.method.HandlerMethod;
4140
import org.springframework.web.method.support.ModelAndViewContainer;
4241

42+
import static org.junit.Assert.*;
43+
4344
/**
4445
* Test fixture with {@link HttpEntityMethodProcessor} delegating to
4546
* actual {@link HttpMessageConverter} instances.
@@ -51,32 +52,31 @@
5152
public class HttpEntityMethodProcessorTests {
5253

5354
private MethodParameter paramList;
55+
5456
private MethodParameter paramSimpleBean;
5557

5658
private ModelAndViewContainer mavContainer;
5759

58-
private ServletWebRequest webRequest;
60+
private WebDataBinderFactory binderFactory;
61+
62+
private MockHttpServletRequest servletRequest;
5963

6064
private MockHttpServletResponse servletResponse;
6165

62-
private MockHttpServletRequest servletRequest;
66+
private ServletWebRequest webRequest;
6367

64-
private WebDataBinderFactory binderFactory;
6568

6669
@Before
6770
public void setUp() throws Exception {
68-
6971
Method method = getClass().getMethod("handle", HttpEntity.class, HttpEntity.class);
7072
paramList = new MethodParameter(method, 0);
7173
paramSimpleBean = new MethodParameter(method, 1);
7274

7375
mavContainer = new ModelAndViewContainer();
74-
76+
binderFactory = new ValidatingBinderFactory();
7577
servletRequest = new MockHttpServletRequest();
7678
servletResponse = new MockHttpServletResponse();
7779
webRequest = new ServletWebRequest(servletRequest, servletResponse);
78-
79-
binderFactory = new ValidatingBinderFactory();
8080
}
8181

8282
@Test
@@ -118,7 +118,6 @@ public void resolveGenericArgument() throws Exception {
118118

119119
@Test
120120
public void resolveArgumentTypeVariable() throws Exception {
121-
122121
Method method = MySimpleParameterizedController.class.getMethod("handleDto", HttpEntity.class);
123122
HandlerMethod handlerMethod = new HandlerMethod(new MySimpleParameterizedController(), method);
124123
MethodParameter methodParam = handlerMethod.getMethodParameters()[0];
@@ -132,31 +131,42 @@ public void resolveArgumentTypeVariable() throws Exception {
132131
HttpEntityMethodProcessor processor = new HttpEntityMethodProcessor(converters);
133132

134133
@SuppressWarnings("unchecked")
135-
HttpEntity<SimpleBean> result = (HttpEntity<SimpleBean>) processor.resolveArgument(methodParam, mavContainer, webRequest, binderFactory);
134+
HttpEntity<SimpleBean> result = (HttpEntity<SimpleBean>)
135+
processor.resolveArgument(methodParam, mavContainer, webRequest, binderFactory);
136136

137137
assertNotNull(result);
138138
assertEquals("Jad", result.getBody().getName());
139139
}
140140

141+
141142
public void handle(HttpEntity<List<SimpleBean>> arg1, HttpEntity<SimpleBean> arg2) {
142143
}
143144

145+
144146
private static abstract class MyParameterizedController<DTO extends Identifiable> {
145-
@SuppressWarnings("unused")
146-
public void handleDto(HttpEntity<DTO> dto) {}
147+
148+
public void handleDto(HttpEntity<DTO> dto) {
149+
}
150+
}
151+
152+
153+
private static class MySimpleParameterizedController extends MyParameterizedController<SimpleBean> {
147154
}
148155

149-
private static class MySimpleParameterizedController extends MyParameterizedController<SimpleBean> { }
150156

151157
private interface Identifiable extends Serializable {
158+
152159
public Long getId();
160+
153161
public void setId(Long id);
154162
}
155163

164+
156165
@SuppressWarnings({ "serial" })
157166
private static class SimpleBean implements Identifiable {
158167

159168
private Long id;
169+
160170
private String name;
161171

162172
@Override
@@ -179,9 +189,11 @@ public void setName(String name) {
179189
}
180190
}
181191

192+
182193
private final class ValidatingBinderFactory implements WebDataBinderFactory {
194+
183195
@Override
184-
public WebDataBinder createBinder(NativeWebRequest webRequest, Object target, String objectName) throws Exception {
196+
public WebDataBinder createBinder(NativeWebRequest webRequest, Object target, String objectName) {
185197
LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean();
186198
validator.afterPropertiesSet();
187199
WebDataBinder dataBinder = new WebDataBinder(target, objectName);
@@ -190,4 +202,4 @@ public WebDataBinder createBinder(NativeWebRequest webRequest, Object target, St
190202
}
191203
}
192204

193-
}
205+
}

0 commit comments

Comments
 (0)