Skip to content

Commit 5007d01

Browse files
committed
Fix for encoding issue with MvcUriComponentsBuilder
Provide method for stronger encoding of expanded URI variables when building links from views. Issue: SPR-17027
1 parent f1c55a3 commit 5007d01

File tree

2 files changed

+34
-12
lines changed

2 files changed

+34
-12
lines changed

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -832,6 +832,16 @@ public MethodArgumentBuilder arg(int index, Object value) {
832832
return this;
833833
}
834834

835+
/**
836+
* Use this method only if you need to apply strong encoding to expanded
837+
* URI variables by quoting all characters with reserved meaning.
838+
* @since 5.0.8
839+
*/
840+
public MethodArgumentBuilder encode() {
841+
this.baseUrl.encode();
842+
return this;
843+
}
844+
835845
public String build() {
836846
return fromMethodInternal(this.baseUrl, this.controllerType, this.method, this.argumentValues)
837847
.build(false).encode().toUriString();

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

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -363,12 +363,7 @@ public void fromMethodNameWithStringReturnType() {
363363

364364
@Test
365365
public void fromMappingNamePlain() {
366-
AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
367-
context.setServletContext(new MockServletContext());
368-
context.register(WebConfig.class);
369-
context.refresh();
370-
371-
this.request.setAttribute(DispatcherServlet.WEB_APPLICATION_CONTEXT_ATTRIBUTE, context);
366+
initWebApplicationContext(WebConfig.class);
372367
this.request.setServerName("example.org");
373368
this.request.setServerPort(9999);
374369
this.request.setContextPath("/base");
@@ -380,18 +375,35 @@ public void fromMappingNamePlain() {
380375

381376
@Test
382377
public void fromMappingNameWithCustomBaseUrl() {
383-
AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
384-
context.setServletContext(new MockServletContext());
385-
context.register(WebConfig.class);
386-
context.refresh();
387-
388-
this.request.setAttribute(DispatcherServlet.WEB_APPLICATION_CONTEXT_ATTRIBUTE, context);
378+
initWebApplicationContext(WebConfig.class);
389379

390380
UriComponentsBuilder baseUrl = UriComponentsBuilder.fromUriString("http://example.org:9999/base");
391381
MvcUriComponentsBuilder mvcBuilder = relativeTo(baseUrl);
392382
String url = mvcBuilder.withMappingName("PAC#getAddressesForCountry").arg(0, "DE").buildAndExpand(123);
393383
assertEquals("http://example.org:9999/base/people/123/addresses/DE", url);
394384
}
385+
386+
@Test // SPR-17027
387+
public void fromMappingNameWithEncoding() {
388+
initWebApplicationContext(WebConfig.class);
389+
390+
this.request.setServerName("example.org");
391+
this.request.setServerPort(9999);
392+
this.request.setContextPath("/base");
393+
394+
String mappingName = "PAC#getAddressesForCountry";
395+
String url = fromMappingName(mappingName).arg(0, "DE;FR").encode().buildAndExpand("_+_");
396+
assertEquals("/base/people/_%2B_/addresses/DE%3BFR", url);
397+
}
398+
399+
private void initWebApplicationContext(Class<?> configClass) {
400+
AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
401+
context.setServletContext(new MockServletContext());
402+
context.register(configClass);
403+
context.refresh();
404+
405+
this.request.setAttribute(DispatcherServlet.WEB_APPLICATION_CONTEXT_ATTRIBUTE, context);
406+
}
395407

396408

397409
static class Person {

0 commit comments

Comments
 (0)