From ddf996cfeb5a725f9ff21e8c14b44c41fcf27d99 Mon Sep 17 00:00:00 2001 From: Brian Clozel Date: Mon, 4 Apr 2016 22:47:24 +0200 Subject: [PATCH] Polish HttpRequestBuilder API This commit makes messageEncoders a required argument for building a client request - those are needed to actually encode the body object as a reactive stream to be written to the HTTP request body. Removed raw types usage in DefaultHttpRequestBuilder. DefaultHttpRequestBuilder now uses a UriTemplateHandler to expand URI templates + variables into a concrete URI. Fixes #80, fixes #85, fixes #86 --- .../reactive/DefaultHttpRequestBuilder.java | 42 +++++-------------- .../client/reactive/HttpRequestBuilder.java | 8 +++- .../web/client/reactive/WebClient.java | 7 +--- 3 files changed, 20 insertions(+), 37 deletions(-) diff --git a/spring-web-reactive/src/main/java/org/springframework/web/client/reactive/DefaultHttpRequestBuilder.java b/spring-web-reactive/src/main/java/org/springframework/web/client/reactive/DefaultHttpRequestBuilder.java index dde80dd4552..cdbe4c9ed2b 100644 --- a/spring-web-reactive/src/main/java/org/springframework/web/client/reactive/DefaultHttpRequestBuilder.java +++ b/spring-web-reactive/src/main/java/org/springframework/web/client/reactive/DefaultHttpRequestBuilder.java @@ -18,7 +18,6 @@ package org.springframework.web.client.reactive; import java.net.URI; -import java.net.URISyntaxException; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -40,6 +39,8 @@ import org.springframework.http.client.reactive.ClientHttpRequest; import org.springframework.http.client.reactive.ClientHttpRequestFactory; import org.springframework.util.Assert; import org.springframework.web.client.RestClientException; +import org.springframework.web.util.DefaultUriTemplateHandler; +import org.springframework.web.util.UriTemplateHandler; /** * Builds a {@link ClientHttpRequest} @@ -51,6 +52,8 @@ import org.springframework.web.client.RestClientException; */ public class DefaultHttpRequestBuilder implements HttpRequestBuilder { + private final UriTemplateHandler uriTemplateHandler = new DefaultUriTemplateHandler(); + protected HttpMethod httpMethod; protected HttpHeaders httpHeaders; @@ -59,8 +62,6 @@ public class DefaultHttpRequestBuilder implements HttpRequestBuilder { protected Publisher contentPublisher; - protected List> messageEncoders; - protected final List cookies = new ArrayList(); protected DefaultHttpRequestBuilder() { @@ -69,7 +70,7 @@ public class DefaultHttpRequestBuilder implements HttpRequestBuilder { public DefaultHttpRequestBuilder(HttpMethod httpMethod, String urlTemplate, Object... urlVariables) throws RestClientException { this.httpMethod = httpMethod; this.httpHeaders = new HttpHeaders(); - this.url = parseURI(urlTemplate); + this.url = this.uriTemplateHandler.expand(urlTemplate, urlVariables); } public DefaultHttpRequestBuilder(HttpMethod httpMethod, URI url) { @@ -78,24 +79,6 @@ public class DefaultHttpRequestBuilder implements HttpRequestBuilder { this.url = url; } - protected DefaultHttpRequestBuilder setMessageEncoders(List> messageEncoders) { - this.messageEncoders = messageEncoders; - return this; - } - - private URI parseURI(String uri) throws RestClientException { - try { - return new URI(uri); - } - catch (URISyntaxException e) { - throw new RestClientException("could not parse URL template", e); - } - } - - public DefaultHttpRequestBuilder param(String name, String... values) { - return this; - } - public DefaultHttpRequestBuilder header(String name, String... values) { Arrays.stream(values).forEach(value -> this.httpHeaders.add(name, value)); return this; @@ -133,7 +116,7 @@ public class DefaultHttpRequestBuilder implements HttpRequestBuilder { return this; } - public DefaultHttpRequestBuilder contentStream(Publisher content) { + public DefaultHttpRequestBuilder contentStream(Publisher content) { this.contentPublisher = Flux.from(content); return this; } @@ -153,7 +136,7 @@ public class DefaultHttpRequestBuilder implements HttpRequestBuilder { return this; } - public ClientHttpRequest build(ClientHttpRequestFactory factory) { + public ClientHttpRequest build(ClientHttpRequestFactory factory, List> messageEncoders) { ClientHttpRequest request = factory.createRequest(this.httpMethod, this.url, this.httpHeaders); request.getHeaders().putAll(this.httpHeaders); @@ -161,7 +144,10 @@ public class DefaultHttpRequestBuilder implements HttpRequestBuilder { ResolvableType requestBodyType = ResolvableType.forInstance(this.contentPublisher); MediaType mediaType = request.getHeaders().getContentType(); - Optional> messageEncoder = resolveEncoder(requestBodyType, mediaType); + Optional> messageEncoder = messageEncoders + .stream() + .filter(e -> e.canEncode(requestBodyType, mediaType)) + .findFirst(); if (messageEncoder.isPresent()) { DataBufferAllocator allocator = request.allocator(); @@ -175,13 +161,7 @@ public class DefaultHttpRequestBuilder implements HttpRequestBuilder { "' for content-type '" + mediaType.toString() + "'"); } } - return request; } - protected Optional> resolveEncoder(ResolvableType type, MediaType mediaType) { - return this.messageEncoders.stream() - .filter(e -> e.canEncode(type, mediaType)).findFirst(); - } - } \ No newline at end of file diff --git a/spring-web-reactive/src/main/java/org/springframework/web/client/reactive/HttpRequestBuilder.java b/spring-web-reactive/src/main/java/org/springframework/web/client/reactive/HttpRequestBuilder.java index 55d5e182294..32e2527a5ea 100644 --- a/spring-web-reactive/src/main/java/org/springframework/web/client/reactive/HttpRequestBuilder.java +++ b/spring-web-reactive/src/main/java/org/springframework/web/client/reactive/HttpRequestBuilder.java @@ -16,6 +16,9 @@ package org.springframework.web.client.reactive; +import java.util.List; + +import org.springframework.core.codec.Encoder; import org.springframework.http.client.reactive.ClientHttpRequest; import org.springframework.http.client.reactive.ClientHttpRequestFactory; @@ -29,6 +32,9 @@ public interface HttpRequestBuilder { /** * Build a {@link ClientHttpRequest} + * + * @param factory the factory that creates the actual {@link ClientHttpRequest} + * @param messageEncoders the {@link Encoder}s to use for encoding the request body */ - ClientHttpRequest build(ClientHttpRequestFactory factory); + ClientHttpRequest build(ClientHttpRequestFactory factory, List> messageEncoders); } diff --git a/spring-web-reactive/src/main/java/org/springframework/web/client/reactive/WebClient.java b/spring-web-reactive/src/main/java/org/springframework/web/client/reactive/WebClient.java index ff825bc4ba1..50f9205c2fb 100644 --- a/spring-web-reactive/src/main/java/org/springframework/web/client/reactive/WebClient.java +++ b/spring-web-reactive/src/main/java/org/springframework/web/client/reactive/WebClient.java @@ -31,8 +31,6 @@ import org.springframework.core.codec.support.JacksonJsonEncoder; import org.springframework.core.codec.support.JsonObjectDecoder; import org.springframework.core.codec.support.StringDecoder; import org.springframework.core.codec.support.StringEncoder; -import org.springframework.core.io.buffer.DataBufferAllocator; -import org.springframework.core.io.buffer.DefaultDataBufferAllocator; import org.springframework.http.HttpStatus; import org.springframework.http.client.reactive.ClientHttpRequest; import org.springframework.http.client.reactive.ClientHttpRequestFactory; @@ -85,7 +83,6 @@ public final class WebClient { */ public WebClient(ClientHttpRequestFactory requestFactory) { this.requestFactory = requestFactory; - DataBufferAllocator allocator = new DefaultDataBufferAllocator(); this.messageEncoders = Arrays.asList(new ByteBufferEncoder(), new StringEncoder(), new JacksonJsonEncoder()); this.messageDecoders = Arrays.asList(new ByteBufferDecoder(), new StringDecoder(), @@ -116,9 +113,9 @@ public final class WebClient { *
  • returning the response with a publisher of the body
  • * */ - public WebResponseActions perform(DefaultHttpRequestBuilder builder) { + public WebResponseActions perform(HttpRequestBuilder builder) { - ClientHttpRequest request = builder.setMessageEncoders(messageEncoders).build(requestFactory); + ClientHttpRequest request = builder.build(this.requestFactory, this.messageEncoders); final Mono clientResponse = request.execute() .log("org.springframework.http.client.reactive");