From 6c4289e2385f0ae8e5478aafbba34ccbea686bef Mon Sep 17 00:00:00 2001 From: Rossen Stoyanchev Date: Tue, 17 Jul 2018 16:40:52 -0400 Subject: [PATCH] Polish --- .../web/util/DefaultUriBuilderFactory.java | 52 ++++++++++--------- .../web/util/UriComponents.java | 7 +-- .../web/util/UriComponentsBuilder.java | 24 +++++---- src/docs/asciidoc/web/web-uris.adoc | 30 ++++++----- 4 files changed, 63 insertions(+), 50 deletions(-) diff --git a/spring-web/src/main/java/org/springframework/web/util/DefaultUriBuilderFactory.java b/spring-web/src/main/java/org/springframework/web/util/DefaultUriBuilderFactory.java index d0cb1be195..8a3205ca47 100644 --- a/spring-web/src/main/java/org/springframework/web/util/DefaultUriBuilderFactory.java +++ b/spring-web/src/main/java/org/springframework/web/util/DefaultUriBuilderFactory.java @@ -40,43 +40,44 @@ import org.springframework.util.StringUtils; */ public class DefaultUriBuilderFactory implements UriBuilderFactory { - /** - * Constants that represent different URI encoding strategies. + * Enum to represent multiple URI encoding strategies. * @see #setEncodingMode */ public enum EncodingMode { /** - * Encode the URI template first, and URI variables later when expanded, - * applying the following to each: + * Pre-encode the URI template first, then strictly encode URI variables + * when expanded, with the following rules: * - *

For most cases this should be the preferred encoding mode. + *

For most cases, this mode is most likely to give the expected + * result because in treats URI variables as opaque data to be fully + * encoded, while {@link #URI_COMPONENT} by comparison is useful only + * if intentionally expanding URI variables with reserved characters. * @since 5.0.8 * @see UriComponentsBuilder#encode() */ TEMPLATE_AND_VALUES, /** - * Encode only URI variables strictly quoting both illegal characters - * and characters with reserved meaning. + * Does not encode the URI template and instead applies strict encoding + * to URI variables via {@link UriUtils#encodeUriVariables} prior to + * expanding them into the template. * @see UriUtils#encodeUriVariables(Object...) * @see UriUtils#encodeUriVariables(Map) */ VALUES_ONLY, /** - * Expand URI variables first, and then encode the expanded URI component - * values, quoting only illegal characters within a given URI - * component type, but not all characters with reserved meaning. - *

This is the mode historically used in the {@code RestTemplate} but - * as of 5.0.8 {@link #TEMPLATE_AND_VALUES} is the recommended encoding - * mode to use instead. + * Expand URI variables first, and then encode the resulting URI + * component values, replacing only non-ASCII and illegal + * (within a given URI component type) characters, but not characters + * with reserved meaning. * @see UriComponents#encode() */ URI_COMPONENT, @@ -129,13 +130,16 @@ public class DefaultUriBuilderFactory implements UriBuilderFactory { /** - * Specify the {@link EncodingMode EncodingMode} to use to encode URIs. - * - *

Note: in 5.1 the default value was changed from - * {@link EncodingMode#URI_COMPONENT URI_COMPONENT} to the now recommended - * {@link EncodingMode#TEMPLATE_AND_VALUES TEMPLATE_AND_VALUES} mode of - * encoding. - * + * Set the encoding mode to use. + *

By default this is set to {@link EncodingMode#TEMPLATE_AND_VALUES + * EncodingMode.TEMPLATE_AND_VALUES}. + *

Note: In 5.1 the default was changed from + * {@link EncodingMode#URI_COMPONENT EncodingMode.URI_COMPONENT}. + * Consequently the {@code WebClient}, which relies on the built-in default + * has also been switched to the new default. The {@code RestTemplate} + * however sets this explicitly to {@link EncodingMode#URI_COMPONENT + * EncodingMode.URI_COMPONENT} explicitly for historic and backwards + * compatibility reasons. * @param encodingMode the encoding mode to use */ public void setEncodingMode(EncodingMode encodingMode) { diff --git a/spring-web/src/main/java/org/springframework/web/util/UriComponents.java b/spring-web/src/main/java/org/springframework/web/util/UriComponents.java index e0f3add3ba..bc3281b959 100644 --- a/spring-web/src/main/java/org/springframework/web/util/UriComponents.java +++ b/spring-web/src/main/java/org/springframework/web/util/UriComponents.java @@ -132,9 +132,10 @@ public abstract class UriComponents implements Serializable { * Invoke this after expanding URI variables to encode the * resulting URI component values. *

In comparison to {@link UriComponentsBuilder#encode()}, this method - * quotes only illegal characters within a given URI component type, - * but not all characters with reserved meaning. For most cases, prefer - * using {@link UriComponentsBuilder#encode()} over this method. + * only replaces non-ASCII and illegal (within a given URI + * component type) characters, but not characters with reserved meaning. + * For most cases, {@link UriComponentsBuilder#encode()} is more likely + * to give the expected result. * @see UriComponentsBuilder#encode() */ public final UriComponents encode() { diff --git a/spring-web/src/main/java/org/springframework/web/util/UriComponentsBuilder.java b/spring-web/src/main/java/org/springframework/web/util/UriComponentsBuilder.java index 38941d2a5c..943208bee6 100644 --- a/spring-web/src/main/java/org/springframework/web/util/UriComponentsBuilder.java +++ b/spring-web/src/main/java/org/springframework/web/util/UriComponentsBuilder.java @@ -328,19 +328,21 @@ public class UriComponentsBuilder implements UriBuilder, Cloneable { // Encode methods /** - * Request to have the URI template encoded first at build time, and - * URI variables encoded later when expanded. + * Request to have the URI template pre-encoded at build time, and + * URI variables encoded separately when expanded. *

In comparison to {@link UriComponents#encode()}, this method has the * same effect on the URI template, i.e. each URI component is encoded by - * quoting only illegal characters within that URI component type. - * However URI variables are encoded more strictly, by quoting both illegal - * characters and characters with reserved meaning. - *

For most cases, prefer this method over {@link UriComponents#encode()} - * which is useful only if intentionally expanding variables with reserved - * characters. For example ';' is legal in a path, but also has reserved - * meaning as a separator. When expanding a variable that contains ';' it - * probably should be encoded, unless the intent is to insert path params - * through the expanded variable. + * replacing non-ASCII and illegal (within the URI component type) characters + * with escaped octets. However URI variables are encoded more strictly, by + * also escaping characters with reserved meaning. + *

For most cases, this method is more likely to give the expected result + * because in treats URI variables as opaque data to be fully encoded, while + * {@link UriComponents#encode()} is useful only if intentionally expanding + * URI variables that contain reserved characters. + *

For example ';' is legal in a path but has reserved meaning. This + * method replaces ";" with "%3B" in URI variables but not in the URI + * template. By contrast, {@link UriComponents#encode()} never replaces ";" + * since it is a legal character in a path. * @since 5.0.8 */ public final UriComponentsBuilder encode() { diff --git a/src/docs/asciidoc/web/web-uris.adoc b/src/docs/asciidoc/web/web-uris.adoc index 65f12c05dd..d6d6702cc4 100644 --- a/src/docs/asciidoc/web/web-uris.adoc +++ b/src/docs/asciidoc/web/web-uris.adoc @@ -116,9 +116,9 @@ Consider ";" which is legal in a path but has reserved meaning. Option 1 replace replaces ";" since it is a legal character in a path. ==== -For most cases option 1 is likely to give the expected result because in treats URI +For most cases option 1 is likely to give the expected result because it treats URI variables as opaque data to be fully encoded, while option 2 is useful only if -intentionally expanding URI variables that contain reserved characters. +URI variables intentionally contain reserved characters. Example usage using option 1: @@ -135,7 +135,7 @@ Example usage using option 1: ---- The `WebClient` and the `RestTemplate` expand and encode URI templates internally through -the `UriBuilderFactory` strategy. Both can be configured wiht a custom instance: +the `UriBuilderFactory` strategy. Both can be configured with a custom strategy: [source,java,indent=0] [subs="verbatim,quotes"] @@ -144,23 +144,29 @@ the `UriBuilderFactory` strategy. Both can be configured wiht a custom instance: DefaultUriBuilderFactory factory = new DefaultUriBuilderFactory(baseUrl) factory.setEncodingMode(EncodingMode.TEMPLATE_AND_VALUES); + // Customize the RestTemplate.. RestTemplate restTemplate = new RestTemplate(); restTemplate.setUriTemplateHandler(factory); + // Customize the WebClient.. WebClient client = WebClient.builder().uriBuilderFactory(factory).build(); ---- -The `DefaultUriBuilderFactory` implementation shown above uses `UriComponentsBuilder` -internally. The approach to encoding is controlled through one of the encoding modes -listed below: +The `DefaultUriBuilderFactory` implementation uses `UriComponentsBuilder` internally to +expand and encode URI templates. As a factory it provides a single place to configure +the approach to encoding based on one of the below encoding modes: -* `TEMPLATE_AND_VALUES` -- uses `UriComponentsBuilder#encode()`, corresponding to option -1 above, to pre-encode the URI template and strictly encode URI variables when expanded. -* `VALUES_ONLY` -- variant of `TEMPLATE_AND_VALUES` that does not encode the URI template. +* `TEMPLATE_AND_VALUES` -- uses `UriComponentsBuilder#encode()`, corresponding to +option 1 above, to pre-encode the URI template and strictly encode URI variables when +expanded. +* `VALUES_ONLY` -- does not encode the URI template and instead applies strict encoding +to URI variables via `UriUtils#encodeUriUriVariables` prior to expanding them into the +template. * `URI_COMPONENTS` -- uses `UriComponents#encode()`, corresponding to option 2 above, to encode URI component value _after_ URI variables are expanded. * `NONE` -- no encoding is applied. -Out of the box the `RestTemplate` uses `EncodingMode.URI_COMPONENTS` for historic reasons -and for backwards compatibility. The `WebClient` uses `EncodingMode.TEMPLATE_AND_VALUES` -starting in 5.1, and `EncodingMode.URI_COMPONENTS` in 5.0.x. \ No newline at end of file +Out of the box the `RestTemplate` is set to `EncodingMode.URI_COMPONENTS` for historic +reasons and for backwards compatibility. The `WebClient` relies on the default value +in `DefaultUriBuilderFactory` which was changed from `EncodingMode.URI_COMPONENTS` in +5.0.x to `EncodingMode.TEMPLATE_AND_VALUES` in 5.1. \ No newline at end of file