51
51
import org .springframework .web .servlet .ModelAndView ;
52
52
53
53
/**
54
- * Test various scenarios for detecting method-level and method parameter annotations depending
55
- * on where they are located -- on interfaces, parent classes, in parameterized methods, or in
54
+ * Test various scenarios for detecting method-level and method parameter annotations depending
55
+ * on where they are located -- on interfaces, parent classes, in parameterized methods, or in
56
56
* combination with proxies.
57
- *
57
+ *
58
58
* @author Rossen Stoyanchev
59
59
*/
60
60
@ RunWith (Parameterized .class )
61
61
public class HandlerMethodAnnotationDetectionTests {
62
-
62
+
63
63
@ Parameters
64
64
public static Collection <Object []> handlerTypes () {
65
65
Object [][] array = new Object [12 ][2 ];
66
66
67
67
array [0 ] = new Object [] { SimpleController .class , true }; // CGLib proxy
68
68
array [1 ] = new Object [] { SimpleController .class , false };
69
-
69
+
70
70
array [2 ] = new Object [] { AbstractClassController .class , true }; // CGLib proxy
71
71
array [3 ] = new Object [] { AbstractClassController .class , false };
72
-
73
- array [4 ] = new Object [] { ParameterizedAbstractClassController .class , false }; // CGLib proxy
74
- array [5 ] = new Object [] { ParameterizedAbstractClassController .class , false };
75
-
72
+
73
+ array [4 ] = new Object [] { ParameterizedAbstractClassController .class , false }; // CGLib proxy
74
+ array [5 ] = new Object [] { ParameterizedAbstractClassController .class , false };
75
+
76
76
array [6 ] = new Object [] { InterfaceController .class , true }; // JDK dynamic proxy
77
- array [7 ] = new Object [] { InterfaceController .class , false };
78
-
79
- array [8 ] = new Object [] { ParameterizedInterfaceController .class , false }; // no AOP
80
- array [9 ] = new Object [] { ParameterizedInterfaceController .class , false };
81
-
77
+ array [7 ] = new Object [] { InterfaceController .class , false };
78
+
79
+ array [8 ] = new Object [] { ParameterizedInterfaceController .class , false }; // no AOP
80
+ array [9 ] = new Object [] { ParameterizedInterfaceController .class , false };
81
+
82
82
array [10 ] = new Object [] { SupportClassController .class , true }; // CGLib proxy
83
83
array [11 ] = new Object [] { SupportClassController .class , false };
84
-
84
+
85
85
return Arrays .asList (array );
86
86
}
87
87
@@ -101,7 +101,7 @@ public HandlerMethodAnnotationDetectionTests(Class<?> controllerType, boolean us
101
101
context .getBeanFactory ().registerSingleton ("advisor" , new DefaultPointcutAdvisor (new SimpleTraceInterceptor ()));
102
102
}
103
103
context .refresh ();
104
-
104
+
105
105
handlerMapping .setApplicationContext (context );
106
106
handlerAdapter .afterPropertiesSet ();
107
107
exceptionResolver .afterPropertiesSet ();
@@ -113,12 +113,12 @@ public void testRequestMappingMethod() throws Exception {
113
113
SimpleDateFormat dateFormat = new SimpleDateFormat (datePattern );
114
114
String dateA = "11:01:2011" ;
115
115
String dateB = "11:02:2011" ;
116
-
116
+
117
117
MockHttpServletRequest request = new MockHttpServletRequest ("POST" , "/path1/path2" );
118
118
request .setParameter ("datePattern" , datePattern );
119
119
request .addHeader ("header1" , dateA );
120
120
request .addHeader ("header2" , dateB );
121
-
121
+
122
122
HandlerExecutionChain chain = handlerMapping .getHandler (request );
123
123
assertNotNull (chain );
124
124
@@ -133,7 +133,7 @@ public void testRequestMappingMethod() throws Exception {
133
133
assertEquals ("failure" , response .getContentAsString ());
134
134
}
135
135
136
-
136
+
137
137
/**
138
138
* SIMPLE CASE
139
139
*/
@@ -156,15 +156,15 @@ public void initModel(@RequestHeader("header1") Date date, Model model) {
156
156
public Date handle (@ RequestHeader ("header2" ) Date date ) throws Exception {
157
157
return date ;
158
158
}
159
-
159
+
160
160
@ ExceptionHandler (Exception .class )
161
161
@ ResponseBody
162
162
public String handleException (Exception exception ) {
163
163
return exception .getMessage ();
164
164
}
165
- }
165
+ }
166
+
166
167
167
-
168
168
@ Controller
169
169
static abstract class MappingAbstractClass {
170
170
@@ -177,15 +177,15 @@ static abstract class MappingAbstractClass {
177
177
@ RequestMapping (value ="/path1/path2" , method =RequestMethod .POST )
178
178
@ ModelAttribute ("attr2" )
179
179
public abstract Date handle (Date date , Model model ) throws Exception ;
180
-
180
+
181
181
@ ExceptionHandler (Exception .class )
182
182
@ ResponseBody
183
183
public abstract String handleException (Exception exception );
184
- }
184
+ }
185
185
186
186
/**
187
187
* CONTROLLER WITH ABSTRACT CLASS
188
- *
188
+ *
189
189
* <p>All annotations can be on methods in the abstract class except parameter annotations.
190
190
*/
191
191
static class AbstractClassController extends MappingAbstractClass {
@@ -202,14 +202,15 @@ public void initModel(@RequestHeader("header1") Date date, Model model) {
202
202
public Date handle (@ RequestHeader ("header2" ) Date date , Model model ) throws Exception {
203
203
return date ;
204
204
}
205
-
205
+
206
206
public String handleException (Exception exception ) {
207
207
return exception .getMessage ();
208
208
}
209
209
}
210
-
211
-
212
- @ Controller
210
+
211
+ // SPR-9374
212
+
213
+ @ RequestMapping
213
214
static interface MappingInterface {
214
215
215
216
@ InitBinder
@@ -221,15 +222,15 @@ static interface MappingInterface {
221
222
@ RequestMapping (value ="/path1/path2" , method =RequestMethod .POST )
222
223
@ ModelAttribute ("attr2" )
223
224
Date handle (@ RequestHeader ("header2" ) Date date , Model model ) throws Exception ;
224
-
225
+
225
226
@ ExceptionHandler (Exception .class )
226
227
@ ResponseBody
227
228
String handleException (Exception exception );
228
- }
229
+ }
229
230
230
231
/**
231
232
* CONTROLLER WITH INTERFACE
232
- *
233
+ *
233
234
* No AOP:
234
235
* All annotations can be on interface methods except parameter annotations.
235
236
*
@@ -250,7 +251,7 @@ public void initModel(@RequestHeader("header1") Date date, Model model) {
250
251
public Date handle (@ RequestHeader ("header2" ) Date date , Model model ) throws Exception {
251
252
return date ;
252
253
}
253
-
254
+
254
255
public String handleException (Exception exception ) {
255
256
return exception .getMessage ();
256
257
}
@@ -269,15 +270,15 @@ static abstract class MappingParameterizedAbstractClass<A, B, C> {
269
270
@ RequestMapping (value ="/path1/path2" , method =RequestMethod .POST )
270
271
@ ModelAttribute ("attr2" )
271
272
public abstract Date handle (C date , Model model ) throws Exception ;
272
-
273
+
273
274
@ ExceptionHandler (Exception .class )
274
275
@ ResponseBody
275
276
public abstract String handleException (Exception exception );
276
- }
277
+ }
277
278
278
279
/**
279
280
* CONTROLLER WITH PARAMETERIZED BASE CLASS
280
- *
281
+ *
281
282
* <p>All annotations can be on methods in the abstract class except parameter annotations.
282
283
*/
283
284
static class ParameterizedAbstractClassController extends MappingParameterizedAbstractClass <String , Date , Date > {
@@ -294,14 +295,13 @@ public void initModel(@RequestHeader("header1") Date date, Model model) {
294
295
public Date handle (@ RequestHeader ("header2" ) Date date , Model model ) throws Exception {
295
296
return date ;
296
297
}
297
-
298
+
298
299
public String handleException (Exception exception ) {
299
300
return exception .getMessage ();
300
301
}
301
302
}
302
303
303
-
304
- @ Controller
304
+ @ RequestMapping
305
305
static interface MappingParameterizedInterface <A , B , C > {
306
306
307
307
@ InitBinder
@@ -313,17 +313,17 @@ static interface MappingParameterizedInterface<A, B, C> {
313
313
@ RequestMapping (value ="/path1/path2" , method =RequestMethod .POST )
314
314
@ ModelAttribute ("attr2" )
315
315
Date handle (C date , Model model ) throws Exception ;
316
-
316
+
317
317
@ ExceptionHandler (Exception .class )
318
318
@ ResponseBody
319
319
String handleException (Exception exception );
320
- }
320
+ }
321
321
322
322
/**
323
323
* CONTROLLER WITH PARAMETERIZED INTERFACE
324
- *
324
+ *
325
325
* <p>All annotations can be on interface except parameter annotations.
326
- *
326
+ *
327
327
* <p>Cannot be used as JDK dynamic proxy since parameterized interface does not contain type information.
328
328
*/
329
329
static class ParameterizedInterfaceController implements MappingParameterizedInterface <String , Date , Date > {
@@ -344,18 +344,18 @@ public void initModel(@RequestHeader("header1") Date date, Model model) {
344
344
public Date handle (@ RequestHeader ("header2" ) Date date , Model model ) throws Exception {
345
345
return date ;
346
346
}
347
-
347
+
348
348
@ ExceptionHandler (Exception .class )
349
349
@ ResponseBody
350
350
public String handleException (Exception exception ) {
351
351
return exception .getMessage ();
352
352
}
353
- }
354
-
355
-
353
+ }
354
+
355
+
356
356
/**
357
357
* SPR-8248
358
- *
358
+ *
359
359
* <p>Support class contains all annotations. Subclass has type-level @{@link RequestMapping}.
360
360
*/
361
361
@ Controller
@@ -377,17 +377,17 @@ public void initModel(@RequestHeader("header1") Date date, Model model) {
377
377
public Date handle (@ RequestHeader ("header2" ) Date date , Model model ) throws Exception {
378
378
return date ;
379
379
}
380
-
380
+
381
381
@ ExceptionHandler (Exception .class )
382
382
@ ResponseBody
383
383
public String handleException (Exception exception ) {
384
384
return exception .getMessage ();
385
385
}
386
- }
386
+ }
387
387
388
388
@ Controller
389
389
@ RequestMapping ("/path1" )
390
390
static class SupportClassController extends MappingSupportClass {
391
- }
391
+ }
392
392
393
393
}
0 commit comments