diff --git a/spring-web/src/main/java/org/springframework/http/RequestEntity.java b/spring-web/src/main/java/org/springframework/http/RequestEntity.java index 6ba2f48e9de..19133210db7 100644 --- a/spring-web/src/main/java/org/springframework/http/RequestEntity.java +++ b/spring-web/src/main/java/org/springframework/http/RequestEntity.java @@ -44,9 +44,13 @@ import org.springframework.util.ObjectUtils; * * *

If you would like to provide a URI template with variables, consider using - * {@link org.springframework.web.util.UriTemplate}: + * {@link org.springframework.web.util.DefaultUriBuilderFactory DefaultUriBuilderFactory}: *

- * URI uri = new UriTemplate("https://example.com/{foo}").expand("bar");
+ * // Create shared factory
+ * UriBuilderFactory factory = new DefaultUriBuilderFactory();
+ *
+ * // Use factory to create URL from template
+ * URI uri = factory.uriString("https://example.com/{foo}").build("bar");
  * RequestEntity<MyRequest> request = RequestEntity.post(uri).accept(MediaType.APPLICATION_JSON).body(body);
  * 
* diff --git a/spring-web/src/main/java/org/springframework/web/util/UriTemplate.java b/spring-web/src/main/java/org/springframework/web/util/UriTemplate.java index d9ccf3b995a..6290db6ef8d 100644 --- a/spring-web/src/main/java/org/springframework/web/util/UriTemplate.java +++ b/spring-web/src/main/java/org/springframework/web/util/UriTemplate.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -30,14 +30,19 @@ import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** - * Represents a URI template. A URI template is a URI-like String that contains variables - * enclosed by braces ({@code {}}) which can be expanded to produce an actual URI. + * Representation of a URI template that can be expanded with URI variables via + * {@link #expand(Map)}, {@link #expand(Object[])}, or matched to a URL via + * {@link #match(String)}. This class is designed to be thread-safe and + * reusable, and allows any number of expand or match calls. * - *

See {@link #expand(Map)}, {@link #expand(Object[])}, and {@link #match(String)} - * for example usages. - * - *

This class is designed to be thread-safe and reusable, allowing for any number - * of expand or match calls. + *

Note: this class uses {@link UriComponentsBuilder} + * internally to expand URI templates, and is merely a shortcut for already + * prepared URI templates. For more dynamic preparation and extra flexibility, + * e.g. around URI encoding, consider using {@code UriComponentsBuilder} or the + * higher level {@link DefaultUriBuilderFactory} which adds several encoding + * modes on top of {@code UriComponentsBuilder}. See the + * reference docs + * for further details. * * @author Arjen Poutsma * @author Juergen Hoeller diff --git a/spring-web/src/test/java/org/springframework/http/RequestEntityTests.java b/spring-web/src/test/java/org/springframework/http/RequestEntityTests.java index 91bd3669196..bd916273314 100644 --- a/spring-web/src/test/java/org/springframework/http/RequestEntityTests.java +++ b/spring-web/src/test/java/org/springframework/http/RequestEntityTests.java @@ -27,7 +27,7 @@ import java.util.Map; import org.junit.jupiter.api.Test; import org.springframework.core.ParameterizedTypeReference; -import org.springframework.web.util.UriTemplate; +import org.springframework.web.util.UriComponentsBuilder; import static org.assertj.core.api.Assertions.assertThat; @@ -58,7 +58,7 @@ public class RequestEntityTests { @Test public void uriVariablesExpansion() throws URISyntaxException { - URI uri = new UriTemplate("https://example.com/{foo}").expand("bar"); + URI uri = UriComponentsBuilder.fromUriString("https://example.com/{foo}").buildAndExpand("bar").toUri(); RequestEntity.get(uri).accept(MediaType.TEXT_PLAIN).build(); String url = "https://www.{host}.com/{path}"; @@ -66,7 +66,7 @@ public class RequestEntityTests { String path = "foo/bar"; URI expected = new URI("https://www.example.com/foo/bar"); - uri = new UriTemplate(url).expand(host, path); + uri = UriComponentsBuilder.fromUriString(url).buildAndExpand(host, path).toUri(); RequestEntity entity = RequestEntity.get(uri).build(); assertThat(entity.getUrl()).isEqualTo(expected); @@ -74,7 +74,7 @@ public class RequestEntityTests { uriVariables.put("host", host); uriVariables.put("path", path); - uri = new UriTemplate(url).expand(uriVariables); + uri = UriComponentsBuilder.fromUriString(url).buildAndExpand(uriVariables).toUri(); entity = RequestEntity.get(uri).build(); assertThat(entity.getUrl()).isEqualTo(expected); } diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/result/view/RequestContext.java b/spring-webflux/src/main/java/org/springframework/web/reactive/result/view/RequestContext.java index 0364aa079ef..f0510906f3e 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/result/view/RequestContext.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/result/view/RequestContext.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -37,7 +37,7 @@ import org.springframework.validation.Errors; import org.springframework.web.bind.EscapedErrors; import org.springframework.web.server.ServerWebExchange; import org.springframework.web.util.HtmlUtils; -import org.springframework.web.util.UriTemplate; +import org.springframework.web.util.UriComponentsBuilder; /** * Context holder for request-specific state, like the {@link MessageSource} to @@ -218,8 +218,7 @@ public class RequestContext { */ public String getContextUrl(String relativeUrl, Map params) { String url = StringUtils.applyRelativePath(getContextPath() + "/", relativeUrl); - UriTemplate template = new UriTemplate(url); - url = template.expand(params).toASCIIString(); + url = UriComponentsBuilder.fromUriString(url).buildAndExpand(params).encode().toUri().toASCIIString(); return getExchange().transformUrl(url); } diff --git a/spring-webflux/src/test/java/org/springframework/web/reactive/result/view/DummyMacroRequestContext.java b/spring-webflux/src/test/java/org/springframework/web/reactive/result/view/DummyMacroRequestContext.java index a7f624bd780..d7e91cdbcc5 100644 --- a/spring-webflux/src/test/java/org/springframework/web/reactive/result/view/DummyMacroRequestContext.java +++ b/spring-webflux/src/test/java/org/springframework/web/reactive/result/view/DummyMacroRequestContext.java @@ -22,7 +22,8 @@ import java.util.Map; import org.springframework.context.support.GenericApplicationContext; import org.springframework.ui.ModelMap; import org.springframework.web.server.ServerWebExchange; -import org.springframework.web.util.UriTemplate; +import org.springframework.web.util.UriComponents; +import org.springframework.web.util.UriComponentsBuilder; /** * Dummy request context used for FreeMarker macro tests. @@ -107,8 +108,8 @@ public class DummyMacroRequestContext { * @see org.springframework.web.reactive.result.view.RequestContext#getContextUrl(String, Map) */ public String getContextUrl(String relativeUrl, Map params) { - UriTemplate template = new UriTemplate(relativeUrl); - return getContextPath() + template.expand(params).toASCIIString(); + UriComponents uric = UriComponentsBuilder.fromUriString(relativeUrl).buildAndExpand(params); + return getContextPath() + uric.toUri().toASCIIString(); } /** diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/support/RequestContext.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/support/RequestContext.java index f2de59f37be..187a4d0972b 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/support/RequestContext.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/support/RequestContext.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -50,7 +50,7 @@ import org.springframework.web.servlet.LocaleContextResolver; import org.springframework.web.servlet.LocaleResolver; import org.springframework.web.servlet.ThemeResolver; import org.springframework.web.util.HtmlUtils; -import org.springframework.web.util.UriTemplate; +import org.springframework.web.util.UriComponentsBuilder; import org.springframework.web.util.UrlPathHelper; import org.springframework.web.util.WebUtils; @@ -563,8 +563,7 @@ public class RequestContext { */ public String getContextUrl(String relativeUrl, Map params) { String url = getContextPath() + relativeUrl; - UriTemplate template = new UriTemplate(url); - url = template.expand(params).toASCIIString(); + url = UriComponentsBuilder.fromUriString(url).buildAndExpand(params).encode().toUri().toASCIIString(); if (this.response != null) { url = this.response.encodeURL(url); } diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/view/DummyMacroRequestContext.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/view/DummyMacroRequestContext.java index 822292b4d7a..cd2bc87d09f 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/view/DummyMacroRequestContext.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/view/DummyMacroRequestContext.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,7 +23,8 @@ import javax.servlet.http.HttpServletRequest; import org.springframework.web.servlet.support.BindStatus; import org.springframework.web.servlet.support.RequestContext; -import org.springframework.web.util.UriTemplate; +import org.springframework.web.util.UriComponents; +import org.springframework.web.util.UriComponentsBuilder; /** * Dummy request context used for FreeMarker macro tests. @@ -140,8 +141,8 @@ public class DummyMacroRequestContext { * @see org.springframework.web.servlet.support.RequestContext#getContextUrl(String, Map) */ public String getContextUrl(String relativeUrl, Map params) { - UriTemplate template = new UriTemplate(relativeUrl); - return getContextPath() + template.expand(params).toASCIIString(); + UriComponents uric = UriComponentsBuilder.fromUriString(relativeUrl).buildAndExpand(params); + return getContextPath() + uric.toUri().toASCIIString(); } /**