5050import org .springframework .web .context .request .ServletRequestAttributes ;
5151import org .springframework .web .context .support .AnnotationConfigWebApplicationContext ;
5252import org .springframework .web .servlet .DispatcherServlet ;
53+ import org .springframework .web .servlet .ModelAndView ;
5354import org .springframework .web .servlet .config .annotation .EnableWebMvc ;
5455import org .springframework .web .servlet .config .annotation .WebMvcConfigurerAdapter ;
5556import org .springframework .web .util .UriComponents ;
@@ -85,38 +86,38 @@ public void reset() {
8586
8687
8788 @ Test
88- public void testFromController () {
89+ public void fromControllerPlain () {
8990 UriComponents uriComponents = fromController (PersonControllerImpl .class ).build ();
9091 assertThat (uriComponents .toUriString (), Matchers .endsWith ("/people" ));
9192 }
9293
9394 @ Test
94- public void testFromControllerUriTemplate () {
95+ public void fromControllerUriTemplate () {
9596 UriComponents uriComponents = fromController (PersonsAddressesController .class ).buildAndExpand (15 );
9697 assertThat (uriComponents .toUriString (), endsWith ("/people/15/addresses" ));
9798 }
9899
99100 @ Test
100- public void testFromControllerSubResource () {
101+ public void fromControllerSubResource () {
101102 UriComponents uriComponents = fromController (PersonControllerImpl .class ).pathSegment ("something" ).build ();
102103
103104 assertThat (uriComponents .toUriString (), endsWith ("/people/something" ));
104105 }
105106
106107 @ Test
107- public void testFromControllerTwoTypeLevelMappings () {
108+ public void fromControllerTwoTypeLevelMappings () {
108109 UriComponents uriComponents = fromController (InvalidController .class ).build ();
109110 assertThat (uriComponents .toUriString (), is ("http://localhost/persons" ));
110111 }
111112
112113 @ Test
113- public void testFromControllerNotMapped () {
114+ public void fromControllerNotMapped () {
114115 UriComponents uriComponents = fromController (UnmappedController .class ).build ();
115116 assertThat (uriComponents .toUriString (), is ("http://localhost/" ));
116117 }
117118
118119 @ Test
119- public void testFromControllerWithCustomBaseUrlViaStaticCall () {
120+ public void fromControllerWithCustomBaseUrlViaStaticCall () {
120121 UriComponentsBuilder builder = UriComponentsBuilder .fromUriString ("http://example.org:9090/base" );
121122 UriComponents uriComponents = fromController (builder , PersonControllerImpl .class ).build ();
122123
@@ -125,25 +126,49 @@ public void testFromControllerWithCustomBaseUrlViaStaticCall() {
125126 }
126127
127128 @ Test
128- public void testFromControllerWithCustomBaseUrlViaInstance () {
129+ public void fromControllerWithCustomBaseUrlViaInstance () {
129130 UriComponentsBuilder builder = UriComponentsBuilder .fromUriString ("http://example.org:9090/base" );
130- MvcUriComponentsBuilder mvcBuilder = MvcUriComponentsBuilder . relativeTo (builder );
131+ MvcUriComponentsBuilder mvcBuilder = relativeTo (builder );
131132 UriComponents uriComponents = mvcBuilder .withController (PersonControllerImpl .class ).build ();
132133
133134 assertEquals ("http://example.org:9090/base/people" , uriComponents .toString ());
134135 assertEquals ("http://example.org:9090/base" , builder .toUriString ());
135136 }
136137
137138 @ Test
138- public void testFromMethodNamePathVariable () {
139+ public void usesForwardedHostAsHostIfHeaderIsSet () {
140+ this .request .addHeader ("X-Forwarded-Host" , "somethingDifferent" );
141+ UriComponents uriComponents = fromController (PersonControllerImpl .class ).build ();
142+
143+ assertThat (uriComponents .toUriString (), startsWith ("http://somethingDifferent" ));
144+ }
145+
146+ @ Test
147+ public void usesForwardedHostAndPortFromHeader () {
148+ request .addHeader ("X-Forwarded-Host" , "foobar:8088" );
149+ UriComponents uriComponents = fromController (PersonControllerImpl .class ).build ();
150+
151+ assertThat (uriComponents .toUriString (), startsWith ("http://foobar:8088" ));
152+ }
153+
154+ @ Test
155+ public void usesFirstHostOfXForwardedHost () {
156+ request .addHeader ("X-Forwarded-Host" , "barfoo:8888, localhost:8088" );
157+ UriComponents uriComponents = fromController (PersonControllerImpl .class ).build ();
158+
159+ assertThat (uriComponents .toUriString (), startsWith ("http://barfoo:8888" ));
160+ }
161+
162+ @ Test
163+ public void fromMethodNamePathVariable () {
139164 UriComponents uriComponents = fromMethodName (ControllerWithMethods .class ,
140165 "methodWithPathVariable" , "1" ).build ();
141166
142167 assertThat (uriComponents .toUriString (), is ("http://localhost/something/1/foo" ));
143168 }
144169
145170 @ Test
146- public void testFromMethodNameTypeLevelPathVariable () {
171+ public void fromMethodNameTypeLevelPathVariable () {
147172 this .request .setContextPath ("/myapp" );
148173 UriComponents uriComponents = fromMethodName (
149174 PersonsAddressesController .class , "getAddressesForCountry" , "DE" ).buildAndExpand ("1" );
@@ -152,7 +177,7 @@ public void testFromMethodNameTypeLevelPathVariable() {
152177 }
153178
154179 @ Test
155- public void testFromMethodNameTwoPathVariables () {
180+ public void fromMethodNameTwoPathVariables () {
156181 DateTime now = DateTime .now ();
157182 UriComponents uriComponents = fromMethodName (
158183 ControllerWithMethods .class , "methodWithTwoPathVariables" , 1 , now ).build ();
@@ -161,7 +186,7 @@ public void testFromMethodNameTwoPathVariables() {
161186 }
162187
163188 @ Test
164- public void testFromMethodNameWithPathVarAndRequestParam () {
189+ public void fromMethodNameWithPathVarAndRequestParam () {
165190 UriComponents uriComponents = fromMethodName (
166191 ControllerWithMethods .class , "methodForNextPage" , "1" , 10 , 5 ).build ();
167192
@@ -179,21 +204,21 @@ public void fromMethodNameWithBridgedMethod() {
179204 }
180205
181206 @ Test // SPR-11391
182- public void testFromMethodNameTypeLevelPathVariableWithoutArgumentValue () {
207+ public void fromMethodNameTypeLevelPathVariableWithoutArgumentValue () {
183208 UriComponents uriComponents = fromMethodName (UserContactController .class , "showCreate" , 123 ).build ();
184209
185210 assertThat (uriComponents .getPath (), is ("/user/123/contacts/create" ));
186211 }
187212
188213 @ Test
189- public void testFromMethodNameNotMapped () {
214+ public void fromMethodNameNotMapped () {
190215 UriComponents uriComponents = fromMethodName (UnmappedController .class , "unmappedMethod" ).build ();
191216
192217 assertThat (uriComponents .toUriString (), is ("http://localhost/" ));
193218 }
194219
195220 @ Test
196- public void testFromMethodNameWithCustomBaseUrlViaStaticCall () {
221+ public void fromMethodNameWithCustomBaseUrlViaStaticCall () {
197222 UriComponentsBuilder builder = UriComponentsBuilder .fromUriString ("http://example.org:9090/base" );
198223 UriComponents uriComponents = fromMethodName (builder , ControllerWithMethods .class ,
199224 "methodWithPathVariable" , "1" ).build ();
@@ -203,57 +228,57 @@ public void testFromMethodNameWithCustomBaseUrlViaStaticCall() {
203228 }
204229
205230 @ Test
206- public void testFromMethodNameWithCustomBaseUrlViaInstance () {
231+ public void fromMethodNameWithCustomBaseUrlViaInstance () {
207232 UriComponentsBuilder builder = UriComponentsBuilder .fromUriString ("http://example.org:9090/base" );
208- MvcUriComponentsBuilder mvcBuilder = MvcUriComponentsBuilder . relativeTo (builder );
233+ MvcUriComponentsBuilder mvcBuilder = relativeTo (builder );
209234 UriComponents uriComponents = mvcBuilder .withMethodName (ControllerWithMethods .class ,
210235 "methodWithPathVariable" , "1" ).build ();
211236
212237 assertEquals ("http://example.org:9090/base/something/1/foo" , uriComponents .toString ());
213238 assertEquals ("http://example.org:9090/base" , builder .toUriString ());
214239 }
215240
216- @ Test
217- public void testFromMethodNameWithMetaAnnotation () {
218- UriComponents uriComponents = fromMethodName (MetaAnnotationController .class , "handleInput" ).build ();
219- assertThat (uriComponents .toUriString (), is ("http://localhost/input" ));
220- }
221-
222241 @ Test // SPR-14405
223- public void testFromMappingNameWithOptionalParam () {
242+ public void fromMethodNameWithOptionalParam () {
224243 UriComponents uriComponents = fromMethodName (ControllerWithMethods .class ,
225244 "methodWithOptionalParam" , new Object [] {null }).build ();
226245
227246 assertThat (uriComponents .toUriString (), is ("http://localhost/something/optional-param" ));
228247 }
229248
230249 @ Test
231- public void testFromMethodCall () {
250+ public void fromMethodNameWithMetaAnnotation () {
251+ UriComponents uriComponents = fromMethodName (MetaAnnotationController .class , "handleInput" ).build ();
252+
253+ assertThat (uriComponents .toUriString (), is ("http://localhost/input" ));
254+ }
255+
256+ @ Test
257+ public void fromMethodCallPlain () {
232258 UriComponents uriComponents = fromMethodCall (on (ControllerWithMethods .class ).myMethod (null )).build ();
233259
234260 assertThat (uriComponents .toUriString (), startsWith ("http://localhost" ));
235261 assertThat (uriComponents .toUriString (), endsWith ("/something/else" ));
236262 }
237263
238264 @ Test
239- public void testFromMethodCallOnSubclass () {
265+ public void fromMethodCallOnSubclass () {
240266 UriComponents uriComponents = fromMethodCall (on (ExtendedController .class ).myMethod (null )).build ();
241267
242268 assertThat (uriComponents .toUriString (), startsWith ("http://localhost" ));
243269 assertThat (uriComponents .toUriString (), endsWith ("/extended/else" ));
244270 }
245271
246272 @ Test
247- public void testFromMethodCallWithTypeLevelUriVars () {
273+ public void fromMethodCallWithTypeLevelUriVars () {
248274 UriComponents uriComponents = fromMethodCall (
249275 on (PersonsAddressesController .class ).getAddressesForCountry ("DE" )).buildAndExpand (15 );
250276
251277 assertThat (uriComponents .toUriString (), endsWith ("/people/15/addresses/DE" ));
252278 }
253279
254-
255280 @ Test
256- public void testFromMethodCallWithPathVar () {
281+ public void fromMethodCallWithPathVariable () {
257282 UriComponents uriComponents = fromMethodCall (
258283 on (ControllerWithMethods .class ).methodWithPathVariable ("1" )).build ();
259284
@@ -262,7 +287,7 @@ public void testFromMethodCallWithPathVar() {
262287 }
263288
264289 @ Test
265- public void testFromMethodCallWithPathVarAndRequestParams () {
290+ public void fromMethodCallWithPathVariableAndRequestParams () {
266291 UriComponents uriComponents = fromMethodCall (
267292 on (ControllerWithMethods .class ).methodForNextPage ("1" , 10 , 5 )).build ();
268293
@@ -274,7 +299,7 @@ public void testFromMethodCallWithPathVarAndRequestParams() {
274299 }
275300
276301 @ Test
277- public void testFromMethodCallWithPathVarAndMultiValueRequestParams () {
302+ public void fromMethodCallWithPathVariableAndMultiValueRequestParams () {
278303 UriComponents uriComponents = fromMethodCall (
279304 on (ControllerWithMethods .class ).methodWithMultiValueRequestParams ("1" , Arrays .asList (3 , 7 ), 5 )).build ();
280305
@@ -286,7 +311,7 @@ public void testFromMethodCallWithPathVarAndMultiValueRequestParams() {
286311 }
287312
288313 @ Test
289- public void testFromMethodCallWithCustomBaseUrlViaStaticCall () {
314+ public void fromMethodCallWithCustomBaseUrlViaStaticCall () {
290315 UriComponentsBuilder builder = UriComponentsBuilder .fromUriString ("http://example.org:9090/base" );
291316 UriComponents uriComponents = fromMethodCall (builder , on (ControllerWithMethods .class ).myMethod (null )).build ();
292317
@@ -295,17 +320,49 @@ public void testFromMethodCallWithCustomBaseUrlViaStaticCall() {
295320 }
296321
297322 @ Test
298- public void testFromMethodCallWithCustomBaseUrlViaInstance () {
323+ public void fromMethodCallWithCustomBaseUrlViaInstance () {
299324 UriComponentsBuilder builder = UriComponentsBuilder .fromUriString ("http://example.org:9090/base" );
300- MvcUriComponentsBuilder mvcBuilder = MvcUriComponentsBuilder . relativeTo (builder );
325+ MvcUriComponentsBuilder mvcBuilder = relativeTo (builder );
301326 UriComponents result = mvcBuilder .withMethodCall (on (ControllerWithMethods .class ).myMethod (null )).build ();
302327
303328 assertEquals ("http://example.org:9090/base/something/else" , result .toString ());
304329 assertEquals ("http://example.org:9090/base" , builder .toUriString ());
305330 }
306331
332+ @ Test // SPR-16710
333+ public void fromMethodCallWithModelAndViewReturnType () {
334+ UriComponents uriComponents = fromMethodCall (
335+ on (BookingControllerWithModelAndView .class ).getBooking (21L )).buildAndExpand (42 );
336+
337+ assertEquals ("http://localhost/hotels/42/bookings/21" , uriComponents .encode ().toUri ().toString ());
338+ }
339+
340+ @ Test // SPR-16710
341+ public void fromMethodCallWithObjectReturnType () {
342+ UriComponents uriComponents = fromMethodCall (
343+ on (BookingControllerWithObject .class ).getBooking (21L )).buildAndExpand (42 );
344+
345+ assertEquals ("http://localhost/hotels/42/bookings/21" , uriComponents .encode ().toUri ().toString ());
346+ }
347+
348+ @ Test (expected = IllegalStateException .class ) // SPR-16710
349+ public void fromMethodCallWithStringReturnType () {
350+ UriComponents uriComponents = fromMethodCall (
351+ on (BookingControllerWithString .class ).getBooking (21L )).buildAndExpand (42 );
352+
353+ assertEquals ("http://localhost/hotels/42/bookings/21" , uriComponents .encode ().toUri ().toString ());
354+ }
355+
356+ @ Test // SPR-16710
357+ public void fromMethodNameWithStringReturnType () {
358+ UriComponents uriComponents = fromMethodName (
359+ BookingControllerWithString .class , "getBooking" , 21L ).buildAndExpand (42 );
360+
361+ assertEquals ("http://localhost/hotels/42/bookings/21" , uriComponents .encode ().toUri ().toString ());
362+ }
363+
307364 @ Test
308- public void testFromMappingName () {
365+ public void fromMappingNamePlain () {
309366 AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext ();
310367 context .setServletContext (new MockServletContext ());
311368 context .register (WebConfig .class );
@@ -317,12 +374,12 @@ public void testFromMappingName() {
317374 this .request .setContextPath ("/base" );
318375
319376 String mappingName = "PAC#getAddressesForCountry" ;
320- String url = MvcUriComponentsBuilder . fromMappingName (mappingName ).arg (0 , "DE" ).buildAndExpand (123 );
377+ String url = fromMappingName (mappingName ).arg (0 , "DE" ).buildAndExpand (123 );
321378 assertEquals ("/base/people/123/addresses/DE" , url );
322379 }
323380
324381 @ Test
325- public void testFromMappingNameWithCustomBaseUrl () {
382+ public void fromMappingNameWithCustomBaseUrl () {
326383 AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext ();
327384 context .setServletContext (new MockServletContext ());
328385 context .register (WebConfig .class );
@@ -331,42 +388,11 @@ public void testFromMappingNameWithCustomBaseUrl() {
331388 this .request .setAttribute (DispatcherServlet .WEB_APPLICATION_CONTEXT_ATTRIBUTE , context );
332389
333390 UriComponentsBuilder baseUrl = UriComponentsBuilder .fromUriString ("http://example.org:9999/base" );
334- MvcUriComponentsBuilder mvcBuilder = MvcUriComponentsBuilder . relativeTo (baseUrl );
391+ MvcUriComponentsBuilder mvcBuilder = relativeTo (baseUrl );
335392 String url = mvcBuilder .withMappingName ("PAC#getAddressesForCountry" ).arg (0 , "DE" ).buildAndExpand (123 );
336393 assertEquals ("http://example.org:9999/base/people/123/addresses/DE" , url );
337394 }
338395
339- @ Test
340- public void usesForwardedHostAsHostIfHeaderIsSet () {
341- this .request .addHeader ("X-Forwarded-Host" , "somethingDifferent" );
342- UriComponents uriComponents = fromController (PersonControllerImpl .class ).build ();
343-
344- assertThat (uriComponents .toUriString (), startsWith ("http://somethingDifferent" ));
345- }
346-
347- @ Test
348- public void usesForwardedHostAndPortFromHeader () {
349- request .addHeader ("X-Forwarded-Host" , "foobar:8088" );
350- UriComponents uriComponents = fromController (PersonControllerImpl .class ).build ();
351-
352- assertThat (uriComponents .toUriString (), startsWith ("http://foobar:8088" ));
353- }
354-
355- @ Test
356- public void usesFirstHostOfXForwardedHost () {
357- request .addHeader ("X-Forwarded-Host" , "barfoo:8888, localhost:8088" );
358- UriComponents uriComponents = fromController (PersonControllerImpl .class ).build ();
359-
360- assertThat (uriComponents .toUriString (), startsWith ("http://barfoo:8888" ));
361- }
362-
363- @ Test // SPR-16710
364- public void withStringReturnType () {
365- UriComponents uriComponents = MvcUriComponentsBuilder .fromMethodCall (
366- on (BookingController .class ).getBooking (21L )).buildAndExpand (42 );
367- assertEquals ("http://localhost/hotels/42/bookings/21" , uriComponents .encode ().toUri ().toString ());
368- }
369-
370396
371397 static class Person {
372398
@@ -516,12 +542,34 @@ public PersonsAddressesController controller() {
516542
517543 @ Controller
518544 @ RequestMapping ("/hotels/{hotel}" )
519- public class BookingController {
545+ static class BookingControllerWithModelAndView {
546+
547+ @ GetMapping ("/bookings/{booking}" )
548+ public ModelAndView getBooking (@ PathVariable Long booking ) {
549+ return new ModelAndView ("url" );
550+ }
551+ }
552+
553+
554+ @ Controller
555+ @ RequestMapping ("/hotels/{hotel}" )
556+ static class BookingControllerWithObject {
520557
521558 @ GetMapping ("/bookings/{booking}" )
522559 public Object getBooking (@ PathVariable Long booking ) {
523560 return "url" ;
524561 }
525562 }
526563
564+
565+ @ Controller
566+ @ RequestMapping ("/hotels/{hotel}" )
567+ static class BookingControllerWithString {
568+
569+ @ GetMapping ("/bookings/{booking}" )
570+ public String getBooking (@ PathVariable Long booking ) {
571+ return "url" ;
572+ }
573+ }
574+
527575}
0 commit comments