Remove http -> web package dependency

See gh-24406
This commit is contained in:
Rossen Stoyanchev 2020-06-10 21:45:26 +01:00
parent adc76a1d8f
commit a0f4d81db7
3 changed files with 130 additions and 62 deletions

View File

@ -24,13 +24,10 @@ import java.time.ZonedDateTime;
import java.util.Arrays;
import java.util.Map;
import java.util.function.Consumer;
import java.util.function.Function;
import org.springframework.lang.Nullable;
import org.springframework.util.MultiValueMap;
import org.springframework.util.ObjectUtils;
import org.springframework.web.util.DefaultUriBuilderFactory;
import org.springframework.web.util.UriTemplateHandler;
/**
* Extension of {@link HttpEntity} that also exposes the HTTP method and the
@ -69,17 +66,14 @@ import org.springframework.web.util.UriTemplateHandler;
*/
public class RequestEntity<T> extends HttpEntity<T> {
private final static UriTemplateHandler DEFAULT_TEMPLATE_HANDLER = new DefaultUriBuilderFactory();
@Nullable
private final HttpMethod method;
private final Function<UriTemplateHandler, URI> uriFunction;
private final URI url;
@Nullable
private final Type type;
/**
* Constructor with method and URL but without body nor headers.
* @param method the method
@ -146,19 +140,9 @@ public class RequestEntity<T> extends HttpEntity<T> {
public RequestEntity(@Nullable T body, @Nullable MultiValueMap<String, String> headers,
@Nullable HttpMethod method, URI url, @Nullable Type type) {
this(body, headers, method, handler -> url, type);
}
/**
* Private constructor with URI function.
* @since 5.3
*/
private RequestEntity(@Nullable T body, @Nullable MultiValueMap<String, String> headers,
@Nullable HttpMethod method, Function<UriTemplateHandler, URI> uriFunction, @Nullable Type type) {
super(body, headers);
this.method = method;
this.uriFunction = uriFunction;
this.url = url;
this.type = type;
}
@ -174,24 +158,9 @@ public class RequestEntity<T> extends HttpEntity<T> {
/**
* Return the URL of the request.
* <p>If the URL was provided as a URI template, the returned URI is expanded
* and encoded with {@link DefaultUriBuilderFactory}.
* @return the URL as a {@code URI}
*/
public URI getUrl() {
return this.uriFunction.apply(DEFAULT_TEMPLATE_HANDLER);
}
/**
* Return the URL of the request.
* <p>If the URL was provided as a URI template, the returned URI is expanded
* with the given {@link DefaultUriBuilderFactory}.
* @param templateHandler the handler to use to expand the URI template with
* @return the URL as a {@code URI}
* @since 5.3
*/
public URI getUrl(UriTemplateHandler templateHandler) {
return this.uriFunction.apply(templateHandler);
return this.url;
}
@ -235,13 +204,15 @@ public class RequestEntity<T> extends HttpEntity<T> {
@Override
public String toString() {
return format(getMethod(), getUrl().toString(), getBody(), getHeaders());
}
static <T> String format(@Nullable HttpMethod httpMethod, String url, @Nullable T body, HttpHeaders headers) {
StringBuilder builder = new StringBuilder("<");
builder.append(getMethod());
builder.append(httpMethod);
builder.append(' ');
builder.append(getUrl());
builder.append(url);
builder.append(',');
T body = getBody();
HttpHeaders headers = getHeaders();
if (body != null) {
builder.append(body);
builder.append(',');
@ -563,24 +534,42 @@ public class RequestEntity<T> extends HttpEntity<T> {
private final HttpMethod method;
private final Function<UriTemplateHandler, URI> uriFunction;
private final HttpHeaders headers = new HttpHeaders();
@Nullable
private final URI uri;
public DefaultBodyBuilder(HttpMethod method, URI url) {
@Nullable
String uriTemplate;
@Nullable
private Object[] uriVarsArray;
@Nullable
Map<String, ?> uriVarsMap;
DefaultBodyBuilder(HttpMethod method, URI url) {
this.method = method;
this.uriFunction = handler -> url;
this.uri = url;
this.uriTemplate = null;
this.uriVarsArray = null;
this.uriVarsMap = null;
}
public DefaultBodyBuilder(HttpMethod method, String uriTemplate, Object... uriVars) {
DefaultBodyBuilder(HttpMethod method, String uriTemplate, Object... uriVars) {
this.method = method;
this.uriFunction = handler -> handler.expand(uriTemplate, uriVars);
this.uri = null;
this.uriTemplate = uriTemplate;
this.uriVarsArray = uriVars;
this.uriVarsMap = null;
}
public DefaultBodyBuilder(HttpMethod method, String uriTemplate, Map<String, ?> uriVars) {
DefaultBodyBuilder(HttpMethod method, String uriTemplate, Map<String, ?> uriVars) {
this.method = method;
this.uriFunction = handler -> handler.expand(uriTemplate, uriVars);
this.uri = null;
this.uriTemplate = uriTemplate;
this.uriVarsArray = null;
this.uriVarsMap = uriVars;
}
@Override
@ -655,17 +644,85 @@ public class RequestEntity<T> extends HttpEntity<T> {
@Override
public RequestEntity<Void> build() {
return new RequestEntity<>(null, this.headers, this.method, this.uriFunction, null);
return buildInternal(null, null);
}
@Override
public <T> RequestEntity<T> body(T body) {
return new RequestEntity<>(body, this.headers, this.method, this.uriFunction, null);
return buildInternal(body, null);
}
@Override
public <T> RequestEntity<T> body(T body, Type type) {
return new RequestEntity<>(body, this.headers, this.method, this.uriFunction, type);
return buildInternal(body, type);
}
private <T> RequestEntity<T> buildInternal(@Nullable T body, @Nullable Type type) {
if (this.uri != null) {
return new RequestEntity<>(body, this.headers, this.method, this.uri, type);
}
else if (this.uriTemplate != null){
return new UriTemplateRequestEntity<>(body, this.headers, this.method, type,
this.uriTemplate, this.uriVarsArray, this.uriVarsMap);
}
else {
throw new IllegalStateException("Neither URI nor URI template");
}
}
}
/**
* RequestEntity initialized with a URI template and variables instead of a {@link URI}.
* @since 5.3
* @param <T> the body type
*/
public static class UriTemplateRequestEntity<T> extends RequestEntity<T> {
String uriTemplate;
@Nullable
private Object[] uriVarsArray;
@Nullable
Map<String, ?> uriVarsMap;
UriTemplateRequestEntity(
@Nullable T body, @Nullable MultiValueMap<String, String> headers,
@Nullable HttpMethod method, @Nullable Type type, String uriTemplate,
@Nullable Object[] uriVarsArray, @Nullable Map<String, ?> uriVarsMap) {
super(body, headers, method, null, type);
this.uriTemplate = uriTemplate;
this.uriVarsArray = uriVarsArray;
this.uriVarsMap = uriVarsMap;
}
public String getUriTemplate() {
return this.uriTemplate;
}
@Nullable
public Object[] getVars() {
return this.uriVarsArray;
}
@Nullable
public Map<String, ?> getVarsMap() {
return this.uriVarsMap;
}
@Override
public URI getUrl() {
throw new UnsupportedOperationException();
}
@Override
public String toString() {
return format(getMethod(), getUriTemplate(), getBody(), getHeaders());
}
}
}

View File

@ -633,24 +633,34 @@ public class RestTemplate extends InterceptingHttpAccessor implements RestOperat
}
@Override
public <T> ResponseEntity<T> exchange(RequestEntity<?> requestEntity, Class<T> responseType)
public <T> ResponseEntity<T> exchange(RequestEntity<?> entity, Class<T> responseType)
throws RestClientException {
RequestCallback requestCallback = httpEntityCallback(requestEntity, responseType);
RequestCallback requestCallback = httpEntityCallback(entity, responseType);
ResponseExtractor<ResponseEntity<T>> responseExtractor = responseEntityExtractor(responseType);
URI url = requestEntity.getUrl(this.uriTemplateHandler);
return nonNull(doExecute(url, requestEntity.getMethod(), requestCallback, responseExtractor));
return nonNull(doExecute(resolveUrl(entity), entity.getMethod(), requestCallback, responseExtractor));
}
@Override
public <T> ResponseEntity<T> exchange(RequestEntity<?> requestEntity, ParameterizedTypeReference<T> responseType)
public <T> ResponseEntity<T> exchange(RequestEntity<?> entity, ParameterizedTypeReference<T> responseType)
throws RestClientException {
Type type = responseType.getType();
RequestCallback requestCallback = httpEntityCallback(requestEntity, type);
RequestCallback requestCallback = httpEntityCallback(entity, type);
ResponseExtractor<ResponseEntity<T>> responseExtractor = responseEntityExtractor(type);
URI url = requestEntity.getUrl(this.uriTemplateHandler);
return nonNull(doExecute(url, requestEntity.getMethod(), requestCallback, responseExtractor));
return nonNull(doExecute(resolveUrl(entity), entity.getMethod(), requestCallback, responseExtractor));
}
private URI resolveUrl(RequestEntity<?> entity) {
if (entity instanceof RequestEntity.UriTemplateRequestEntity) {
RequestEntity.UriTemplateRequestEntity<?> ext = (RequestEntity.UriTemplateRequestEntity<?>) entity;
return (ext.getVars() != null ?
this.uriTemplateHandler.expand(ext.getUriTemplate(), ext.getVars()) :
this.uriTemplateHandler.expand(ext.getUriTemplate(), ext.getVarsMap()));
}
else {
return entity.getUrl();
}
}

View File

@ -82,16 +82,17 @@ public class RequestEntityTests {
}
@Test
public void uriExpansion() throws URISyntaxException{
public void uriExpansion() {
RequestEntity<Void> entity =
RequestEntity.get("https://www.{host}.com/{path}", "example", "foo/bar").build();
DefaultUriBuilderFactory factory = new DefaultUriBuilderFactory();
assertThat(entity.getUrl(factory)).isEqualTo(new URI("https://www.example.com/foo%2Fbar"));
assertThat(entity).isInstanceOf(RequestEntity.UriTemplateRequestEntity.class);
RequestEntity.UriTemplateRequestEntity<Void> ext = (RequestEntity.UriTemplateRequestEntity<Void>) entity;
factory.setEncodingMode(DefaultUriBuilderFactory.EncodingMode.NONE);
assertThat(entity.getUrl(factory)).isEqualTo(new URI("https://www.example.com/foo/bar"));
DefaultUriBuilderFactory factory = new DefaultUriBuilderFactory();
assertThat(ext.getUriTemplate()).isEqualTo("https://www.{host}.com/{path}");
assertThat(ext.getVars()).containsExactly("example", "foo/bar");
}