提交 1ba0625c 编写于 作者: R Rossen Stoyanchev

Add baseUrl to DefaultUriTemplateHandler

Issue: SPR-13035
上级 01d1e71d
......@@ -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.
*
* <p><strong>Note: </strong>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.
* <p>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<String, ?> 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<String> 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);
}
}
}
......@@ -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<String, String> vars = new HashMap<String, String>(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<String, String> vars = new HashMap<String, String>(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);
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册