Skip to content

Commit

Permalink
Polish UriBuilderFactory and implementation
Browse files Browse the repository at this point in the history
Issue: SPR-16422
  • Loading branch information
rstoyanchev committed Feb 15, 2018
1 parent 3d20db1 commit 4db0d99
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 51 deletions.
Expand Up @@ -298,18 +298,16 @@ else if (this.uriTemplateHandler instanceof org.springframework.web.util.Abstrac
}

/**
* Configure the {@link UriTemplateHandler} to use to expand URI templates.
* By default the {@link DefaultUriBuilderFactory} is used which relies on
* Spring's URI template support and exposes several useful properties that
* customize its behavior for encoding and for pre-pending a common base URL.
* An alternative implementation may be used to plug an external URI
* template library.
* <p><strong>Note:</strong> if switching from
* Customize how URI templates are expanded into URI instances.
* <p>By default {@link DefaultUriBuilderFactory} with default settings is
* used. You can supply a {@code DefaultUriBuilderFactory} configured
* differently, or an entirely different implementation, for example that
* plugs in a 3rd party URI template library.
* <p><strong>Note:</strong> in 5.0 the switch from
* {@link org.springframework.web.util.DefaultUriTemplateHandler
* DefaultUriTemplateHandler} (deprecated in 4.3) to
* {@link DefaultUriBuilderFactory} keep in mind that the
* {@link DefaultUriBuilderFactory} has a different default for the
* {@code parsePath} property (from false to true).
* DefaultUriTemplateHandler} (deprecated in 4.3), as the default to use, to
* {@link DefaultUriBuilderFactory} brings in a different default for the
* {@code parsePath} property (switching from false to true).
* @param handler the URI template handler to use
*/
public void setUriTemplateHandler(UriTemplateHandler handler) {
Expand Down
Expand Up @@ -17,6 +17,7 @@
package org.springframework.web.util;

import java.net.URI;
import java.nio.charset.Charset;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
Expand All @@ -28,19 +29,56 @@
import org.springframework.util.ObjectUtils;

/**
* Default implementation of {@link UriBuilderFactory} providing options to
* pre-configure all {@link UriBuilder} instances with common properties
* such as a base URI, encoding mode, and default URI variables.
* {@code UriBuilderFactory} that relies on {@link UriComponentsBuilder} for
* the actual building of the URI.
*
* <p>Provides options to create {@link UriBuilder} instances with a common
* base URI, alternative encoding mode strategies, among others.
*
* <p>Uses {@link UriComponentsBuilder} for URI building.
*
* @author Rossen Stoyanchev
* @since 5.0
* @see UriComponentsBuilder
*/
public class DefaultUriBuilderFactory implements UriBuilderFactory {

public enum EncodingMode {URI_COMPONENT, VALUES_ONLY, NONE}

/**
* Constants that represent different URI encoding strategies.
* @see #setEncodingMode
*/
public enum EncodingMode {

/**
* The default way of encoding that {@link UriComponents} supports:
* <ol>
* <li>Expand URI variables.
* <li>Encode individual URI components as described in
* {@link UriComponents#encode(Charset)}.
* </ol>
* <p>This mode <strong>does not</strong> encode all characters with
* reserved meaning but only the ones that are illegal within a given
* URI component as defined in RFC 396. This matches the way the
* multi-argument {@link URI} constructor does encoding.
*/
URI_COMPONENT,

/**
* Comprehensive encoding of URI variable values prior to expanding:
* <ol>
* <li>Apply {@link UriUtils#encode(String, Charset)} to each URI variable value.
* <li>Expand URI variable values.
* </ol>
* <p>This mode encodes all characters with reserved meaning, therefore
* ensuring that expanded URI variable do not have any impact on the
* structure or meaning of the URI.
*/
VALUES_ONLY,

/**
* No encoding should be applied.
*/
NONE }


private final UriComponentsBuilder baseUri;
Expand Down Expand Up @@ -103,20 +141,9 @@ public void setDefaultUriVariables(@Nullable Map<String, ?> defaultUriVariables)
}

/**
* Specify the encoding mode to use when building URIs:
* <ul>
* <li>URI_COMPONENT -- expand the URI variables first and then encode all URI
* component (e.g. host, path, query, etc) according to the encoding rules
* for each individual component.
* <li>VALUES_ONLY -- encode URI variable values only, prior to expanding
* them, using a "strict" encoding mode, i.e. encoding all characters
* outside the unreserved set as defined in
* <a href="https://tools.ietf.org/html/rfc3986#section-2">RFC 3986 Section 2</a>.
* This ensures a URI variable value will not contain any characters with a
* reserved purpose.
* <li>NONE -- in this mode no encoding is performed.
* </ul>
* <p>By default this is set to {@code "URI_COMPONENT"}.
* Specify the {@link EncodingMode EncodingMode} to use when building URIs.
* <p>By default set to
* {@link EncodingMode#URI_COMPONENT EncodingMode.URI_COMPONENT}.
* @param encodingMode the encoding mode to use
*/
public void setEncodingMode(EncodingMode encodingMode) {
Expand Down
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2017 the original author or authors.
* Copyright 2002-2018 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.
Expand All @@ -16,24 +16,24 @@
package org.springframework.web.util;

/**
* Factory to create {@link UriBuilder} instances pre-configured in a specific
* way such as sharing a common base URI across all builders.
* Factory to create {@link UriBuilder} instances with shared configuration
* such as a base URI, an encoding mode strategy, and others across all URI
* builder instances created through a factory.
*
* @author Rossen Stoyanchev
* @since 5.0
*/
public interface UriBuilderFactory extends UriTemplateHandler {

/**
* Create a builder from the given URI template string.
* Implementations may further combine the URI template with a base URI.
* Initialize a builder with the given URI template.
* @param uriTemplate the URI template to use
* @return the builder instance
* @return the URI builder instance
*/
UriBuilder uriString(String uriTemplate);

/**
* Create a builder with default settings.
* Create a URI builder with default settings.
* @return the builder instance
*/
UriBuilder builder();
Expand Down
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2017 the original author or authors.
* Copyright 2002-2018 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.
Expand All @@ -20,30 +20,27 @@
import java.util.Map;

/**
* Strategy for expanding a URI template.
*
* <p>Supported as a property on the {@code RestTemplate} as well as the
* {@code AsyncRestTemplate}.
* Defines methods for expanding a URI template with variables.
*
* @author Rossen Stoyanchev
* @since 4.2
* @see DefaultUriBuilderFactory
* @see org.springframework.web.client.RestTemplate#setUriTemplateHandler(UriTemplateHandler)
*/
public interface UriTemplateHandler {

/**
* Expand the given URI template from a map of URI variables.
* @param uriTemplate the URI template string
* @param uriVariables the URI variables
* @return the resulting URI
* Expand the given URI template with a map of URI variables.
* @param uriTemplate the URI template
* @param uriVariables variable values
* @return the created URI instance
*/
URI expand(String uriTemplate, Map<String, ?> uriVariables);

/**
* Expand the given URI template from an array of URI variables.
* @param uriTemplate the URI template string
* @param uriVariables the URI variable values
* @return the resulting URI
* Expand the given URI template with an array of URI variables.
* @param uriTemplate the URI template
* @param uriVariables variable values
* @return the created URI instance
*/
URI expand(String uriTemplate, Object... uriVariables);

Expand Down

0 comments on commit 4db0d99

Please sign in to comment.