19
19
import java .io .ByteArrayInputStream ;
20
20
import java .io .IOException ;
21
21
import java .io .InputStream ;
22
+ import java .lang .reflect .Method ;
22
23
import java .net .URI ;
23
24
import java .nio .charset .StandardCharsets ;
24
25
import java .time .ZoneId ;
27
28
import java .util .Arrays ;
28
29
import java .util .Collections ;
29
30
import java .util .Date ;
30
- import java .util .Optional ;
31
31
32
32
import org .hamcrest .Matchers ;
33
33
import org .junit .Before ;
56
56
import org .springframework .web .HttpMediaTypeNotSupportedException ;
57
57
import org .springframework .web .bind .annotation .RequestMapping ;
58
58
import org .springframework .web .context .request .ServletWebRequest ;
59
- import org .springframework .web .method .ResolvableMethod ;
60
59
import org .springframework .web .method .support .ModelAndViewContainer ;
61
60
62
- import static java .time .Instant .ofEpochMilli ;
63
- import static java .time .format .DateTimeFormatter .RFC_1123_DATE_TIME ;
61
+ import static java .time .Instant .* ;
62
+ import static java .time .format .DateTimeFormatter .* ;
64
63
import static org .junit .Assert .*;
65
64
import static org .mockito .BDDMockito .*;
66
- import static org .springframework .http .MediaType .APPLICATION_OCTET_STREAM ;
67
- import static org .springframework .http .MediaType .TEXT_PLAIN ;
68
- import static org .springframework .web .method .ResolvableMethod .on ;
69
- import static org .springframework .web .servlet .HandlerMapping .PRODUCIBLE_MEDIA_TYPES_ATTRIBUTE ;
65
+ import static org .springframework .http .MediaType .*;
66
+ import static org .springframework .web .servlet .HandlerMapping .*;
70
67
71
68
/**
72
69
* Test fixture for {@link HttpEntityMethodProcessor} delegating to a mock
@@ -94,6 +91,26 @@ public class HttpEntityMethodProcessorMockTests {
94
91
95
92
private HttpMessageConverter <Object > resourceRegionMessageConverter ;
96
93
94
+ private MethodParameter paramHttpEntity ;
95
+
96
+ private MethodParameter paramRequestEntity ;
97
+
98
+ private MethodParameter paramResponseEntity ;
99
+
100
+ private MethodParameter paramInt ;
101
+
102
+ private MethodParameter returnTypeResponseEntity ;
103
+
104
+ private MethodParameter returnTypeResponseEntityProduces ;
105
+
106
+ private MethodParameter returnTypeResponseEntityResource ;
107
+
108
+ private MethodParameter returnTypeHttpEntity ;
109
+
110
+ private MethodParameter returnTypeHttpEntitySubclass ;
111
+
112
+ private MethodParameter returnTypeInt ;
113
+
97
114
private ModelAndViewContainer mavContainer ;
98
115
99
116
private MockHttpServletRequest servletRequest ;
@@ -102,12 +119,6 @@ public class HttpEntityMethodProcessorMockTests {
102
119
103
120
private ServletWebRequest webRequest ;
104
121
105
- private MethodParameter returnTypeResponseEntity =
106
- on (TestHandler .class ).resolveReturnType (ResponseEntity .class , String .class );
107
-
108
- private MethodParameter returnTypeResponseEntityResource =
109
- on (TestHandler .class ).resolveReturnType (ResponseEntity .class , Resource .class );
110
-
111
122
112
123
@ Before
113
124
@ SuppressWarnings ("unchecked" )
@@ -128,6 +139,20 @@ public void setup() throws Exception {
128
139
processor = new HttpEntityMethodProcessor (Arrays .asList (
129
140
stringHttpMessageConverter , resourceMessageConverter , resourceRegionMessageConverter ));
130
141
142
+ Method handle1 = getClass ().getMethod ("handle1" , HttpEntity .class , ResponseEntity .class ,
143
+ Integer .TYPE , RequestEntity .class );
144
+
145
+ paramHttpEntity = new MethodParameter (handle1 , 0 );
146
+ paramRequestEntity = new MethodParameter (handle1 , 3 );
147
+ paramResponseEntity = new MethodParameter (handle1 , 1 );
148
+ paramInt = new MethodParameter (handle1 , 2 );
149
+ returnTypeResponseEntity = new MethodParameter (handle1 , -1 );
150
+ returnTypeResponseEntityProduces = new MethodParameter (getClass ().getMethod ("handle4" ), -1 );
151
+ returnTypeHttpEntity = new MethodParameter (getClass ().getMethod ("handle2" , HttpEntity .class ), -1 );
152
+ returnTypeHttpEntitySubclass = new MethodParameter (getClass ().getMethod ("handle2x" , HttpEntity .class ), -1 );
153
+ returnTypeInt = new MethodParameter (getClass ().getMethod ("handle3" ), -1 );
154
+ returnTypeResponseEntityResource = new MethodParameter (getClass ().getMethod ("handle5" ), -1 );
155
+
131
156
mavContainer = new ModelAndViewContainer ();
132
157
servletRequest = new MockHttpServletRequest ("GET" , "/foo" );
133
158
servletResponse = new MockHttpServletResponse ();
@@ -137,39 +162,25 @@ public void setup() throws Exception {
137
162
138
163
@ Test
139
164
public void supportsParameter () {
140
- ResolvableMethod method = on (TestHandler .class ).named ("entityParams" ).build ();
141
- assertTrue ("HttpEntity parameter not supported" ,
142
- processor .supportsParameter (method .arg (HttpEntity .class , String .class )));
143
- assertTrue ("RequestEntity parameter not supported" ,
144
- processor .supportsParameter (method .arg (RequestEntity .class , String .class )));
145
- assertFalse ("ResponseEntity parameter supported" ,
146
- processor .supportsParameter (method .arg (ResponseEntity .class , String .class )));
147
- assertFalse ("non-entity parameter supported" ,
148
- processor .supportsParameter (method .arg (Integer .class )));
165
+ assertTrue ("HttpEntity parameter not supported" , processor .supportsParameter (paramHttpEntity ));
166
+ assertTrue ("RequestEntity parameter not supported" , processor .supportsParameter (paramRequestEntity ));
167
+ assertFalse ("ResponseEntity parameter supported" , processor .supportsParameter (paramResponseEntity ));
168
+ assertFalse ("non-entity parameter supported" , processor .supportsParameter (paramInt ));
149
169
}
150
170
151
171
@ Test
152
172
public void supportsReturnType () {
153
- assertTrue ("ResponseEntity return type not supported" ,
154
- processor .supportsReturnType (on (TestHandler .class ).resolveReturnType (ResponseEntity .class , String .class )));
155
- assertTrue ("HttpEntity return type not supported" ,
156
- processor .supportsReturnType (on (TestHandler .class ).resolveReturnType (HttpEntity .class )));
157
- assertTrue ("Custom HttpEntity subclass not supported" ,
158
- processor .supportsReturnType (on (TestHandler .class ).resolveReturnType (CustomHttpEntity .class )));
159
- assertTrue ("Optional ResponseEntity not supported" ,
160
- processor .supportsReturnType (on (TestHandler .class ).resolveReturnType (Optional .class , ResponseEntity .class )));
161
- assertFalse ("RequestEntity return type supported" ,
162
- processor .supportsReturnType (on (TestHandler .class )
163
- .named ("entityParams" ).build ().arg (RequestEntity .class , String .class )));
164
- assertFalse ("non-ResponseBody return type supported" ,
165
- processor .supportsReturnType (on (TestHandler .class ).resolveReturnType (Integer .class )));
173
+ assertTrue ("ResponseEntity return type not supported" , processor .supportsReturnType (returnTypeResponseEntity ));
174
+ assertTrue ("HttpEntity return type not supported" , processor .supportsReturnType (returnTypeHttpEntity ));
175
+ assertTrue ("Custom HttpEntity subclass not supported" , processor .supportsReturnType (returnTypeHttpEntitySubclass ));
176
+ assertFalse ("RequestEntity parameter supported" ,
177
+ processor .supportsReturnType (paramRequestEntity ));
178
+ assertFalse ("non-ResponseBody return type supported" , processor .supportsReturnType (returnTypeInt ));
166
179
}
167
180
168
181
@ Test
169
182
public void shouldResolveHttpEntityArgument () throws Exception {
170
183
String body = "Foo" ;
171
- MethodParameter paramHttpEntity = on (TestHandler .class ).named ("entityParams" )
172
- .build ().arg (HttpEntity .class , String .class );
173
184
174
185
MediaType contentType = TEXT_PLAIN ;
175
186
servletRequest .addHeader ("Content-Type" , contentType .toString ());
@@ -188,8 +199,6 @@ public void shouldResolveHttpEntityArgument() throws Exception {
188
199
@ Test
189
200
public void shouldResolveRequestEntityArgument () throws Exception {
190
201
String body = "Foo" ;
191
- MethodParameter paramRequestEntity = on (TestHandler .class ).named ("entityParams" )
192
- .build ().arg (RequestEntity .class , String .class );
193
202
194
203
MediaType contentType = TEXT_PLAIN ;
195
204
servletRequest .addHeader ("Content-Type" , contentType .toString ());
@@ -216,8 +225,6 @@ public void shouldResolveRequestEntityArgument() throws Exception {
216
225
217
226
@ Test
218
227
public void shouldFailResolvingWhenConverterCannotRead () throws Exception {
219
- MethodParameter paramHttpEntity = on (TestHandler .class ).named ("entityParams" )
220
- .build ().arg (HttpEntity .class , String .class );
221
228
MediaType contentType = TEXT_PLAIN ;
222
229
servletRequest .setMethod ("POST" );
223
230
servletRequest .addHeader ("Content-Type" , contentType .toString ());
@@ -231,8 +238,6 @@ public void shouldFailResolvingWhenConverterCannotRead() throws Exception {
231
238
232
239
@ Test
233
240
public void shouldFailResolvingWhenContentTypeNotSupported () throws Exception {
234
- MethodParameter paramHttpEntity = on (TestHandler .class ).named ("entityParams" )
235
- .build ().arg (HttpEntity .class , String .class );
236
241
servletRequest .setMethod ("POST" );
237
242
servletRequest .setContent ("some content" .getBytes (StandardCharsets .UTF_8 ));
238
243
this .thrown .expect (HttpMediaTypeNotSupportedException .class );
@@ -255,14 +260,13 @@ public void shouldHandleReturnValue() throws Exception {
255
260
256
261
@ Test
257
262
public void shouldHandleReturnValueWithProducibleMediaType () throws Exception {
258
- MethodParameter returnType = on (TestHandler .class ).resolveReturnType (ResponseEntity .class , CharSequence .class );
259
263
String body = "Foo" ;
260
264
ResponseEntity <String > returnValue = new ResponseEntity <>(body , HttpStatus .OK );
261
265
servletRequest .addHeader ("Accept" , "text/*" );
262
266
servletRequest .setAttribute (PRODUCIBLE_MEDIA_TYPES_ATTRIBUTE , Collections .singleton (MediaType .TEXT_HTML ));
263
267
given (stringHttpMessageConverter .canWrite (String .class , MediaType .TEXT_HTML )).willReturn (true );
264
268
265
- processor .handleReturnValue (returnValue , returnType , mavContainer , webRequest );
269
+ processor .handleReturnValue (returnValue , returnTypeResponseEntityProduces , mavContainer , webRequest );
266
270
267
271
assertTrue (mavContainer .isRequestHandled ());
268
272
verify (stringHttpMessageConverter ).write (eq (body ), eq (MediaType .TEXT_HTML ), isA (HttpOutputMessage .class ));
@@ -307,7 +311,6 @@ public void shouldFailHandlingWhenContentTypeNotSupported() throws Exception {
307
311
308
312
@ Test
309
313
public void shouldFailHandlingWhenConverterCannotWrite () throws Exception {
310
- MethodParameter returnType = on (TestHandler .class ).resolveReturnType (ResponseEntity .class , CharSequence .class );
311
314
String body = "Foo" ;
312
315
ResponseEntity <String > returnValue = new ResponseEntity <>(body , HttpStatus .OK );
313
316
MediaType accepted = TEXT_PLAIN ;
@@ -319,7 +322,7 @@ public void shouldFailHandlingWhenConverterCannotWrite() throws Exception {
319
322
given (stringHttpMessageConverter .canWrite (String .class , accepted )).willReturn (false );
320
323
321
324
this .thrown .expect (HttpMediaTypeNotAcceptableException .class );
322
- processor .handleReturnValue (returnValue , returnType , mavContainer , webRequest );
325
+ processor .handleReturnValue (returnValue , returnTypeResponseEntityProduces , mavContainer , webRequest );
323
326
}
324
327
325
328
@ Test // SPR-9142
@@ -358,16 +361,6 @@ public void shouldHandleResponseHeaderAndBody() throws Exception {
358
361
assertEquals ("headerValue" , outputMessage .getValue ().getHeaders ().get ("header" ).get (0 ));
359
362
}
360
363
361
- @ Test // SPR-13281
362
- public void shouldReturnNotFoundWhenEmptyOptional () throws Exception {
363
- MethodParameter returnType = on (TestHandler .class ).resolveReturnType (Optional .class , ResponseEntity .class );
364
- Optional <ResponseEntity > returnValue = Optional .empty ();
365
-
366
- processor .handleReturnValue (returnValue , returnType , mavContainer , webRequest );
367
- assertTrue (mavContainer .isRequestHandled ());
368
- assertEquals (HttpStatus .NOT_FOUND .value (), servletResponse .getStatus ());
369
- }
370
-
371
364
@ Test
372
365
public void shouldHandleLastModifiedWithHttp304 () throws Exception {
373
366
long currentTime = new Date ().getTime ();
@@ -704,46 +697,38 @@ private void assertConditionalResponse(HttpStatus status, String body, String et
704
697
}
705
698
}
706
699
707
- private static class TestHandler {
708
-
709
- @ SuppressWarnings ("unused" )
710
- public ResponseEntity <String > entityParams (HttpEntity <String > httpEntity , ResponseEntity <String > entity ,
711
- Integer i , RequestEntity <String > requestEntity ) {
712
700
713
- return entity ;
714
- }
715
-
716
- @ SuppressWarnings ("unused" )
717
- public HttpEntity <?> httpEntity (HttpEntity <?> entity ) {
718
- return entity ;
719
- }
701
+ @ SuppressWarnings ("unused" )
702
+ public ResponseEntity <String > handle1 (HttpEntity <String > httpEntity , ResponseEntity <String > entity ,
703
+ int i , RequestEntity <String > requestEntity ) {
720
704
721
- @ SuppressWarnings ("unused" )
722
- public CustomHttpEntity customHttpEntity (HttpEntity <?> entity ) {
723
- return new CustomHttpEntity ();
724
- }
705
+ return entity ;
706
+ }
725
707
726
- @ SuppressWarnings ("unused" )
727
- public Optional < ResponseEntity > handleOptionalEntity ( ) {
728
- return null ;
729
- }
708
+ @ SuppressWarnings ("unused" )
709
+ public HttpEntity <?> handle2 ( HttpEntity <?> entity ) {
710
+ return entity ;
711
+ }
730
712
731
- @ SuppressWarnings ("unused" )
732
- @ RequestMapping (produces = {"text/html" , "application/xhtml+xml" })
733
- public ResponseEntity <CharSequence > produces () {
734
- return null ;
735
- }
713
+ @ SuppressWarnings ("unused" )
714
+ public CustomHttpEntity handle2x (HttpEntity <?> entity ) {
715
+ return new CustomHttpEntity ();
716
+ }
736
717
737
- @ SuppressWarnings ("unused" )
738
- public ResponseEntity < Resource > resourceResponseEntity () {
739
- return null ;
740
- }
718
+ @ SuppressWarnings ("unused" )
719
+ public int handle3 () {
720
+ return 42 ;
721
+ }
741
722
742
- @ SuppressWarnings ("unused" )
743
- public Integer integer () {
744
- return 42 ;
745
- }
723
+ @ SuppressWarnings ("unused" )
724
+ @ RequestMapping (produces = {"text/html" , "application/xhtml+xml" })
725
+ public ResponseEntity <String > handle4 () {
726
+ return null ;
727
+ }
746
728
729
+ @ SuppressWarnings ("unused" )
730
+ public ResponseEntity <Resource > handle5 () {
731
+ return null ;
747
732
}
748
733
749
734
@ SuppressWarnings ("unused" )
0 commit comments