From 1ba0625cd9d9043b3b80a0de872cfbaf3e324467 Mon Sep 17 00:00:00 2001 From: Rossen Stoyanchev Date: Wed, 20 May 2015 15:11:49 -0400 Subject: [PATCH] Add baseUrl to DefaultUriTemplateHandler Issue: SPR-13035 --- .../web/util/DefaultUriTemplateHandler.java | 61 +++++++++++++++++-- .../util/DefaultUriTemplateHandlerTests.java | 24 +++++++- 2 files changed, 77 insertions(+), 8 deletions(-) diff --git a/spring-web/src/main/java/org/springframework/web/util/DefaultUriTemplateHandler.java b/spring-web/src/main/java/org/springframework/web/util/DefaultUriTemplateHandler.java index 9b7b838247..ef949d2d65 100644 --- a/spring-web/src/main/java/org/springframework/web/util/DefaultUriTemplateHandler.java +++ b/spring-web/src/main/java/org/springframework/web/util/DefaultUriTemplateHandler.java @@ -16,9 +16,12 @@ package org.springframework.web.util; import java.net.URI; +import java.net.URISyntaxException; import java.util.List; import java.util.Map; +import org.springframework.util.Assert; + /** * Default implementation of {@link UriTemplateHandler} that relies on * {@link UriComponentsBuilder} internally. @@ -28,9 +31,42 @@ import java.util.Map; */ public class DefaultUriTemplateHandler implements UriTemplateHandler { + private String baseUrl; + private boolean parsePath; + /** + * Configure a base URL to prepend URI templates with. The base URL should + * have a scheme and host but may also contain a port and a partial path. + * Individual URI templates then may provide the remaining part of the URL + * including additional path, query and fragment. + * + *

Note: Individual URI templates are expanded and + * encoded before being appended to the base URL. Therefore the base URL is + * expected to be fully expanded and encoded, which can be done with the help + * of {@link UriComponentsBuilder}. + * + * @param baseUrl the base URL. + */ + public void setBaseUrl(String baseUrl) { + if (baseUrl != null) { + UriComponents uriComponents = UriComponentsBuilder.fromUriString(baseUrl).build(); + Assert.hasText(uriComponents.getScheme(), "'baseUrl' must have a scheme"); + Assert.hasText(uriComponents.getHost(), "'baseUrl' must have a host"); + Assert.isNull(uriComponents.getQuery(), "'baseUrl' cannot have a query"); + Assert.isNull(uriComponents.getFragment(), "'baseUrl' cannot have a fragment"); + } + this.baseUrl = baseUrl; + } + + /** + * Return the configured base URL. + */ + public String getBaseUrl() { + return this.baseUrl; + } + /** * Whether to parse the path of a URI template string into path segments. *

If set to {@code true} the path of parsed URI templates is decomposed @@ -55,17 +91,19 @@ public class DefaultUriTemplateHandler implements UriTemplateHandler { @Override public URI expand(String uriTemplate, Map uriVariables) { - UriComponentsBuilder builder = initBuilder(uriTemplate); - return builder.build().expand(uriVariables).encode().toUri(); + UriComponentsBuilder uriComponentsBuilder = initUriComponentsBuilder(uriTemplate); + UriComponents uriComponents = uriComponentsBuilder.build().expand(uriVariables).encode(); + return insertBaseUrl(uriComponents); } @Override public URI expand(String uriTemplate, Object... uriVariableValues) { - UriComponentsBuilder builder = initBuilder(uriTemplate); - return builder.build().expand(uriVariableValues).encode().toUri(); + UriComponentsBuilder uriComponentsBuilder = initUriComponentsBuilder(uriTemplate); + UriComponents uriComponents = uriComponentsBuilder.build().expand(uriVariableValues).encode(); + return insertBaseUrl(uriComponents); } - protected UriComponentsBuilder initBuilder(String uriTemplate) { + protected UriComponentsBuilder initUriComponentsBuilder(String uriTemplate) { UriComponentsBuilder builder = UriComponentsBuilder.fromUriString(uriTemplate); if (shouldParsePath()) { List pathSegments = builder.build().getPathSegments(); @@ -77,4 +115,17 @@ public class DefaultUriTemplateHandler implements UriTemplateHandler { return builder; } + protected URI insertBaseUrl(UriComponents uriComponents) { + if (getBaseUrl() == null || uriComponents.getHost() != null) { + return uriComponents.toUri(); + } + String url = getBaseUrl() + uriComponents.toUriString(); + try { + return new URI(url); + } + catch (URISyntaxException ex) { + throw new IllegalArgumentException("Invalid URL after inserting base URL: " + url, ex); + } + } + } diff --git a/spring-web/src/test/java/org/springframework/web/util/DefaultUriTemplateHandlerTests.java b/spring-web/src/test/java/org/springframework/web/util/DefaultUriTemplateHandlerTests.java index 18eae557fc..1642351edc 100644 --- a/spring-web/src/test/java/org/springframework/web/util/DefaultUriTemplateHandlerTests.java +++ b/spring-web/src/test/java/org/springframework/web/util/DefaultUriTemplateHandlerTests.java @@ -39,6 +39,24 @@ public class DefaultUriTemplateHandlerTests { } + @Test + public void baseUrl() throws Exception { + this.handler.setBaseUrl("http://localhost:8080"); + URI actual = this.handler.expand("/myapiresource"); + + URI expected = new URI("http://localhost:8080/myapiresource"); + assertEquals(expected, actual); + } + + @Test + public void baseUrlWithPartialPath() throws Exception { + this.handler.setBaseUrl("http://localhost:8080/context"); + URI actual = this.handler.expand("/myapiresource"); + + URI expected = new URI("http://localhost:8080/context/myapiresource"); + assertEquals(expected, actual); + } + @Test public void expandWithFullPath() throws Exception { Map vars = new HashMap(2); @@ -49,11 +67,11 @@ public class DefaultUriTemplateHandlerTests { URI actual = this.handler.expand(template, vars); URI expected = new URI("http://example.com/hotels/1/pic/pics/logo.png"); - assertEquals("Invalid expanded template", expected, actual); + assertEquals(expected, actual); } @Test - public void expandWithFullPathParsedIntoPathSegments() throws Exception { + public void expandWithFullPathAndParsePathEnabled() throws Exception { Map vars = new HashMap(2); vars.put("hotel", "1"); vars.put("publicpath", "pics/logo.png"); @@ -64,7 +82,7 @@ public class DefaultUriTemplateHandlerTests { URI actual = this.handler.expand(template, vars); URI expected = new URI("http://example.com/hotels/1/pic/pics%2Flogo.png/size/150x150"); - assertEquals("Invalid expanded template", expected, actual); + assertEquals(expected, actual); } } -- GitLab