Add UriTemplateHandler
This change introduces a strategy for expanding a URI template into a URI and makes it a property of the RestTemplate and AsyncRestTemplate so that they can be pre-configured with such a strategy. The DefaultUriTemplateHandler relies on UriComponentsBuilder internally and provides functionality equivalent to using the UriTemplate. A DefaultUriTemplateHandler can also be configured to parse the path of a URI template into path segments in order to allow expanding URI variables according to path segment encoding rules. Issue: SPR-12750
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
* Copyright 2002-2015 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.
|
||||
@@ -49,7 +49,8 @@ import org.springframework.util.concurrent.ListenableFuture;
|
||||
import org.springframework.util.concurrent.ListenableFutureAdapter;
|
||||
import org.springframework.util.concurrent.ListenableFutureCallback;
|
||||
import org.springframework.util.concurrent.SuccessCallback;
|
||||
import org.springframework.web.util.UriTemplate;
|
||||
import org.springframework.web.util.DefaultUriTemplateHandler;
|
||||
import org.springframework.web.util.UriTemplateHandler;
|
||||
|
||||
/**
|
||||
* <strong>Spring's central class for asynchronous client-side HTTP access.</strong>
|
||||
@@ -146,6 +147,22 @@ public class AsyncRestTemplate extends AsyncHttpAccessor implements AsyncRestOpe
|
||||
return this.syncTemplate.getErrorHandler();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a custom {@link UriTemplateHandler} for expanding URI templates.
|
||||
* <p>By default, RestTemplate uses {@link DefaultUriTemplateHandler}.
|
||||
* @param handler the URI template handler to use
|
||||
*/
|
||||
public void setUriTemplateHandler(UriTemplateHandler handler) {
|
||||
this.syncTemplate.setUriTemplateHandler(handler);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the configured URI template handler.
|
||||
*/
|
||||
public UriTemplateHandler getUriTemplateHandler() {
|
||||
return this.syncTemplate.getUriTemplateHandler();
|
||||
}
|
||||
|
||||
@Override
|
||||
public RestOperations getRestOperations() {
|
||||
return this.syncTemplate;
|
||||
@@ -493,7 +510,7 @@ public class AsyncRestTemplate extends AsyncHttpAccessor implements AsyncRestOpe
|
||||
public <T> ListenableFuture<T> execute(String url, HttpMethod method, AsyncRequestCallback requestCallback,
|
||||
ResponseExtractor<T> responseExtractor, Object... urlVariables) throws RestClientException {
|
||||
|
||||
URI expanded = new UriTemplate(url).expand(urlVariables);
|
||||
URI expanded = getUriTemplateHandler().expand(url, urlVariables);
|
||||
return doExecute(expanded, method, requestCallback, responseExtractor);
|
||||
}
|
||||
|
||||
@@ -501,7 +518,7 @@ public class AsyncRestTemplate extends AsyncHttpAccessor implements AsyncRestOpe
|
||||
public <T> ListenableFuture<T> execute(String url, HttpMethod method, AsyncRequestCallback requestCallback,
|
||||
ResponseExtractor<T> responseExtractor, Map<String, ?> urlVariables) throws RestClientException {
|
||||
|
||||
URI expanded = new UriTemplate(url).expand(urlVariables);
|
||||
URI expanded = getUriTemplateHandler().expand(url, urlVariables);
|
||||
return doExecute(expanded, method, requestCallback, responseExtractor);
|
||||
}
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.xml.transform.Source;
|
||||
|
||||
import org.springframework.core.ParameterizedTypeReference;
|
||||
@@ -51,7 +52,8 @@ import org.springframework.http.converter.xml.MappingJackson2XmlHttpMessageConve
|
||||
import org.springframework.http.converter.xml.SourceHttpMessageConverter;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.web.util.UriTemplate;
|
||||
import org.springframework.web.util.DefaultUriTemplateHandler;
|
||||
import org.springframework.web.util.UriTemplateHandler;
|
||||
|
||||
/**
|
||||
* <strong>Spring's central class for synchronous client-side HTTP access.</strong>
|
||||
@@ -135,6 +137,8 @@ public class RestTemplate extends InterceptingHttpAccessor implements RestOperat
|
||||
|
||||
private ResponseErrorHandler errorHandler = new DefaultResponseErrorHandler();
|
||||
|
||||
private UriTemplateHandler uriTemplateHandler = new DefaultUriTemplateHandler();
|
||||
|
||||
private final ResponseExtractor<HttpHeaders> headersExtractor = new HeadersExtractor();
|
||||
|
||||
|
||||
@@ -226,6 +230,23 @@ public class RestTemplate extends InterceptingHttpAccessor implements RestOperat
|
||||
return this.errorHandler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a custom {@link UriTemplateHandler} for expanding URI templates.
|
||||
* <p>By default, RestTemplate uses {@link DefaultUriTemplateHandler}.
|
||||
* @param handler the URI template handler to use
|
||||
*/
|
||||
public void setUriTemplateHandler(UriTemplateHandler handler) {
|
||||
Assert.notNull(handler, "'uriTemplateHandler' is required.");
|
||||
this.uriTemplateHandler = handler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the configured URI template handler.
|
||||
*/
|
||||
public UriTemplateHandler getUriTemplateHandler() {
|
||||
return this.uriTemplateHandler;
|
||||
}
|
||||
|
||||
|
||||
// GET
|
||||
|
||||
@@ -526,7 +547,7 @@ public class RestTemplate extends InterceptingHttpAccessor implements RestOperat
|
||||
public <T> T execute(String url, HttpMethod method, RequestCallback requestCallback,
|
||||
ResponseExtractor<T> responseExtractor, Object... urlVariables) throws RestClientException {
|
||||
|
||||
URI expanded = new UriTemplate(url).expand(urlVariables);
|
||||
URI expanded = getUriTemplateHandler().expand(url, urlVariables);
|
||||
return doExecute(expanded, method, requestCallback, responseExtractor);
|
||||
}
|
||||
|
||||
@@ -534,7 +555,7 @@ public class RestTemplate extends InterceptingHttpAccessor implements RestOperat
|
||||
public <T> T execute(String url, HttpMethod method, RequestCallback requestCallback,
|
||||
ResponseExtractor<T> responseExtractor, Map<String, ?> urlVariables) throws RestClientException {
|
||||
|
||||
URI expanded = new UriTemplate(url).expand(urlVariables);
|
||||
URI expanded = getUriTemplateHandler().expand(url, urlVariables);
|
||||
return doExecute(expanded, method, requestCallback, responseExtractor);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* Copyright 2002-2015 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.web.util;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Default implementation of {@link UriTemplateHandler} that relies on
|
||||
* {@link UriComponentsBuilder} internally.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 4.2
|
||||
*/
|
||||
public class DefaultUriTemplateHandler implements UriTemplateHandler {
|
||||
|
||||
private boolean parsePath;
|
||||
|
||||
|
||||
/**
|
||||
* 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
|
||||
* into path segments so that URI variables expanded into the path are
|
||||
* treated according to path segment encoding rules. In effect that means the
|
||||
* "/" character is percent encoded.
|
||||
* <p>By default this is set to {@code false} in which case the path is kept
|
||||
* as a full path and expanded URI variables will preserve "/" characters.
|
||||
* @param parsePath whether to parse the path into path segments
|
||||
*/
|
||||
public void setParsePath(boolean parsePath) {
|
||||
this.parsePath = parsePath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the handler is configured to parse the path into path segments.
|
||||
*/
|
||||
public boolean shouldParsePath() {
|
||||
return this.parsePath;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public URI expand(String uriTemplate, Map<String, ?> uriVariables) {
|
||||
UriComponentsBuilder builder = initBuilder(uriTemplate);
|
||||
return builder.build().expand(uriVariables).encode().toUri();
|
||||
}
|
||||
|
||||
@Override
|
||||
public URI expand(String uriTemplate, Object... uriVariableValues) {
|
||||
UriComponentsBuilder builder = initBuilder(uriTemplate);
|
||||
return builder.build().expand(uriVariableValues).encode().toUri();
|
||||
}
|
||||
|
||||
protected UriComponentsBuilder initBuilder(String uriTemplate) {
|
||||
UriComponentsBuilder builder = UriComponentsBuilder.fromUriString(uriTemplate);
|
||||
if (shouldParsePath()) {
|
||||
List<String> pathSegments = builder.build().getPathSegments();
|
||||
builder.replacePath(null);
|
||||
for (String pathSegment : pathSegments) {
|
||||
builder.pathSegment(pathSegment);
|
||||
}
|
||||
}
|
||||
return builder;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright 2002-2015 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.web.util;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* A strategy for expanding a URI template with URI variables into a {@link URI}.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 4.2
|
||||
*/
|
||||
public interface UriTemplateHandler {
|
||||
|
||||
/**
|
||||
* Expand the give URI template with a map of URI variables.
|
||||
* @param uriTemplate the URI template string
|
||||
* @param uriVariables the URI variables
|
||||
* @return the resulting URI
|
||||
*/
|
||||
URI expand(String uriTemplate, Map<String, ?> uriVariables);
|
||||
|
||||
/**
|
||||
* Expand the give URI template with an array of URI variable values.
|
||||
* @param uriTemplate the URI template string
|
||||
* @param uriVariableValues the URI variable values
|
||||
* @return the resulting URI
|
||||
*/
|
||||
URI expand(String uriTemplate, Object... uriVariableValues);
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user