Polishing
This commit is contained in:
parent
7582adc0bc
commit
6242e30539
|
|
@ -28,6 +28,7 @@ import org.springframework.http.codec.HttpMessageReader;
|
|||
*
|
||||
* @param <T> the type of data to extract
|
||||
* @param <M> the type of {@link ReactiveHttpInputMessage} this extractor can be applied to
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
* @since 5.0
|
||||
* @see BodyExtractors
|
||||
|
|
@ -37,20 +38,21 @@ public interface BodyExtractor<T, M extends ReactiveHttpInputMessage> {
|
|||
|
||||
/**
|
||||
* Extract from the given input message.
|
||||
* @param inputMessage request to extract from
|
||||
* @param inputMessage the request to extract from
|
||||
* @param context the configuration to use
|
||||
* @return the extracted data
|
||||
*/
|
||||
T extract(M inputMessage, Context context);
|
||||
|
||||
|
||||
/**
|
||||
* Defines the context used during the extraction.
|
||||
*/
|
||||
interface Context {
|
||||
|
||||
/**
|
||||
* Supply a {@linkplain Stream stream} of {@link HttpMessageReader}s to be used for body
|
||||
* extraction.
|
||||
* Supply a {@linkplain Stream stream} of {@link HttpMessageReader}s
|
||||
* to be used for body extraction.
|
||||
* @return the stream of message readers
|
||||
*/
|
||||
Supplier<Stream<HttpMessageReader<?>>> messageReaders();
|
||||
|
|
|
|||
|
|
@ -112,18 +112,6 @@ public abstract class BodyExtractors {
|
|||
};
|
||||
}
|
||||
|
||||
private static HttpMessageReader<MultiValueMap<String, String>> formMessageReader(BodyExtractor.Context context) {
|
||||
return context.messageReaders().get()
|
||||
.filter(messageReader -> messageReader
|
||||
.canRead(FORM_TYPE, MediaType.APPLICATION_FORM_URLENCODED))
|
||||
.findFirst()
|
||||
.map(BodyExtractors::<MultiValueMap<String, String>>cast)
|
||||
.orElseThrow(() -> new IllegalStateException(
|
||||
"Could not find HttpMessageReader that supports " +
|
||||
MediaType.APPLICATION_FORM_URLENCODED_VALUE));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return a {@code BodyExtractor} that returns the body of the message as a {@link Flux} of
|
||||
* {@link DataBuffer}s.
|
||||
|
|
@ -136,12 +124,10 @@ public abstract class BodyExtractors {
|
|||
return (inputMessage, context) -> inputMessage.getBody();
|
||||
}
|
||||
|
||||
|
||||
private static <T, S extends Publisher<T>> S readWithMessageReaders(
|
||||
ReactiveHttpInputMessage inputMessage,
|
||||
BodyExtractor.Context context,
|
||||
ResolvableType elementType,
|
||||
Function<HttpMessageReader<T>, S> readerFunction,
|
||||
Function<Throwable, S> unsupportedError) {
|
||||
ReactiveHttpInputMessage inputMessage, BodyExtractor.Context context, ResolvableType elementType,
|
||||
Function<HttpMessageReader<T>, S> readerFunction, Function<Throwable, S> unsupportedError) {
|
||||
|
||||
MediaType contentType = contentType(inputMessage);
|
||||
Supplier<Stream<HttpMessageReader<?>>> messageReaders = context.messageReaders();
|
||||
|
|
@ -160,6 +146,17 @@ public abstract class BodyExtractors {
|
|||
});
|
||||
}
|
||||
|
||||
private static HttpMessageReader<MultiValueMap<String, String>> formMessageReader(BodyExtractor.Context context) {
|
||||
return context.messageReaders().get()
|
||||
.filter(messageReader -> messageReader
|
||||
.canRead(FORM_TYPE, MediaType.APPLICATION_FORM_URLENCODED))
|
||||
.findFirst()
|
||||
.map(BodyExtractors::<MultiValueMap<String, String>>cast)
|
||||
.orElseThrow(() -> new IllegalStateException(
|
||||
"Could not find HttpMessageReader that supports " +
|
||||
MediaType.APPLICATION_FORM_URLENCODED_VALUE));
|
||||
}
|
||||
|
||||
private static MediaType contentType(HttpMessage message) {
|
||||
MediaType result = message.getHeaders().getContentType();
|
||||
return result != null ? result : MediaType.APPLICATION_OCTET_STREAM;
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ import org.springframework.http.codec.HttpMessageWriter;
|
|||
*
|
||||
* @param <T> the type of data to insert
|
||||
* @param <M> the type of {@link ReactiveHttpOutputMessage} this inserter can be applied to
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
* @since 5.0
|
||||
* @see BodyInserters
|
||||
|
|
@ -45,14 +46,15 @@ public interface BodyInserter<T, M extends ReactiveHttpOutputMessage> {
|
|||
*/
|
||||
Mono<Void> insert(M outputMessage, Context context);
|
||||
|
||||
|
||||
/**
|
||||
* Defines the context used during the insertion.
|
||||
*/
|
||||
interface Context {
|
||||
|
||||
/**
|
||||
* Supply a {@linkplain Stream stream} of {@link HttpMessageWriter}s to be used for response
|
||||
* body conversion.
|
||||
* Supply a {@linkplain Stream stream} of {@link HttpMessageWriter}s
|
||||
* to be used for response body conversion.
|
||||
* @return the stream of message writers
|
||||
*/
|
||||
Supplier<Stream<HttpMessageWriter<?>>> messageWriters();
|
||||
|
|
@ -61,8 +63,6 @@ public interface BodyInserter<T, M extends ReactiveHttpOutputMessage> {
|
|||
* Return the map of hints to use for response body conversion.
|
||||
*/
|
||||
Map<String, Object> hints();
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,7 +45,8 @@ import org.springframework.util.MultiValueMap;
|
|||
*/
|
||||
public abstract class BodyInserters {
|
||||
|
||||
private static final ResolvableType RESOURCE_TYPE = ResolvableType.forClass(Resource.class);
|
||||
private static final ResolvableType RESOURCE_TYPE =
|
||||
ResolvableType.forClass(Resource.class);
|
||||
|
||||
private static final ResolvableType SERVER_SIDE_EVENT_TYPE =
|
||||
ResolvableType.forClass(ServerSentEvent.class);
|
||||
|
|
@ -53,7 +54,6 @@ public abstract class BodyInserters {
|
|||
private static final ResolvableType FORM_TYPE =
|
||||
ResolvableType.forClassWithGenerics(MultiValueMap.class, String.class, String.class);
|
||||
|
||||
|
||||
private static final BodyInserter<Void, ReactiveHttpOutputMessage> EMPTY =
|
||||
(response, context) -> response.setComplete();
|
||||
|
||||
|
|
@ -223,19 +223,6 @@ public abstract class BodyInserters {
|
|||
};
|
||||
}
|
||||
|
||||
private static <T> HttpMessageWriter<T> findMessageWriter(
|
||||
BodyInserter.Context context, ResolvableType type, MediaType mediaType) {
|
||||
|
||||
return context.messageWriters().get()
|
||||
.filter(messageWriter -> messageWriter.canWrite(type, mediaType))
|
||||
.findFirst()
|
||||
.map(BodyInserters::<T>cast)
|
||||
.orElseThrow(() -> new IllegalStateException(
|
||||
"Could not find HttpMessageWriter that supports " + mediaType));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Return a {@code BodyInserter} that writes the given {@code Publisher<DataBuffer>} to the body.
|
||||
* @param publisher the data buffer publisher to write
|
||||
|
|
@ -274,6 +261,17 @@ public abstract class BodyInserters {
|
|||
};
|
||||
}
|
||||
|
||||
private static <T> HttpMessageWriter<T> findMessageWriter(
|
||||
BodyInserter.Context context, ResolvableType type, MediaType mediaType) {
|
||||
|
||||
return context.messageWriters().get()
|
||||
.filter(messageWriter -> messageWriter.canWrite(type, mediaType))
|
||||
.findFirst()
|
||||
.map(BodyInserters::<T>cast)
|
||||
.orElseThrow(() -> new IllegalStateException(
|
||||
"Could not find HttpMessageWriter that supports " + mediaType));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private static <T> HttpMessageWriter<T> cast(HttpMessageWriter<?> messageWriter) {
|
||||
return (HttpMessageWriter<T>) messageWriter;
|
||||
|
|
|
|||
|
|
@ -81,7 +81,6 @@ public interface ClientRequest {
|
|||
|
||||
/**
|
||||
* Create a builder with the method, URI, headers, and cookies of the given request.
|
||||
*
|
||||
* @param other the request to copy the method, URI, headers, and cookies from
|
||||
* @return the created builder
|
||||
*/
|
||||
|
|
@ -120,7 +119,6 @@ public interface ClientRequest {
|
|||
|
||||
/**
|
||||
* Copy the given headers into the entity's headers map.
|
||||
*
|
||||
* @param headers the existing HttpHeaders to copy from
|
||||
* @return this builder
|
||||
*/
|
||||
|
|
@ -136,7 +134,6 @@ public interface ClientRequest {
|
|||
|
||||
/**
|
||||
* Copy the given cookies into the entity's cookies map.
|
||||
*
|
||||
* @param cookies the existing cookies to copy from
|
||||
* @return this builder
|
||||
*/
|
||||
|
|
@ -164,7 +161,6 @@ public interface ClientRequest {
|
|||
* @return the request entity
|
||||
*/
|
||||
ClientRequest build();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -110,7 +110,6 @@ public interface ClientResponse {
|
|||
/**
|
||||
* Return the header value(s), if any, for the header of the given name.
|
||||
* <p>Return an empty list if no header values are found.
|
||||
*
|
||||
* @param headerName the header name
|
||||
*/
|
||||
List<String> header(String headerName);
|
||||
|
|
|
|||
|
|
@ -61,6 +61,7 @@ class DefaultClientRequestBuilder implements ClientRequest.Builder {
|
|||
this.url = url;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public ClientRequest.Builder header(String headerName, String... headerValues) {
|
||||
for (String headerValue : headerValues) {
|
||||
|
|
@ -113,6 +114,7 @@ class DefaultClientRequestBuilder implements ClientRequest.Builder {
|
|||
this.inserter);
|
||||
}
|
||||
|
||||
|
||||
private static class BodyInserterRequest implements ClientRequest {
|
||||
|
||||
private final HttpMethod method;
|
||||
|
|
@ -126,8 +128,8 @@ class DefaultClientRequestBuilder implements ClientRequest.Builder {
|
|||
private final BodyInserter<?, ? super ClientHttpRequest> inserter;
|
||||
|
||||
public BodyInserterRequest(HttpMethod method, URI url, HttpHeaders headers,
|
||||
MultiValueMap<String, String> cookies,
|
||||
BodyInserter<?, ? super ClientHttpRequest> inserter) {
|
||||
MultiValueMap<String, String> cookies, BodyInserter<?, ? super ClientHttpRequest> inserter) {
|
||||
|
||||
this.method = method;
|
||||
this.url = url;
|
||||
this.headers = HttpHeaders.readOnlyHttpHeaders(headers);
|
||||
|
|
@ -169,6 +171,7 @@ class DefaultClientRequestBuilder implements ClientRequest.Builder {
|
|||
.forEach(entry -> requestHeaders
|
||||
.put(entry.getKey(), entry.getValue()));
|
||||
}
|
||||
|
||||
MultiValueMap<String, HttpCookie> requestCookies = request.getCookies();
|
||||
if (!this.cookies.isEmpty()) {
|
||||
this.cookies.entrySet().forEach(entry -> {
|
||||
|
|
@ -185,7 +188,6 @@ class DefaultClientRequestBuilder implements ClientRequest.Builder {
|
|||
public Supplier<Stream<HttpMessageWriter<?>>> messageWriters() {
|
||||
return strategies.messageWriters();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> hints() {
|
||||
return Collections.emptyMap();
|
||||
|
|
@ -193,4 +195,5 @@ class DefaultClientRequestBuilder implements ClientRequest.Builder {
|
|||
});
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -60,6 +60,7 @@ class DefaultClientResponse implements ClientResponse {
|
|||
this.headers = new DefaultHeaders();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public HttpStatus statusCode() {
|
||||
return this.response.getStatusCode();
|
||||
|
|
@ -99,6 +100,7 @@ class DefaultClientResponse implements ClientResponse {
|
|||
return bodyToPublisher(BodyExtractors.toFlux(elementClass), Flux::error);
|
||||
}
|
||||
|
||||
|
||||
private <T extends Publisher<?>> T bodyToPublisher(
|
||||
BodyExtractor<T, ? super ClientHttpResponse> extractor,
|
||||
Function<WebClientException, T> errorFunction) {
|
||||
|
|
@ -115,6 +117,7 @@ class DefaultClientResponse implements ClientResponse {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
private class DefaultHeaders implements Headers {
|
||||
|
||||
private HttpHeaders delegate() {
|
||||
|
|
|
|||
|
|
@ -130,6 +130,7 @@ class DefaultExchangeStrategiesBuilder implements ExchangeStrategies.Builder {
|
|||
return new DefaultExchangeStrategies(this.messageReaders, this.messageWriters);
|
||||
}
|
||||
|
||||
|
||||
private static class DefaultExchangeStrategies implements ExchangeStrategies {
|
||||
|
||||
private final List<HttpMessageReader<?>> messageReaders;
|
||||
|
|
@ -137,8 +138,8 @@ class DefaultExchangeStrategiesBuilder implements ExchangeStrategies.Builder {
|
|||
private final List<HttpMessageWriter<?>> messageWriters;
|
||||
|
||||
public DefaultExchangeStrategies(
|
||||
List<HttpMessageReader<?>> messageReaders,
|
||||
List<HttpMessageWriter<?>> messageWriters) {
|
||||
List<HttpMessageReader<?>> messageReaders, List<HttpMessageWriter<?>> messageWriters) {
|
||||
|
||||
this.messageReaders = unmodifiableCopy(messageReaders);
|
||||
this.messageWriters = unmodifiableCopy(messageWriters);
|
||||
}
|
||||
|
|
@ -156,7 +157,6 @@ class DefaultExchangeStrategiesBuilder implements ExchangeStrategies.Builder {
|
|||
public Supplier<Stream<HttpMessageWriter<?>>> messageWriters() {
|
||||
return this.messageWriters::stream;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,11 +32,10 @@ import org.springframework.util.Assert;
|
|||
public interface ExchangeFilterFunction {
|
||||
|
||||
/**
|
||||
* Apply this filter to the given request and exchange function. The given
|
||||
* {@linkplain ExchangeFunction exchange function} represents the next entity in the
|
||||
* chain, and can be {@linkplain ExchangeFunction#exchange(ClientRequest) invoked} in order
|
||||
* to proceed to the exchange, or not invoked to block the chain.
|
||||
*
|
||||
* Apply this filter to the given request and exchange function.
|
||||
* <p>The given {@linkplain ExchangeFunction exchange function} represents the next entity
|
||||
* in the chain, and can be {@linkplain ExchangeFunction#exchange(ClientRequest) invoked}
|
||||
* in order to proceed to the exchange, or not invoked to block the chain.
|
||||
* @param request the request
|
||||
* @param next the next exchange function in the chain
|
||||
* @return the filtered response
|
||||
|
|
|
|||
|
|
@ -23,15 +23,15 @@ import org.springframework.util.Assert;
|
|||
/**
|
||||
* Represents a function that exchanges a {@linkplain ClientRequest request} for a (delayed)
|
||||
* {@linkplain ClientResponse}. Can be used as an alternative to {@link WebClient}.
|
||||
*
|
||||
* <p>For example:
|
||||
* <pre class="code">
|
||||
* ExchangeFunction exchangeFunction = ExchangeFunctions.create(new ReactorClientHttpConnector());
|
||||
* ClientRequest<Void> request = ClientRequest.method(HttpMethod.GET,
|
||||
* "http://example.com/resource").build();
|
||||
* ClientRequest<Void> request = ClientRequest.method(HttpMethod.GET, "http://example.com/resource").build();
|
||||
*
|
||||
* Mono<String> result = exchangeFunction
|
||||
* .exchange(request)
|
||||
* .then(response -> response.bodyToMono(String.class));
|
||||
* .exchange(request)
|
||||
* .then(response -> response.bodyToMono(String.class));
|
||||
* </pre>
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
|
|
@ -56,7 +56,6 @@ public interface ExchangeFunction {
|
|||
*/
|
||||
default ExchangeFunction filter(ExchangeFilterFunction filter) {
|
||||
Assert.notNull(filter, "'filter' must not be null");
|
||||
|
||||
return filter.apply(this);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -49,11 +49,9 @@ public abstract class ExchangeFunctions {
|
|||
* @param strategies the strategies to use
|
||||
* @return the created function
|
||||
*/
|
||||
public static ExchangeFunction create(ClientHttpConnector connector,
|
||||
ExchangeStrategies strategies) {
|
||||
public static ExchangeFunction create(ClientHttpConnector connector, ExchangeStrategies strategies) {
|
||||
Assert.notNull(connector, "'connector' must not be null");
|
||||
Assert.notNull(strategies, "'strategies' must not be null");
|
||||
|
||||
return new DefaultExchangeFunction(connector, strategies);
|
||||
}
|
||||
|
||||
|
|
@ -64,9 +62,7 @@ public abstract class ExchangeFunctions {
|
|||
|
||||
private final ExchangeStrategies strategies;
|
||||
|
||||
public DefaultExchangeFunction(
|
||||
ClientHttpConnector connector,
|
||||
ExchangeStrategies strategies) {
|
||||
public DefaultExchangeFunction(ClientHttpConnector connector, ExchangeStrategies strategies) {
|
||||
this.connector = connector;
|
||||
this.strategies = strategies;
|
||||
}
|
||||
|
|
@ -74,7 +70,6 @@ public abstract class ExchangeFunctions {
|
|||
@Override
|
||||
public Mono<ClientResponse> exchange(ClientRequest request) {
|
||||
Assert.notNull(request, "'request' must not be null");
|
||||
|
||||
return this.connector
|
||||
.connect(request.method(), request.url(),
|
||||
clientHttpRequest -> request.writeTo(clientHttpRequest, this.strategies))
|
||||
|
|
|
|||
|
|
@ -29,8 +29,8 @@ import org.springframework.util.Assert;
|
|||
/**
|
||||
* Defines the strategies for invoking {@link ExchangeFunction}s. An instance of
|
||||
* this class is immutable; instances are typically created through the mutable {@link Builder}:
|
||||
* either through {@link #builder()} to set up default strategies, or {@link #empty()} to start from
|
||||
* scratch. Alternatively, {@code ExchangeStrategies} instances can be created through
|
||||
* either through {@link #builder()} to set up default strategies, or {@link #empty()} to start
|
||||
* from scratch. Alternatively, {@code ExchangeStrategies} instances can be created through
|
||||
* {@link #of(Supplier, Supplier)}.
|
||||
*
|
||||
* @author Brian Clozel
|
||||
|
|
@ -70,8 +70,8 @@ public interface ExchangeStrategies {
|
|||
* Return a new {@code ExchangeStrategies} based on the given
|
||||
* {@linkplain ApplicationContext application context}.
|
||||
* The returned supplier will search for all {@link HttpMessageReader}, and
|
||||
* {@link HttpMessageWriter} instances in the given application context and return them for
|
||||
* {@link #messageReaders()}, and {@link #messageWriters()} respectively.
|
||||
* {@link HttpMessageWriter} instances in the given application context and return
|
||||
* them for {@link #messageReaders()}, and {@link #messageWriters()} respectively.
|
||||
* @param applicationContext the application context to base the strategies on
|
||||
* @return the new {@code ExchangeStrategies}
|
||||
*/
|
||||
|
|
@ -83,8 +83,10 @@ public interface ExchangeStrategies {
|
|||
* Return a new {@code ExchangeStrategies} described by the given supplier functions.
|
||||
* All provided supplier function parameters can be {@code null} to indicate an empty
|
||||
* stream is to be returned.
|
||||
* @param messageReaders the supplier function for {@link HttpMessageReader} instances (can be {@code null})
|
||||
* @param messageWriters the supplier function for {@link HttpMessageWriter} instances (can be {@code null})
|
||||
* @param messageReaders the supplier function for {@link HttpMessageReader} instances
|
||||
* (can be {@code null})
|
||||
* @param messageWriters the supplier function for {@link HttpMessageWriter} instances
|
||||
* (can be {@code null})
|
||||
* @return the new {@code ExchangeStrategies}
|
||||
*/
|
||||
static ExchangeStrategies of(Supplier<Stream<HttpMessageReader<?>>> messageReaders,
|
||||
|
|
@ -156,8 +158,7 @@ public interface ExchangeStrategies {
|
|||
|
||||
/**
|
||||
* Add the given decoder to this builder. This is a convenient alternative to adding a
|
||||
* {@link org.springframework.http.codec.DecoderHttpMessageReader} that wraps the given
|
||||
* decoder.
|
||||
* {@link org.springframework.http.codec.DecoderHttpMessageReader} that wraps the given decoder.
|
||||
* @param decoder the decoder to add
|
||||
* @return this builder
|
||||
*/
|
||||
|
|
@ -172,8 +173,7 @@ public interface ExchangeStrategies {
|
|||
|
||||
/**
|
||||
* Add the given encoder to this builder. This is a convenient alternative to adding a
|
||||
* {@link org.springframework.http.codec.EncoderHttpMessageWriter} that wraps the given
|
||||
* encoder.
|
||||
* {@link org.springframework.http.codec.EncoderHttpMessageWriter} that wraps the given encoder.
|
||||
* @param encoder the encoder to add
|
||||
* @return this builder
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -35,16 +35,13 @@ import org.springframework.web.util.UriBuilder;
|
|||
import org.springframework.web.util.UriBuilderFactory;
|
||||
|
||||
/**
|
||||
* The main class for performing Web requests.
|
||||
* The main entry point for initiating web requests on the client side.
|
||||
*
|
||||
* <pre class="code">
|
||||
*
|
||||
* // Initialize the client
|
||||
*
|
||||
* WebClient client = WebClient.create("http://abc.com");
|
||||
*
|
||||
* // Perform requests...
|
||||
*
|
||||
* Mono<String> result = client.get()
|
||||
* .uri("/foo")
|
||||
* .exchange()
|
||||
|
|
@ -124,12 +121,10 @@ public interface WebClient {
|
|||
* Configure a base URI for requests performed through the client for
|
||||
* example to avoid repeating the same host, port, base path, or even
|
||||
* query parameters with every request.
|
||||
*
|
||||
* <p>For example given this initialization:
|
||||
* <pre class="code">
|
||||
* WebClient client = WebClient.create("http://abc.com/v1");
|
||||
* </pre>
|
||||
*
|
||||
* <p>The base URI is applied to exchanges with a URI template:
|
||||
* <pre class="code">
|
||||
* // GET http://abc.com/v1/accounts/43
|
||||
|
|
@ -138,7 +133,6 @@ public interface WebClient {
|
|||
* .exchange()
|
||||
* .then(response -> response.bodyToMono(Account.class));
|
||||
* </pre>
|
||||
*
|
||||
* <p>The base URI is also applied to exchanges with a {@code UriBuilder}:
|
||||
* <pre class="code">
|
||||
* // GET http://abc.com/v1/accounts?q=12
|
||||
|
|
@ -147,7 +141,6 @@ public interface WebClient {
|
|||
* .exchange()
|
||||
* .then(response -> response.bodyToFlux(Account.class));
|
||||
* </pre>
|
||||
*
|
||||
* <p>The base URI can be overridden with an absolute URI:
|
||||
* <pre class="code">
|
||||
* // GET http://xyz.com/path
|
||||
|
|
@ -156,7 +149,6 @@ public interface WebClient {
|
|||
* .exchange()
|
||||
* .then(response -> response.bodyToMono(Account.class));
|
||||
* </pre>
|
||||
*
|
||||
* <p>The base URI can be partially overridden with a {@code UriBuilder}:
|
||||
* <pre class="code">
|
||||
* // GET http://abc.com/v2/accounts?q=12
|
||||
|
|
@ -165,8 +157,6 @@ public interface WebClient {
|
|||
* .exchange()
|
||||
* .then(response -> response.bodyToFlux(Account.class));
|
||||
* </pre>
|
||||
*
|
||||
*
|
||||
* @param baseUrl the base URI for all requests
|
||||
*/
|
||||
static WebClient create(String baseUrl) {
|
||||
|
|
@ -302,7 +292,6 @@ public interface WebClient {
|
|||
* configured for this client.
|
||||
*/
|
||||
HeaderSpec uri(Function<UriBuilder, URI> uriFunction);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -354,7 +343,6 @@ public interface WebClient {
|
|||
|
||||
/**
|
||||
* Copy the given cookies into the entity's cookies map.
|
||||
*
|
||||
* @param cookies the existing cookies to copy from
|
||||
* @return this builder
|
||||
*/
|
||||
|
|
@ -416,7 +404,6 @@ public interface WebClient {
|
|||
* @return a {@code Mono} with the response
|
||||
*/
|
||||
<T, S extends Publisher<T>> Mono<ClientResponse> exchange(S publisher, Class<T> elementClass);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2017 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.
|
||||
|
|
@ -36,12 +36,13 @@ public class WebClientException extends NestedRuntimeException {
|
|||
}
|
||||
|
||||
/**
|
||||
* Construct a new instance of {@code WebClientException} with the given message and
|
||||
* exception.
|
||||
* Construct a new instance of {@code WebClientException} with the given message
|
||||
* and exception.
|
||||
* @param msg the message
|
||||
* @param ex the exception
|
||||
*/
|
||||
public WebClientException(String msg, Throwable ex) {
|
||||
super(msg, ex);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -53,24 +53,23 @@ class DefaultEntityResponseBuilder<T> implements EntityResponse.Builder<T> {
|
|||
|
||||
private final BodyInserter<T, ? super ServerHttpResponse> inserter;
|
||||
|
||||
private final HttpHeaders headers = new HttpHeaders();
|
||||
private HttpStatus status = HttpStatus.OK;
|
||||
|
||||
private HttpStatus statusCode = HttpStatus.OK;
|
||||
private final HttpHeaders headers = new HttpHeaders();
|
||||
|
||||
private final Map<String, Object> hints = new HashMap<>();
|
||||
|
||||
|
||||
|
||||
public DefaultEntityResponseBuilder(T entity,
|
||||
BodyInserter<T, ? super ServerHttpResponse> inserter) {
|
||||
public DefaultEntityResponseBuilder(T entity, BodyInserter<T, ? super ServerHttpResponse> inserter) {
|
||||
this.entity = entity;
|
||||
this.inserter = inserter;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public EntityResponse.Builder<T> status(HttpStatus status) {
|
||||
Assert.notNull(status, "'status' must not be null");
|
||||
this.statusCode = status;
|
||||
this.status = status;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
|
@ -165,10 +164,11 @@ class DefaultEntityResponseBuilder<T> implements EntityResponse.Builder<T> {
|
|||
|
||||
@Override
|
||||
public Mono<EntityResponse<T>> build() {
|
||||
return Mono.just(new DefaultEntityResponse<T>(this.statusCode, this.headers, this.entity,
|
||||
return Mono.just(new DefaultEntityResponse<T>(this.status, this.headers, this.entity,
|
||||
this.inserter, this.hints));
|
||||
}
|
||||
|
||||
|
||||
private final static class DefaultEntityResponse<T>
|
||||
extends DefaultServerResponseBuilder.AbstractServerResponse
|
||||
implements EntityResponse<T> {
|
||||
|
|
@ -180,10 +180,9 @@ class DefaultEntityResponseBuilder<T> implements EntityResponse.Builder<T> {
|
|||
private final Map<String, Object> hints;
|
||||
|
||||
|
||||
public DefaultEntityResponse(HttpStatus statusCode,
|
||||
HttpHeaders headers, T entity,
|
||||
BodyInserter<T, ? super ServerHttpResponse> inserter,
|
||||
Map<String, Object> hints) {
|
||||
public DefaultEntityResponse(HttpStatus statusCode, HttpHeaders headers, T entity,
|
||||
BodyInserter<T, ? super ServerHttpResponse> inserter, Map<String, Object> hints) {
|
||||
|
||||
super(statusCode, headers);
|
||||
this.entity = entity;
|
||||
this.inserter = inserter;
|
||||
|
|
@ -210,7 +209,6 @@ class DefaultEntityResponseBuilder<T> implements EntityResponse.Builder<T> {
|
|||
public Supplier<Stream<HttpMessageWriter<?>>> messageWriters() {
|
||||
return strategies.messageWriters();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> hints() {
|
||||
return hints;
|
||||
|
|
@ -218,4 +216,5 @@ class DefaultEntityResponseBuilder<T> implements EntityResponse.Builder<T> {
|
|||
});
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -80,6 +80,7 @@ class DefaultHandlerStrategiesBuilder implements HandlerStrategies.Builder {
|
|||
|
||||
private Function<ServerRequest, Optional<Locale>> localeResolver;
|
||||
|
||||
|
||||
public void defaultConfiguration() {
|
||||
messageReader(new DecoderHttpMessageReader<>(new ByteArrayDecoder()));
|
||||
messageReader(new DecoderHttpMessageReader<>(new ByteBufferDecoder()));
|
||||
|
|
@ -149,6 +150,7 @@ class DefaultHandlerStrategiesBuilder implements HandlerStrategies.Builder {
|
|||
this.viewResolvers, localeResolver);
|
||||
}
|
||||
|
||||
|
||||
private static class DefaultHandlerStrategies implements HandlerStrategies {
|
||||
|
||||
private final List<HttpMessageReader<?>> messageReaders;
|
||||
|
|
@ -159,12 +161,12 @@ class DefaultHandlerStrategiesBuilder implements HandlerStrategies.Builder {
|
|||
|
||||
private final Function<ServerRequest, Optional<Locale>> localeResolver;
|
||||
|
||||
|
||||
public DefaultHandlerStrategies(
|
||||
List<HttpMessageReader<?>> messageReaders,
|
||||
List<HttpMessageWriter<?>> messageWriters,
|
||||
List<ViewResolver> viewResolvers,
|
||||
Function<ServerRequest, Optional<Locale>> localeResolver) {
|
||||
|
||||
this.messageReaders = unmodifiableCopy(messageReaders);
|
||||
this.messageWriters = unmodifiableCopy(messageWriters);
|
||||
this.viewResolvers = unmodifiableCopy(viewResolvers);
|
||||
|
|
|
|||
|
|
@ -46,17 +46,25 @@ class DefaultRenderingResponseBuilder implements RenderingResponse.Builder {
|
|||
|
||||
private final String name;
|
||||
|
||||
private HttpStatus status = HttpStatus.OK;
|
||||
|
||||
private final HttpHeaders headers = new HttpHeaders();
|
||||
|
||||
private final Map<String, Object> model = new LinkedHashMap<String, Object>();
|
||||
|
||||
private HttpStatus status = HttpStatus.OK;
|
||||
|
||||
public DefaultRenderingResponseBuilder(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public RenderingResponse.Builder status(HttpStatus status) {
|
||||
Assert.notNull(status, "'status' must not be null");
|
||||
this.status = status;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RenderingResponse.Builder modelAttribute(Object attribute) {
|
||||
Assert.notNull(attribute, "'value' must not be null");
|
||||
|
|
@ -113,20 +121,12 @@ class DefaultRenderingResponseBuilder implements RenderingResponse.Builder {
|
|||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RenderingResponse.Builder status(HttpStatus status) {
|
||||
Assert.notNull(status, "'status' must not be null");
|
||||
this.status = status;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Mono<RenderingResponse> build() {
|
||||
return Mono.just(new DefaultRenderingResponse(this.status, this.headers, this.name,
|
||||
this.model));
|
||||
return Mono.just(new DefaultRenderingResponse(this.status, this.headers, this.name, this.model));
|
||||
}
|
||||
|
||||
|
||||
private final static class DefaultRenderingResponse
|
||||
extends DefaultServerResponseBuilder.AbstractServerResponse
|
||||
implements RenderingResponse {
|
||||
|
|
@ -164,6 +164,7 @@ class DefaultRenderingResponseBuilder implements RenderingResponse.Builder {
|
|||
MediaType contentType = exchange.getResponse().getHeaders().getContentType();
|
||||
Locale locale = resolveLocale(exchange, strategies);
|
||||
Stream<ViewResolver> viewResolverStream = strategies.viewResolvers().get();
|
||||
|
||||
return Flux.fromStream(viewResolverStream)
|
||||
.concatMap(viewResolver -> viewResolver.resolveViewName(this.name, locale))
|
||||
.next()
|
||||
|
|
@ -185,5 +186,4 @@ class DefaultRenderingResponseBuilder implements RenderingResponse.Builder {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -162,6 +162,7 @@ class DefaultServerRequest implements ServerRequest {
|
|||
return String.format("%s %s", method(), path());
|
||||
}
|
||||
|
||||
|
||||
private class DefaultHeaders implements Headers {
|
||||
|
||||
private HttpHeaders delegate() {
|
||||
|
|
|
|||
|
|
@ -170,13 +170,11 @@ class DefaultServerResponseBuilder implements ServerResponse.BodyBuilder {
|
|||
BiFunction<ServerWebExchange, HandlerStrategies, Mono<Void>> writeFunction) {
|
||||
|
||||
Assert.notNull(writeFunction, "'writeFunction' must not be null");
|
||||
return Mono.just(new WriterFunctionServerResponse(this.statusCode, this.headers,
|
||||
writeFunction));
|
||||
return Mono.just(new WriterFunctionServerResponse(this.statusCode, this.headers, writeFunction));
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T, P extends Publisher<T>> Mono<ServerResponse> body(P publisher,
|
||||
Class<T> elementClass) {
|
||||
public <T, P extends Publisher<T>> Mono<ServerResponse> body(P publisher, Class<T> elementClass) {
|
||||
Assert.notNull(publisher, "'publisher' must not be null");
|
||||
Assert.notNull(elementClass, "'elementClass' must not be null");
|
||||
|
||||
|
|
@ -191,9 +189,7 @@ class DefaultServerResponseBuilder implements ServerResponse.BodyBuilder {
|
|||
@Override
|
||||
public <T> Mono<ServerResponse> body(BodyInserter<T, ? super ServerHttpResponse> inserter) {
|
||||
Assert.notNull(inserter, "'inserter' must not be null");
|
||||
return Mono
|
||||
.just(new BodyInserterServerResponse<>(this.statusCode, this.headers, inserter,
|
||||
this.hints));
|
||||
return Mono.just(new BodyInserterServerResponse<>(this.statusCode, this.headers, inserter, this.hints));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -220,6 +216,7 @@ class DefaultServerResponseBuilder implements ServerResponse.BodyBuilder {
|
|||
.map(renderingResponse -> renderingResponse);
|
||||
}
|
||||
|
||||
|
||||
static abstract class AbstractServerResponse implements ServerResponse {
|
||||
|
||||
private final HttpStatus statusCode;
|
||||
|
|
@ -260,13 +257,14 @@ class DefaultServerResponseBuilder implements ServerResponse.BodyBuilder {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
private static final class WriterFunctionServerResponse extends AbstractServerResponse {
|
||||
|
||||
private final BiFunction<ServerWebExchange, HandlerStrategies, Mono<Void>> writeFunction;
|
||||
|
||||
public WriterFunctionServerResponse(HttpStatus statusCode,
|
||||
HttpHeaders headers,
|
||||
public WriterFunctionServerResponse(HttpStatus statusCode, HttpHeaders headers,
|
||||
BiFunction<ServerWebExchange, HandlerStrategies, Mono<Void>> writeFunction) {
|
||||
|
||||
super(statusCode, headers);
|
||||
this.writeFunction = writeFunction;
|
||||
}
|
||||
|
|
@ -279,7 +277,6 @@ class DefaultServerResponseBuilder implements ServerResponse.BodyBuilder {
|
|||
}
|
||||
|
||||
|
||||
|
||||
private static final class BodyInserterServerResponse<T> extends AbstractServerResponse {
|
||||
|
||||
private final BodyInserter<T, ? super ServerHttpResponse> inserter;
|
||||
|
|
|
|||
|
|
@ -52,11 +52,11 @@ public interface EntityResponse<T> extends ServerResponse {
|
|||
*/
|
||||
BodyInserter<T, ? super ServerHttpResponse> inserter();
|
||||
|
||||
|
||||
// Static builder methods
|
||||
|
||||
/**
|
||||
* Create a builder with the given object.
|
||||
*
|
||||
* @param t the object that represents the body of the response
|
||||
* @param <T> the type of the elements contained in the publisher
|
||||
* @return the created builder
|
||||
|
|
@ -67,7 +67,6 @@ public interface EntityResponse<T> extends ServerResponse {
|
|||
|
||||
/**
|
||||
* Create a builder with the given publisher.
|
||||
*
|
||||
* @param publisher the publisher that represents the body of the response
|
||||
* @param elementClass the class of elements contained in the publisher
|
||||
* @param <T> the type of the elements contained in the publisher
|
||||
|
|
@ -81,7 +80,6 @@ public interface EntityResponse<T> extends ServerResponse {
|
|||
|
||||
/**
|
||||
* Create a builder with the given publisher.
|
||||
*
|
||||
* @param publisher the publisher that represents the body of the response
|
||||
* @param elementType the type of elements contained in the publisher
|
||||
* @param <T> the type of the elements contained in the publisher
|
||||
|
|
@ -93,6 +91,7 @@ public interface EntityResponse<T> extends ServerResponse {
|
|||
BodyInserters.fromPublisher(publisher, elementType));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Defines a builder for {@code EntityResponse}.
|
||||
*/
|
||||
|
|
@ -100,7 +99,6 @@ public interface EntityResponse<T> extends ServerResponse {
|
|||
|
||||
/**
|
||||
* Add the given header value(s) under the given name.
|
||||
*
|
||||
* @param headerName the header name
|
||||
* @param headerValues the header value(s)
|
||||
* @return this builder
|
||||
|
|
@ -110,7 +108,6 @@ public interface EntityResponse<T> extends ServerResponse {
|
|||
|
||||
/**
|
||||
* Copy the given headers into the entity's headers map.
|
||||
*
|
||||
* @param headers the existing HttpHeaders to copy from
|
||||
* @return this builder
|
||||
* @see HttpHeaders#add(String, String)
|
||||
|
|
@ -127,7 +124,6 @@ public interface EntityResponse<T> extends ServerResponse {
|
|||
/**
|
||||
* Set the set of allowed {@link HttpMethod HTTP methods}, as specified
|
||||
* by the {@code Allow} header.
|
||||
*
|
||||
* @param allowedMethods the allowed methods
|
||||
* @return this builder
|
||||
* @see HttpHeaders#setAllow(Set)
|
||||
|
|
@ -137,7 +133,6 @@ public interface EntityResponse<T> extends ServerResponse {
|
|||
/**
|
||||
* Set the set of allowed {@link HttpMethod HTTP methods}, as specified
|
||||
* by the {@code Allow} header.
|
||||
*
|
||||
* @param allowedMethods the allowed methods
|
||||
* @return this builder
|
||||
* @see HttpHeaders#setAllow(Set)
|
||||
|
|
@ -146,7 +141,6 @@ public interface EntityResponse<T> extends ServerResponse {
|
|||
|
||||
/**
|
||||
* Set the entity tag of the body, as specified by the {@code ETag} header.
|
||||
*
|
||||
* @param eTag the new entity tag
|
||||
* @return this builder
|
||||
* @see HttpHeaders#setETag(String)
|
||||
|
|
@ -158,7 +152,6 @@ public interface EntityResponse<T> extends ServerResponse {
|
|||
* {@code Last-Modified} header.
|
||||
* <p>The date should be specified as the number of milliseconds since
|
||||
* January 1, 1970 GMT.
|
||||
*
|
||||
* @param lastModified the last modified date
|
||||
* @return this builder
|
||||
* @see HttpHeaders#setLastModified(long)
|
||||
|
|
@ -167,7 +160,6 @@ public interface EntityResponse<T> extends ServerResponse {
|
|||
|
||||
/**
|
||||
* Set the location of a resource, as specified by the {@code Location} header.
|
||||
*
|
||||
* @param location the location
|
||||
* @return this builder
|
||||
* @see HttpHeaders#setLocation(URI)
|
||||
|
|
@ -179,7 +171,6 @@ public interface EntityResponse<T> extends ServerResponse {
|
|||
* {@code Cache-Control} header.
|
||||
* <p>A {@code CacheControl} instance can be built like
|
||||
* {@code CacheControl.maxAge(3600).cachePublic().noTransform()}.
|
||||
*
|
||||
* @param cacheControl a builder for cache-related HTTP response headers
|
||||
* @return this builder
|
||||
* @see <a href="https://tools.ietf.org/html/rfc7234#section-5.2">RFC-7234 Section 5.2</a>
|
||||
|
|
@ -192,7 +183,6 @@ public interface EntityResponse<T> extends ServerResponse {
|
|||
* subject to content negotiation and variances based on the value of the
|
||||
* given request headers. The configured request header names are added only
|
||||
* if not already present in the response "Vary" header.
|
||||
*
|
||||
* @param requestHeaders request header names
|
||||
* @return this builder
|
||||
*/
|
||||
|
|
@ -201,7 +191,6 @@ public interface EntityResponse<T> extends ServerResponse {
|
|||
/**
|
||||
* Set the length of the body in bytes, as specified by the
|
||||
* {@code Content-Length} header.
|
||||
*
|
||||
* @param contentLength the content length
|
||||
* @return this builder
|
||||
* @see HttpHeaders#setContentLength(long)
|
||||
|
|
@ -211,7 +200,6 @@ public interface EntityResponse<T> extends ServerResponse {
|
|||
/**
|
||||
* Set the {@linkplain MediaType media type} of the body, as specified by the
|
||||
* {@code Content-Type} header.
|
||||
*
|
||||
* @param contentType the content type
|
||||
* @return this builder
|
||||
* @see HttpHeaders#setContentType(MediaType)
|
||||
|
|
@ -228,11 +216,9 @@ public interface EntityResponse<T> extends ServerResponse {
|
|||
|
||||
/**
|
||||
* Build the response.
|
||||
*
|
||||
* @return the built response
|
||||
*/
|
||||
Mono<EntityResponse<T>> build();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2017 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.
|
||||
|
|
@ -37,12 +37,11 @@ public interface HandlerFilterFunction<T extends ServerResponse, R extends Serve
|
|||
|
||||
/**
|
||||
* Apply this filter to the given handler function. The given
|
||||
* {@linkplain HandlerFunction handler function} represents the next entity in the
|
||||
* chain, and can be {@linkplain HandlerFunction#handle(ServerRequest) invoked} in order
|
||||
* to proceed to this entity, or not invoked to block the chain.
|
||||
*
|
||||
* {@linkplain HandlerFunction handler function} represents the next entity in the chain,
|
||||
* and can be {@linkplain HandlerFunction#handle(ServerRequest) invoked} in order to
|
||||
* proceed to this entity, or not invoked to block the chain.
|
||||
* @param request the request
|
||||
* @param next the next handler or filter function in the chain
|
||||
* @param next the next handler or filter function in the chain
|
||||
* @return the filtered response
|
||||
* @see ServerRequestWrapper
|
||||
*/
|
||||
|
|
@ -58,8 +57,7 @@ public interface HandlerFilterFunction<T extends ServerResponse, R extends Serve
|
|||
default HandlerFilterFunction<T, R> andThen(HandlerFilterFunction<T, T> after) {
|
||||
Assert.notNull(after, "'after' must not be null");
|
||||
return (request, next) -> {
|
||||
HandlerFunction<T> nextHandler =
|
||||
handlerRequest -> after.filter(handlerRequest, next);
|
||||
HandlerFunction<T> nextHandler = handlerRequest -> after.filter(handlerRequest, next);
|
||||
return filter(request, nextHandler);
|
||||
};
|
||||
}
|
||||
|
|
@ -80,8 +78,8 @@ public interface HandlerFilterFunction<T extends ServerResponse, R extends Serve
|
|||
* @param requestProcessor the request processor
|
||||
* @return the filter adaptation of the request processor
|
||||
*/
|
||||
static HandlerFilterFunction<?, ?> ofRequestProcessor(Function<ServerRequest,
|
||||
Mono<ServerRequest>> requestProcessor) {
|
||||
static HandlerFilterFunction<?, ?> ofRequestProcessor(
|
||||
Function<ServerRequest, Mono<ServerRequest>> requestProcessor) {
|
||||
|
||||
Assert.notNull(requestProcessor, "'requestProcessor' must not be null");
|
||||
return (request, next) -> requestProcessor.apply(request).then(next::handle);
|
||||
|
|
@ -93,8 +91,8 @@ public interface HandlerFilterFunction<T extends ServerResponse, R extends Serve
|
|||
* @param responseProcessor the response processor
|
||||
* @return the filter adaptation of the request processor
|
||||
*/
|
||||
static <T extends ServerResponse, R extends ServerResponse> HandlerFilterFunction<T, R> ofResponseProcessor(Function<T,
|
||||
R> responseProcessor) {
|
||||
static <T extends ServerResponse, R extends ServerResponse> HandlerFilterFunction<T, R> ofResponseProcessor(
|
||||
Function<T, R> responseProcessor) {
|
||||
|
||||
Assert.notNull(responseProcessor, "'responseProcessor' must not be null");
|
||||
return (request, next) -> next.handle(request).map(responseProcessor);
|
||||
|
|
|
|||
|
|
@ -45,11 +45,13 @@ class PathResourceLookupFunction implements Function<ServerRequest, Mono<Resourc
|
|||
|
||||
private final Resource location;
|
||||
|
||||
|
||||
public PathResourceLookupFunction(String pattern, Resource location) {
|
||||
this.pattern = pattern;
|
||||
this.location = location;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Mono<Resource> apply(ServerRequest request) {
|
||||
String path = processPath(request.path());
|
||||
|
|
@ -150,9 +152,7 @@ class PathResourceLookupFunction implements Function<ServerRequest, Mono<Resourc
|
|||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,11 +43,11 @@ public interface RenderingResponse extends ServerResponse {
|
|||
*/
|
||||
Map<String, Object> model();
|
||||
|
||||
|
||||
// Builder
|
||||
|
||||
/**
|
||||
* Create a builder with the given template name.
|
||||
*
|
||||
* @param name the name of the template to render
|
||||
* @return the created builder
|
||||
*/
|
||||
|
|
@ -56,6 +56,7 @@ public interface RenderingResponse extends ServerResponse {
|
|||
return new DefaultRenderingResponseBuilder(name);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Defines a builder for {@code RenderingResponse}.
|
||||
*/
|
||||
|
|
@ -80,15 +81,15 @@ public interface RenderingResponse extends ServerResponse {
|
|||
Builder modelAttribute(String name, Object value);
|
||||
|
||||
/**
|
||||
* Copy all attributes in the supplied array into the model, using attribute
|
||||
* name generation for each element.
|
||||
* Copy all attributes in the supplied array into the model,
|
||||
* using attribute name generation for each element.
|
||||
* @see #modelAttribute(Object)
|
||||
*/
|
||||
Builder modelAttributes(Object... attributes);
|
||||
|
||||
/**
|
||||
* Copy all attributes in the supplied {@code Collection} into the model, using attribute
|
||||
* name generation for each element.
|
||||
* Copy all attributes in the supplied {@code Collection} into the model,
|
||||
* using attribute name generation for each element.
|
||||
* @see #modelAttribute(Object)
|
||||
*/
|
||||
Builder modelAttributes(Collection<?> attributes);
|
||||
|
|
@ -125,12 +126,9 @@ public interface RenderingResponse extends ServerResponse {
|
|||
|
||||
/**
|
||||
* Build the response.
|
||||
*
|
||||
* @return the built response
|
||||
*/
|
||||
Mono<RenderingResponse> build();
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,19 +32,16 @@ import org.springframework.util.Assert;
|
|||
public interface RequestPredicate {
|
||||
|
||||
/**
|
||||
* Evaluates this predicate on the given request.
|
||||
*
|
||||
*
|
||||
* Evaluate this predicate on the given request.
|
||||
* @param request the request to match against
|
||||
* @return {@code true} if the request matches the predicate; {@code false} otherwise
|
||||
*/
|
||||
boolean test(ServerRequest request);
|
||||
|
||||
/**
|
||||
* Returns a composed request predicate that tests against both this predicate AND the {@code other} predicate.
|
||||
* When evaluating the composed predicate, if this predicate is {@code false}, then the {@code other}
|
||||
* predicate is not evaluated.
|
||||
*
|
||||
* Return a composed request predicate that tests against both this predicate AND
|
||||
* the {@code other} predicate. When evaluating the composed predicate, if this
|
||||
* predicate is {@code false}, then the {@code other} predicate is not evaluated.
|
||||
* @param other a predicate that will be logically-ANDed with this predicate
|
||||
* @return a predicate composed of this predicate AND the {@code other} predicate
|
||||
*/
|
||||
|
|
@ -55,12 +52,10 @@ public interface RequestPredicate {
|
|||
public boolean test(ServerRequest t) {
|
||||
return RequestPredicate.this.test(t) && other.test(t);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ServerRequest nestRequest(ServerRequest request) {
|
||||
return other.nestRequest(RequestPredicate.this.nestRequest(request));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("(%s && %s)", RequestPredicate.this, other);
|
||||
|
|
@ -70,7 +65,6 @@ public interface RequestPredicate {
|
|||
|
||||
/**
|
||||
* Return a predicate that represents the logical negation of this predicate.
|
||||
*
|
||||
* @return a predicate that represents the logical negation of this predicate
|
||||
*/
|
||||
default RequestPredicate negate() {
|
||||
|
|
@ -78,9 +72,9 @@ public interface RequestPredicate {
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns a composed request predicate that tests against both this predicate OR the {@code other} predicate.
|
||||
* When evaluating the composed predicate, if this predicate is {@code true}, then the {@code other} predicate
|
||||
* is not evaluated.
|
||||
* Return a composed request predicate that tests against both this predicate OR
|
||||
* the {@code other} predicate. When evaluating the composed predicate, if this
|
||||
* predicate is {@code true}, then the {@code other} predicate is not evaluated.
|
||||
* @param other a predicate that will be logically-ORed with this predicate
|
||||
* @return a predicate composed of this predicate OR the {@code other} predicate
|
||||
*/
|
||||
|
|
@ -91,7 +85,6 @@ public interface RequestPredicate {
|
|||
public boolean test(ServerRequest t) {
|
||||
return RequestPredicate.this.test(t) || other.test(t);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ServerRequest nestRequest(ServerRequest request) {
|
||||
if (RequestPredicate.this.test(request)) {
|
||||
|
|
@ -105,7 +98,6 @@ public interface RequestPredicate {
|
|||
" nor " + other + "matches");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("(%s || %s)", RequestPredicate.this, other);
|
||||
|
|
@ -114,9 +106,9 @@ public interface RequestPredicate {
|
|||
}
|
||||
|
||||
/**
|
||||
* Transforms the given request into a request used for a nested route. For instance, a
|
||||
* path-based predicate can return a {@code ServerRequest} with a nested path.
|
||||
* <p>Default implementation returns the given path.
|
||||
* Transform the given request into a request used for a nested route. For instance,
|
||||
* a path-based predicate can return a {@code ServerRequest} with a nested path.
|
||||
* <p>The default implementation returns the given path.
|
||||
* @param request the request to be nested
|
||||
* @return the nested request
|
||||
* @see RouterFunctions#nest(RequestPredicate, RouterFunction)
|
||||
|
|
@ -124,4 +116,5 @@ public interface RequestPredicate {
|
|||
default ServerRequest nestRequest(ServerRequest request) {
|
||||
return request;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,8 +43,8 @@ import org.springframework.web.util.patterns.PathPattern;
|
|||
import org.springframework.web.util.patterns.PathPatternParser;
|
||||
|
||||
/**
|
||||
* Implementations of {@link RequestPredicate} that implement various useful request matching operations, such as
|
||||
* matching based on path, HTTP method, etc.
|
||||
* Implementations of {@link RequestPredicate} that implement various useful
|
||||
* request matching operations, such as matching based on path, HTTP method, etc.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
* @since 5.0
|
||||
|
|
@ -55,18 +55,18 @@ public abstract class RequestPredicates {
|
|||
|
||||
private static final PathPatternParser DEFAULT_PATTERN_PARSER = new PathPatternParser();
|
||||
|
||||
|
||||
/**
|
||||
* Returns a {@code RequestPredicate} that always matches.
|
||||
*
|
||||
* Return a {@code RequestPredicate} that always matches.
|
||||
* @return a predicate that always matches
|
||||
*/
|
||||
public static RequestPredicate all() {
|
||||
return request -> true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return a {@code RequestPredicate} that tests against the given HTTP method.
|
||||
*
|
||||
* @param httpMethod the HTTP method to match to
|
||||
* @return a predicate that tests against the given HTTP method
|
||||
*/
|
||||
|
|
@ -76,7 +76,6 @@ public abstract class RequestPredicates {
|
|||
|
||||
/**
|
||||
* Return a {@code RequestPredicate} that tests the request path against the given path pattern.
|
||||
*
|
||||
* @param pattern the pattern to match to
|
||||
* @return a predicate that tests against the given path pattern
|
||||
*/
|
||||
|
|
@ -89,7 +88,6 @@ public abstract class RequestPredicates {
|
|||
* Return a function that creates new path-matching {@code RequestPredicates} from pattern
|
||||
* Strings using the given {@link PathPatternParser}. This method can be used to specify a
|
||||
* non-default, customized {@code PathPatternParser} when resolving path patterns.
|
||||
*
|
||||
* @param patternParser the parser used to parse patterns given to the returned function
|
||||
* @return a function that resolves patterns Strings into path-matching
|
||||
* {@code RequestPredicate}s
|
||||
|
|
@ -105,7 +103,6 @@ public abstract class RequestPredicates {
|
|||
|
||||
/**
|
||||
* Return a {@code RequestPredicate} that tests the request's headers against the given headers predicate.
|
||||
*
|
||||
* @param headersPredicate a predicate that tests against the request headers
|
||||
* @return a predicate that tests against the given header predicate
|
||||
*/
|
||||
|
|
@ -115,15 +112,15 @@ public abstract class RequestPredicates {
|
|||
|
||||
/**
|
||||
* Return a {@code RequestPredicate} that tests if the request's
|
||||
* {@linkplain ServerRequest.Headers#contentType() content type} is {@linkplain MediaType#includes(MediaType) included}
|
||||
* by any of the given media types.
|
||||
*
|
||||
* {@linkplain ServerRequest.Headers#contentType() content type} is
|
||||
* {@linkplain MediaType#includes(MediaType) included} by any of the given media types.
|
||||
* @param mediaTypes the media types to match the request's content type against
|
||||
* @return a predicate that tests the request's content type against the given media types
|
||||
*/
|
||||
public static RequestPredicate contentType(MediaType... mediaTypes) {
|
||||
Assert.notEmpty(mediaTypes, "'mediaTypes' must not be empty");
|
||||
Set<MediaType> mediaTypeSet = new HashSet<>(Arrays.asList(mediaTypes));
|
||||
|
||||
return headers(new Predicate<ServerRequest.Headers>() {
|
||||
@Override
|
||||
public boolean test(ServerRequest.Headers headers) {
|
||||
|
|
@ -146,13 +143,13 @@ public abstract class RequestPredicates {
|
|||
* Return a {@code RequestPredicate} that tests if the request's
|
||||
* {@linkplain ServerRequest.Headers#accept() accept} header is
|
||||
* {@linkplain MediaType#isCompatibleWith(MediaType) compatible} with any of the given media types.
|
||||
*
|
||||
* @param mediaTypes the media types to match the request's accept header against
|
||||
* @return a predicate that tests the request's accept header against the given media types
|
||||
*/
|
||||
public static RequestPredicate accept(MediaType... mediaTypes) {
|
||||
Assert.notEmpty(mediaTypes, "'mediaTypes' must not be empty");
|
||||
Set<MediaType> mediaTypeSet = new HashSet<>(Arrays.asList(mediaTypes));
|
||||
|
||||
return headers(new Predicate<ServerRequest.Headers>() {
|
||||
@Override
|
||||
public boolean test(ServerRequest.Headers headers) {
|
||||
|
|
@ -169,94 +166,85 @@ public abstract class RequestPredicates {
|
|||
traceMatch("Accept", mediaTypeSet, acceptedMediaTypes, match);
|
||||
return match;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("Accept: %s", mediaTypeSet);
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a {@code RequestPredicate} that matches if request's HTTP method is {@code GET} and the given
|
||||
* {@code pattern} matches against the request path.
|
||||
*
|
||||
* Return a {@code RequestPredicate} that matches if request's HTTP method is {@code GET}
|
||||
* and the given {@code pattern} matches against the request path.
|
||||
* @param pattern the path pattern to match against
|
||||
* @return a predicate that matches if the request method is GET and if the given pattern matches against the
|
||||
* request path
|
||||
* @return a predicate that matches if the request method is GET and if the given pattern
|
||||
* matches against the request path
|
||||
*/
|
||||
public static RequestPredicate GET(String pattern) {
|
||||
return method(HttpMethod.GET).and(path(pattern));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a {@code RequestPredicate} that matches if request's HTTP method is {@code HEAD} and the given
|
||||
* {@code pattern} matches against the request path.
|
||||
*
|
||||
* Return a {@code RequestPredicate} that matches if request's HTTP method is {@code HEAD}
|
||||
* and the given {@code pattern} matches against the request path.
|
||||
* @param pattern the path pattern to match against
|
||||
* @return a predicate that matches if the request method is HEAD and if the given pattern matches against the
|
||||
* request path
|
||||
* @return a predicate that matches if the request method is HEAD and if the given pattern
|
||||
* matches against the request path
|
||||
*/
|
||||
public static RequestPredicate HEAD(String pattern) {
|
||||
return method(HttpMethod.HEAD).and(path(pattern));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a {@code RequestPredicate} that matches if request's HTTP method is {@code POST} and the given
|
||||
* {@code pattern} matches against the request path.
|
||||
*
|
||||
* Return a {@code RequestPredicate} that matches if request's HTTP method is {@code POST}
|
||||
* and the given {@code pattern} matches against the request path.
|
||||
* @param pattern the path pattern to match against
|
||||
* @return a predicate that matches if the request method is POST and if the given pattern matches against the
|
||||
* request path
|
||||
* @return a predicate that matches if the request method is POST and if the given pattern
|
||||
* matches against the request path
|
||||
*/
|
||||
public static RequestPredicate POST(String pattern) {
|
||||
return method(HttpMethod.POST).and(path(pattern));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a {@code RequestPredicate} that matches if request's HTTP method is {@code PUT} and the given
|
||||
* {@code pattern} matches against the request path.
|
||||
*
|
||||
* Return a {@code RequestPredicate} that matches if request's HTTP method is {@code PUT}
|
||||
* and the given {@code pattern} matches against the request path.
|
||||
* @param pattern the path pattern to match against
|
||||
* @return a predicate that matches if the request method is PUT and if the given pattern matches against the
|
||||
* request path
|
||||
* @return a predicate that matches if the request method is PUT and if the given pattern
|
||||
* matches against the request path
|
||||
*/
|
||||
public static RequestPredicate PUT(String pattern) {
|
||||
return method(HttpMethod.PUT).and(path(pattern));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a {@code RequestPredicate} that matches if request's HTTP method is {@code PATCH} and the given
|
||||
* {@code pattern} matches against the request path.
|
||||
*
|
||||
* Return a {@code RequestPredicate} that matches if request's HTTP method is {@code PATCH}
|
||||
* and the given {@code pattern} matches against the request path.
|
||||
* @param pattern the path pattern to match against
|
||||
* @return a predicate that matches if the request method is PATCH and if the given pattern matches against the
|
||||
* request path
|
||||
* @return a predicate that matches if the request method is PATCH and if the given pattern
|
||||
* matches against the request path
|
||||
*/
|
||||
public static RequestPredicate PATCH(String pattern) {
|
||||
return method(HttpMethod.PATCH).and(path(pattern));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a {@code RequestPredicate} that matches if request's HTTP method is {@code DELETE} and the given
|
||||
* {@code pattern} matches against the request path.
|
||||
*
|
||||
* Return a {@code RequestPredicate} that matches if request's HTTP method is {@code DELETE}
|
||||
* and the given {@code pattern} matches against the request path.
|
||||
* @param pattern the path pattern to match against
|
||||
* @return a predicate that matches if the request method is DELETE and if the given pattern matches against the
|
||||
* request path
|
||||
* @return a predicate that matches if the request method is DELETE and if the given pattern
|
||||
* matches against the request path
|
||||
*/
|
||||
public static RequestPredicate DELETE(String pattern) {
|
||||
return method(HttpMethod.DELETE).and(path(pattern));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a {@code RequestPredicate} that matches if request's HTTP method is {@code OPTIONS} and the given
|
||||
* {@code pattern} matches against the request path.
|
||||
*
|
||||
* Return a {@code RequestPredicate} that matches if request's HTTP method is {@code OPTIONS}
|
||||
* and the given {@code pattern} matches against the request path.
|
||||
* @param pattern the path pattern to match against
|
||||
* @return a predicate that matches if the request method is OPTIONS and if the given pattern matches against the
|
||||
* request path
|
||||
* @return a predicate that matches if the request method is OPTIONS and if the given pattern
|
||||
* matches against the request path
|
||||
*/
|
||||
public static RequestPredicate OPTIONS(String pattern) {
|
||||
return method(HttpMethod.OPTIONS).and(path(pattern));
|
||||
|
|
@ -301,7 +289,6 @@ public abstract class RequestPredicates {
|
|||
*/
|
||||
public static RequestPredicate pathPrefix(String pathPrefixPattern) {
|
||||
Assert.notNull(pathPrefixPattern, "'pathPrefixPattern' must not be null");
|
||||
|
||||
if (!pathPrefixPattern.endsWith("/**")) {
|
||||
pathPrefixPattern += "/**";
|
||||
}
|
||||
|
|
@ -313,8 +300,7 @@ public abstract class RequestPredicates {
|
|||
* against the given predicate.
|
||||
* @param name the name of the query parameter to test against
|
||||
* @param predicate predicate to test against the query parameter value
|
||||
* @return a predicate that matches the given predicate against the query parameter of the given
|
||||
* name
|
||||
* @return a predicate that matches the given predicate against the query parameter of the given name
|
||||
* @see ServerRequest#queryParam(String)
|
||||
*/
|
||||
public static RequestPredicate queryParam(String name, Predicate<String> predicate) {
|
||||
|
|
@ -324,6 +310,7 @@ public abstract class RequestPredicates {
|
|||
};
|
||||
}
|
||||
|
||||
|
||||
private static void traceMatch(String prefix, Object desired, Object actual, boolean match) {
|
||||
if (logger.isTraceEnabled()) {
|
||||
String message = String.format("%s \"%s\" %s against value \"%s\"",
|
||||
|
|
@ -355,6 +342,7 @@ public abstract class RequestPredicates {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
private static class PathPatternPredicate implements RequestPredicate {
|
||||
|
||||
private final PathPattern pattern;
|
||||
|
|
@ -398,6 +386,7 @@ public abstract class RequestPredicates {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
private static class HeadersPredicate implements RequestPredicate {
|
||||
|
||||
private final Predicate<ServerRequest.Headers> headersPredicate;
|
||||
|
|
@ -418,6 +407,7 @@ public abstract class RequestPredicates {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
private static class SubPathServerRequestWrapper implements ServerRequest {
|
||||
|
||||
private final ServerRequest request;
|
||||
|
|
@ -506,8 +496,8 @@ public abstract class RequestPredicates {
|
|||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("%s %s", method(), path());
|
||||
return method() + " " + path();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,17 +40,18 @@ import org.springframework.web.reactive.function.BodyInserters;
|
|||
*/
|
||||
class ResourceHandlerFunction implements HandlerFunction<ServerResponse> {
|
||||
|
||||
|
||||
private static final Set<HttpMethod> SUPPORTED_METHODS =
|
||||
EnumSet.of(HttpMethod.GET, HttpMethod.HEAD, HttpMethod.OPTIONS);
|
||||
|
||||
|
||||
private final Resource resource;
|
||||
|
||||
|
||||
public ResourceHandlerFunction(Resource resource) {
|
||||
this.resource = resource;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Mono<ServerResponse> handle(ServerRequest request) {
|
||||
switch (request.method()) {
|
||||
|
|
@ -72,6 +73,7 @@ class ResourceHandlerFunction implements HandlerFunction<ServerResponse> {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
private static class HeadMethodResource implements Resource {
|
||||
|
||||
private static final byte[] EMPTY = new byte[0];
|
||||
|
|
@ -133,8 +135,6 @@ class ResourceHandlerFunction implements HandlerFunction<ServerResponse> {
|
|||
public String getDescription() {
|
||||
return this.delegate.getDescription();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,8 +37,8 @@ import org.springframework.web.server.adapter.WebHttpHandlerBuilder;
|
|||
/**
|
||||
* <strong>Central entry point to Spring's functional web framework.</strong>
|
||||
* Exposes routing functionality, such as to
|
||||
* {@linkplain #route(RequestPredicate, HandlerFunction) create} a {@code RouterFunction} given a
|
||||
* {@code RequestPredicate} and {@code HandlerFunction}, and to do further
|
||||
* {@linkplain #route(RequestPredicate, HandlerFunction) create} a {@code RouterFunction}
|
||||
* given a {@code RequestPredicate} and {@code HandlerFunction}, and to do further
|
||||
* {@linkplain #nest(RequestPredicate, RouterFunction) subrouting} on an existing routing
|
||||
* function.
|
||||
*
|
||||
|
|
@ -77,10 +77,8 @@ public abstract class RouterFunctions {
|
|||
* {@code listUsers} method in {@code userController}:
|
||||
* <pre class="code">
|
||||
* RouterFunction<ServerResponse> route =
|
||||
* RouterFunctions.route(RequestPredicates.GET("/user"),
|
||||
* userController::listUsers);
|
||||
* RouterFunctions.route(RequestPredicates.GET("/user"), userController::listUsers);
|
||||
* </pre>
|
||||
*
|
||||
* @param predicate the predicate to test
|
||||
* @param handlerFunction the handler function to route to if the predicate applies
|
||||
* @param <T> the type of response returned by the handler function
|
||||
|
|
@ -166,7 +164,6 @@ public abstract class RouterFunctions {
|
|||
public static RouterFunction<ServerResponse> resources(String pattern, Resource location) {
|
||||
Assert.hasLength(pattern, "'pattern' must not be empty");
|
||||
Assert.notNull(location, "'location' must not be null");
|
||||
|
||||
return resources(new PathResourceLookupFunction(pattern, location));
|
||||
}
|
||||
|
||||
|
|
@ -179,7 +176,6 @@ public abstract class RouterFunctions {
|
|||
*/
|
||||
public static RouterFunction<ServerResponse> resources(Function<ServerRequest, Mono<Resource>> lookupFunction) {
|
||||
Assert.notNull(lookupFunction, "'lookupFunction' must not be null");
|
||||
|
||||
return request -> lookupFunction.apply(request).map(ResourceHandlerFunction::new);
|
||||
}
|
||||
|
||||
|
|
@ -270,13 +266,10 @@ public abstract class RouterFunctions {
|
|||
Assert.notNull(routerFunction, "RouterFunction must not be null");
|
||||
Assert.notNull(strategies, "HandlerStrategies must not be null");
|
||||
|
||||
return new HandlerMapping() {
|
||||
@Override
|
||||
public Mono<Object> getHandler(ServerWebExchange exchange) {
|
||||
ServerRequest request = new DefaultServerRequest(exchange, strategies);
|
||||
addAttributes(exchange, request);
|
||||
return routerFunction.route(request).map(handlerFunction -> (Object)handlerFunction);
|
||||
}
|
||||
return exchange -> {
|
||||
ServerRequest request = new DefaultServerRequest(exchange, strategies);
|
||||
addAttributes(exchange, request);
|
||||
return routerFunction.route(request).map(handlerFunction -> (Object)handlerFunction);
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -126,12 +126,12 @@ public interface ServerRequest {
|
|||
*/
|
||||
default Optional<String> queryParam(String name) {
|
||||
List<String> queryParams = this.queryParams(name);
|
||||
return !queryParams.isEmpty() ? Optional.of(queryParams.get(0)) : Optional.empty();
|
||||
return (!queryParams.isEmpty() ? Optional.of(queryParams.get(0)) : Optional.empty());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return all query parameter with the given name. Returns an empty list if no values could
|
||||
* be found.
|
||||
* Return all query parameter with the given name.
|
||||
* <p>Returns an empty list if no values could be found.
|
||||
* @param name the parameter name
|
||||
* @return the parameter values
|
||||
*/
|
||||
|
|
@ -149,8 +149,7 @@ public interface ServerRequest {
|
|||
return pathVariables().get(name);
|
||||
}
|
||||
else {
|
||||
throw new IllegalArgumentException(
|
||||
"No path variable with name \"" + name + "\" available");
|
||||
throw new IllegalArgumentException("No path variable with name \"" + name + "\" available");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -223,7 +222,6 @@ public interface ServerRequest {
|
|||
/**
|
||||
* Return the header value(s), if any, for the header of the given name.
|
||||
* <p>Return an empty list if no header values are found.
|
||||
*
|
||||
* @param headerName the header name
|
||||
*/
|
||||
List<String> header(String headerName);
|
||||
|
|
@ -232,7 +230,6 @@ public interface ServerRequest {
|
|||
* Return the headers as a {@link HttpHeaders} instance.
|
||||
*/
|
||||
HttpHeaders asHttpHeaders();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,8 +39,9 @@ import org.springframework.web.reactive.function.BodyInserters;
|
|||
import org.springframework.web.server.ServerWebExchange;
|
||||
|
||||
/**
|
||||
* Represents a typed, server-side HTTP response, as returned by a
|
||||
* {@linkplain HandlerFunction handler function} or {@linkplain HandlerFilterFunction filter function}.
|
||||
* Represents a typed server-side HTTP response, as returned
|
||||
* by a {@linkplain HandlerFunction handler function} or
|
||||
* {@linkplain HandlerFilterFunction filter function}.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
* @author Sebastien Deleuze
|
||||
|
|
@ -61,19 +62,18 @@ public interface ServerResponse {
|
|||
HttpHeaders headers();
|
||||
|
||||
/**
|
||||
* Writes this response to the given web exchange.
|
||||
*
|
||||
* Write this response to the given web exchange.
|
||||
* @param exchange the web exchange to write to
|
||||
* @param strategies the strategies to use when writing
|
||||
* @return {@code Mono<Void>} to indicate when writing is complete
|
||||
*/
|
||||
Mono<Void> writeTo(ServerWebExchange exchange, HandlerStrategies strategies);
|
||||
|
||||
|
||||
// Static builder methods
|
||||
|
||||
/**
|
||||
* Create a builder with the status code and headers of the given response.
|
||||
*
|
||||
* @param other the response to copy the status and headers from
|
||||
* @return the created builder
|
||||
*/
|
||||
|
|
@ -85,7 +85,6 @@ public interface ServerResponse {
|
|||
|
||||
/**
|
||||
* Create a builder with the given status.
|
||||
*
|
||||
* @param status the response status
|
||||
* @return the created builder
|
||||
*/
|
||||
|
|
@ -96,7 +95,6 @@ public interface ServerResponse {
|
|||
|
||||
/**
|
||||
* Create a builder with the status set to {@linkplain HttpStatus#OK OK}.
|
||||
*
|
||||
* @return the created builder
|
||||
*/
|
||||
static BodyBuilder ok() {
|
||||
|
|
@ -106,7 +104,6 @@ public interface ServerResponse {
|
|||
/**
|
||||
* Create a new builder with a {@linkplain HttpStatus#CREATED CREATED} status
|
||||
* and a location header set to the given URI.
|
||||
*
|
||||
* @param location the location URI
|
||||
* @return the created builder
|
||||
*/
|
||||
|
|
@ -117,7 +114,6 @@ public interface ServerResponse {
|
|||
|
||||
/**
|
||||
* Create a builder with an {@linkplain HttpStatus#ACCEPTED ACCEPTED} status.
|
||||
*
|
||||
* @return the created builder
|
||||
*/
|
||||
static BodyBuilder accepted() {
|
||||
|
|
@ -126,7 +122,6 @@ public interface ServerResponse {
|
|||
|
||||
/**
|
||||
* Create a builder with a {@linkplain HttpStatus#NO_CONTENT NO_CONTENT} status.
|
||||
*
|
||||
* @return the created builder
|
||||
*/
|
||||
static HeadersBuilder<?> noContent() {
|
||||
|
|
@ -135,7 +130,6 @@ public interface ServerResponse {
|
|||
|
||||
/**
|
||||
* Create a builder with a {@linkplain HttpStatus#BAD_REQUEST BAD_REQUEST} status.
|
||||
*
|
||||
* @return the created builder
|
||||
*/
|
||||
static BodyBuilder badRequest() {
|
||||
|
|
@ -154,7 +148,6 @@ public interface ServerResponse {
|
|||
/**
|
||||
* Create a builder with an
|
||||
* {@linkplain HttpStatus#UNPROCESSABLE_ENTITY UNPROCESSABLE_ENTITY} status.
|
||||
*
|
||||
* @return the created builder
|
||||
*/
|
||||
static BodyBuilder unprocessableEntity() {
|
||||
|
|
@ -164,14 +157,12 @@ public interface ServerResponse {
|
|||
|
||||
/**
|
||||
* Defines a builder that adds headers to the response.
|
||||
*
|
||||
* @param <B> the builder subclass
|
||||
*/
|
||||
interface HeadersBuilder<B extends HeadersBuilder<B>> {
|
||||
|
||||
/**
|
||||
* Add the given header value(s) under the given name.
|
||||
*
|
||||
* @param headerName the header name
|
||||
* @param headerValues the header value(s)
|
||||
* @return this builder
|
||||
|
|
@ -181,7 +172,6 @@ public interface ServerResponse {
|
|||
|
||||
/**
|
||||
* Copy the given headers into the entity's headers map.
|
||||
*
|
||||
* @param headers the existing HttpHeaders to copy from
|
||||
* @return this builder
|
||||
* @see HttpHeaders#add(String, String)
|
||||
|
|
@ -201,7 +191,6 @@ public interface ServerResponse {
|
|||
/**
|
||||
* Set the set of allowed {@link HttpMethod HTTP methods}, as specified
|
||||
* by the {@code Allow} header.
|
||||
*
|
||||
* @param allowedMethods the allowed methods
|
||||
* @return this builder
|
||||
* @see HttpHeaders#setAllow(Set)
|
||||
|
|
@ -210,7 +199,6 @@ public interface ServerResponse {
|
|||
|
||||
/**
|
||||
* Set the entity tag of the body, as specified by the {@code ETag} header.
|
||||
*
|
||||
* @param eTag the new entity tag
|
||||
* @return this builder
|
||||
* @see HttpHeaders#setETag(String)
|
||||
|
|
@ -222,7 +210,6 @@ public interface ServerResponse {
|
|||
* {@code Last-Modified} header.
|
||||
* <p>The date should be specified as the number of milliseconds since
|
||||
* January 1, 1970 GMT.
|
||||
*
|
||||
* @param lastModified the last modified date
|
||||
* @return this builder
|
||||
* @see HttpHeaders#setLastModified(long)
|
||||
|
|
@ -231,7 +218,6 @@ public interface ServerResponse {
|
|||
|
||||
/**
|
||||
* Set the location of a resource, as specified by the {@code Location} header.
|
||||
*
|
||||
* @param location the location
|
||||
* @return this builder
|
||||
* @see HttpHeaders#setLocation(URI)
|
||||
|
|
@ -243,7 +229,6 @@ public interface ServerResponse {
|
|||
* {@code Cache-Control} header.
|
||||
* <p>A {@code CacheControl} instance can be built like
|
||||
* {@code CacheControl.maxAge(3600).cachePublic().noTransform()}.
|
||||
*
|
||||
* @param cacheControl a builder for cache-related HTTP response headers
|
||||
* @return this builder
|
||||
* @see <a href="https://tools.ietf.org/html/rfc7234#section-5.2">RFC-7234 Section 5.2</a>
|
||||
|
|
@ -256,7 +241,6 @@ public interface ServerResponse {
|
|||
* subject to content negotiation and variances based on the value of the
|
||||
* given request headers. The configured request header names are added only
|
||||
* if not already present in the response "Vary" header.
|
||||
*
|
||||
* @param requestHeaders request header names
|
||||
* @return this builder
|
||||
*/
|
||||
|
|
@ -264,7 +248,6 @@ public interface ServerResponse {
|
|||
|
||||
/**
|
||||
* Build the response entity with no body.
|
||||
*
|
||||
* @return the built response
|
||||
*/
|
||||
Mono<ServerResponse> build();
|
||||
|
|
@ -272,7 +255,6 @@ public interface ServerResponse {
|
|||
/**
|
||||
* Build the response entity with no body.
|
||||
* The response will be committed when the given {@code voidPublisher} completes.
|
||||
*
|
||||
* @param voidPublisher publisher publisher to indicate when the response should be committed
|
||||
* @return the built response
|
||||
*/
|
||||
|
|
@ -280,12 +262,10 @@ public interface ServerResponse {
|
|||
|
||||
/**
|
||||
* Build the response entity with a custom writer function.
|
||||
*
|
||||
* @param writeFunction the function used to write to the {@link ServerWebExchange}
|
||||
* @return the built response
|
||||
*/
|
||||
Mono<ServerResponse> build(BiFunction<ServerWebExchange, HandlerStrategies,
|
||||
Mono<Void>> writeFunction);
|
||||
Mono<ServerResponse> build(BiFunction<ServerWebExchange, HandlerStrategies, Mono<Void>> writeFunction);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -313,16 +293,16 @@ public interface ServerResponse {
|
|||
BodyBuilder contentType(MediaType contentType);
|
||||
|
||||
/**
|
||||
* Add a serialization hint like {@link AbstractJackson2Codec#JSON_VIEW_HINT} to
|
||||
* customize how the body will be serialized.
|
||||
* Add a serialization hint like {@link AbstractJackson2Codec#JSON_VIEW_HINT}
|
||||
* to customize how the body will be serialized.
|
||||
* @param key the hint key
|
||||
* @param value the hint value
|
||||
*/
|
||||
BodyBuilder hint(String key, Object value);
|
||||
|
||||
/**
|
||||
* Set the body of the response to the given {@code Publisher} and return it. This
|
||||
* convenience method combines {@link #body(BodyInserter)} and
|
||||
* Set the body of the response to the given {@code Publisher} and return it.
|
||||
* This convenience method combines {@link #body(BodyInserter)} and
|
||||
* {@link BodyInserters#fromPublisher(Publisher, Class)}.
|
||||
* @param publisher the {@code Publisher} to write to the response
|
||||
* @param elementClass the class of elements contained in the publisher
|
||||
|
|
|
|||
|
|
@ -49,9 +49,8 @@ import org.springframework.http.server.reactive.ServerHttpRequest;
|
|||
import org.springframework.mock.http.server.reactive.test.MockServerHttpRequest;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.springframework.http.codec.json.AbstractJackson2Codec.JSON_VIEW_HINT;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.springframework.http.codec.json.AbstractJackson2Codec.*;
|
||||
|
||||
/**
|
||||
* @author Arjen Poutsma
|
||||
|
|
@ -63,6 +62,7 @@ public class BodyExtractorsTests {
|
|||
|
||||
private Map<String, Object> hints;
|
||||
|
||||
|
||||
@Before
|
||||
public void createContext() {
|
||||
final List<HttpMessageReader<?>> messageReaders = new ArrayList<>();
|
||||
|
|
@ -85,6 +85,7 @@ public class BodyExtractorsTests {
|
|||
this.hints = new HashMap<String, Object>();
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void toMono() throws Exception {
|
||||
BodyExtractor<Mono<String>, ReactiveHttpInputMessage> extractor = BodyExtractors.toMono(String.class);
|
||||
|
|
@ -232,7 +233,6 @@ public class BodyExtractorsTests {
|
|||
})
|
||||
.expectComplete()
|
||||
.verify();
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -256,6 +256,7 @@ public class BodyExtractorsTests {
|
|||
|
||||
interface SafeToDeserialize {}
|
||||
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static class User {
|
||||
|
||||
|
|
@ -289,4 +290,4 @@ public class BodyExtractorsTests {
|
|||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -59,9 +59,9 @@ import org.springframework.mock.http.server.reactive.test.MockServerHttpResponse
|
|||
import org.springframework.util.LinkedMultiValueMap;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
import static org.junit.Assert.assertArrayEquals;
|
||||
import static org.springframework.http.codec.json.AbstractJackson2Codec.JSON_VIEW_HINT;
|
||||
import static java.nio.charset.StandardCharsets.*;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.springframework.http.codec.json.AbstractJackson2Codec.*;
|
||||
|
||||
/**
|
||||
* @author Arjen Poutsma
|
||||
|
|
@ -73,6 +73,7 @@ public class BodyInsertersTests {
|
|||
|
||||
private Map<String, Object> hints;
|
||||
|
||||
|
||||
@Before
|
||||
public void createContext() {
|
||||
final List<HttpMessageWriter<?>> messageWriters = new ArrayList<>();
|
||||
|
|
@ -96,9 +97,10 @@ public class BodyInsertersTests {
|
|||
return hints;
|
||||
}
|
||||
};
|
||||
this.hints = new HashMap();
|
||||
this.hints = new HashMap<>();
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void ofString() throws Exception {
|
||||
String body = "foo";
|
||||
|
|
@ -255,6 +257,7 @@ public class BodyInsertersTests {
|
|||
|
||||
interface SafeToSerialize {}
|
||||
|
||||
|
||||
private static class User {
|
||||
|
||||
@JsonView(SafeToSerialize.class)
|
||||
|
|
@ -287,5 +290,4 @@ public class BodyInsertersTests {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,14 +34,10 @@ import org.springframework.http.codec.HttpMessageWriter;
|
|||
import org.springframework.mock.http.client.reactive.test.MockClientHttpRequest;
|
||||
import org.springframework.web.reactive.function.BodyInserter;
|
||||
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.springframework.http.HttpMethod.DELETE;
|
||||
import static org.springframework.http.HttpMethod.GET;
|
||||
import static org.springframework.http.HttpMethod.POST;
|
||||
import static java.nio.charset.StandardCharsets.*;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
import static org.springframework.http.HttpMethod.*;
|
||||
|
||||
/**
|
||||
* @author Arjen Poutsma
|
||||
|
|
|
|||
|
|
@ -46,11 +46,9 @@ import org.springframework.http.codec.HttpMessageReader;
|
|||
import org.springframework.util.LinkedMultiValueMap;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertSame;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.springframework.web.reactive.function.BodyExtractors.toMono;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
import static org.springframework.web.reactive.function.BodyExtractors.*;
|
||||
|
||||
/**
|
||||
* @author Arjen Poutsma
|
||||
|
|
@ -68,10 +66,10 @@ public class DefaultClientResponseTests {
|
|||
public void createMocks() {
|
||||
mockResponse = mock(ClientHttpResponse.class);
|
||||
mockExchangeStrategies = mock(ExchangeStrategies.class);
|
||||
|
||||
defaultClientResponse = new DefaultClientResponse(mockResponse, mockExchangeStrategies);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void statusCode() throws Exception {
|
||||
HttpStatus status = HttpStatus.CONTINUE;
|
||||
|
|
@ -210,5 +208,4 @@ public class DefaultClientResponseTests {
|
|||
.verify();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,10 +29,8 @@ import reactor.core.publisher.Mono;
|
|||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.MediaType;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verifyNoMoreInteractions;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link DefaultWebClient}.
|
||||
|
|
|
|||
|
|
@ -23,11 +23,9 @@ import reactor.core.publisher.Mono;
|
|||
|
||||
import org.springframework.http.HttpHeaders;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.springframework.http.HttpMethod.GET;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
import static org.springframework.http.HttpMethod.*;
|
||||
|
||||
/**
|
||||
* @author Arjen Poutsma
|
||||
|
|
@ -100,4 +98,4 @@ public class ExchangeFilterFunctionsTests {
|
|||
assertEquals(response, result);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,8 +36,7 @@ import org.springframework.http.ReactiveHttpOutputMessage;
|
|||
import org.springframework.http.codec.HttpMessageReader;
|
||||
import org.springframework.http.codec.HttpMessageWriter;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* @author Arjen Poutsma
|
||||
|
|
@ -104,6 +103,7 @@ public class ExchangeStrategiesTests {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
private static class DummyMessageReader implements HttpMessageReader<Object> {
|
||||
|
||||
@Override
|
||||
|
|
@ -128,5 +128,5 @@ public class ExchangeStrategiesTests {
|
|||
return Mono.empty();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,9 +35,8 @@ import org.springframework.http.HttpStatus;
|
|||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.codec.Pojo;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.springframework.web.reactive.function.BodyInserters.fromObject;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.springframework.web.reactive.function.BodyInserters.*;
|
||||
|
||||
/**
|
||||
* Integration tests using a {@link ExchangeFunction} through {@link WebClient}.
|
||||
|
|
@ -269,7 +268,6 @@ public class WebClientIntegrationTests {
|
|||
RecordedRequest recordedRequest = server.takeRequest();
|
||||
Assert.assertEquals(1, server.getRequestCount());
|
||||
Assert.assertEquals("bar", recordedRequest.getHeader("foo"));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -295,7 +293,6 @@ public class WebClientIntegrationTests {
|
|||
RecordedRequest recordedRequest = server.takeRequest();
|
||||
Assert.assertEquals(1, server.getRequestCount());
|
||||
Assert.assertEquals("bar", recordedRequest.getHeader("foo"));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2017 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.
|
||||
|
|
@ -22,8 +22,7 @@ import org.springframework.http.server.reactive.HttpHandler;
|
|||
/**
|
||||
* @author Arjen Poutsma
|
||||
*/
|
||||
public abstract class AbstractRouterFunctionIntegrationTests
|
||||
extends AbstractHttpHandlerIntegrationTests {
|
||||
public abstract class AbstractRouterFunctionIntegrationTests extends AbstractHttpHandlerIntegrationTests {
|
||||
|
||||
@Override
|
||||
protected final HttpHandler createHttpHandler() {
|
||||
|
|
@ -32,4 +31,5 @@ public abstract class AbstractRouterFunctionIntegrationTests
|
|||
}
|
||||
|
||||
protected abstract RouterFunction<?> routerFunction();
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -48,9 +48,8 @@ import org.springframework.web.server.ServerWebExchange;
|
|||
import org.springframework.web.server.adapter.DefaultServerWebExchange;
|
||||
import org.springframework.web.server.session.MockWebSessionManager;
|
||||
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertSame;
|
||||
import static java.nio.charset.StandardCharsets.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* @author Arjen Poutsma
|
||||
|
|
@ -122,7 +121,7 @@ public class DefaultEntityResponseBuilderTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void eTag() throws Exception {
|
||||
public void etag() throws Exception {
|
||||
String body = "foo";
|
||||
Mono<EntityResponse<String>> result = EntityResponse.fromObject(body).eTag("foo").build();
|
||||
StepVerifier.create(result)
|
||||
|
|
@ -213,4 +212,4 @@ public class DefaultEntityResponseBuilderTests {
|
|||
assertNotNull(mockResponse.getBody());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,8 +36,7 @@ import org.springframework.web.server.ServerWebExchange;
|
|||
import org.springframework.web.server.adapter.DefaultServerWebExchange;
|
||||
import org.springframework.web.server.session.MockWebSessionManager;
|
||||
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
/**
|
||||
* @author Arjen Poutsma
|
||||
|
|
@ -134,4 +133,4 @@ public class DefaultRenderingResponseTests {
|
|||
.verify();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -52,10 +52,9 @@ import org.springframework.web.server.ServerWebExchange;
|
|||
import org.springframework.web.server.UnsupportedMediaTypeStatusException;
|
||||
import org.springframework.web.server.WebSession;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.springframework.web.reactive.function.BodyExtractors.toMono;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
import static org.springframework.web.reactive.function.BodyExtractors.*;
|
||||
|
||||
/**
|
||||
* @author Arjen Poutsma
|
||||
|
|
@ -72,6 +71,7 @@ public class DefaultServerRequestTests {
|
|||
|
||||
private DefaultServerRequest defaultRequest;
|
||||
|
||||
|
||||
@Before
|
||||
public void createMocks() {
|
||||
mockRequest = mock(ServerHttpRequest.class);
|
||||
|
|
@ -85,6 +85,7 @@ public class DefaultServerRequestTests {
|
|||
defaultRequest = new DefaultServerRequest(mockExchange, mockHandlerStrategies);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void method() throws Exception {
|
||||
HttpMethod method = HttpMethod.HEAD;
|
||||
|
|
@ -258,4 +259,4 @@ public class DefaultServerRequestTests {
|
|||
.verify();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,9 +35,8 @@ import org.springframework.http.MediaType;
|
|||
import org.springframework.mock.http.server.reactive.test.MockServerHttpResponse;
|
||||
import org.springframework.web.server.ServerWebExchange;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
/**
|
||||
* @author Arjen Poutsma
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2017 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.
|
||||
|
|
@ -23,7 +23,6 @@ import java.util.function.Function;
|
|||
import java.util.function.Supplier;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
|
@ -50,26 +49,22 @@ import org.springframework.web.reactive.function.server.support.ServerResponseRe
|
|||
import org.springframework.web.reactive.result.view.ViewResolver;
|
||||
import org.springframework.web.server.adapter.WebHttpHandlerBuilder;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.springframework.web.reactive.function.BodyInserters.fromObject;
|
||||
import static org.springframework.web.reactive.function.BodyInserters.fromPublisher;
|
||||
import static org.springframework.web.reactive.function.server.RouterFunctions.route;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.springframework.web.reactive.function.BodyInserters.*;
|
||||
import static org.springframework.web.reactive.function.server.RouterFunctions.*;
|
||||
|
||||
/**
|
||||
* Tests the use of {@link HandlerFunction} and {@link RouterFunction} in a
|
||||
* {@link DispatcherHandler}.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
*/
|
||||
public class DispatcherHandlerIntegrationTests extends AbstractHttpHandlerIntegrationTests {
|
||||
|
||||
|
||||
private final RestTemplate restTemplate = new RestTemplate();
|
||||
|
||||
private AnnotationConfigApplicationContext wac;
|
||||
|
||||
private RestTemplate restTemplate;
|
||||
|
||||
@Before
|
||||
public void createRestTemplate() {
|
||||
this.restTemplate = new RestTemplate();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected HttpHandler createHttpHandler() {
|
||||
|
|
@ -83,6 +78,7 @@ public class DispatcherHandlerIntegrationTests extends AbstractHttpHandlerIntegr
|
|||
return WebHttpHandlerBuilder.webHandler(webHandler).build();
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void mono() throws Exception {
|
||||
ResponseEntity<Person> result =
|
||||
|
|
@ -160,6 +156,7 @@ public class DispatcherHandlerIntegrationTests extends AbstractHttpHandlerIntegr
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
private static class PersonHandler {
|
||||
|
||||
public Mono<ServerResponse> mono(ServerRequest request) {
|
||||
|
|
@ -220,11 +217,8 @@ public class DispatcherHandlerIntegrationTests extends AbstractHttpHandlerIntegr
|
|||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Person{" +
|
||||
"name='" + this.name + '\'' +
|
||||
'}';
|
||||
return "Person{" + "name='" + this.name + '\'' + '}';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,8 +34,7 @@ import org.springframework.http.ReactiveHttpOutputMessage;
|
|||
import org.springframework.http.codec.HttpMessageReader;
|
||||
import org.springframework.http.codec.HttpMessageWriter;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* @author Arjen Poutsma
|
||||
|
|
@ -106,6 +105,7 @@ public class HandlerStrategiesTests {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
private static class DummyMessageReader implements HttpMessageReader<Object> {
|
||||
|
||||
@Override
|
||||
|
|
@ -130,5 +130,6 @@ public class HandlerStrategiesTests {
|
|||
return Mono.empty();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2017 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.
|
||||
|
|
@ -32,14 +32,13 @@ import org.springframework.http.HttpRange;
|
|||
import org.springframework.http.MediaType;
|
||||
import org.springframework.web.reactive.function.server.support.ServerRequestWrapper;
|
||||
|
||||
import static org.junit.Assert.assertSame;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
/**
|
||||
* @author Arjen Poutsma
|
||||
*/
|
||||
public class HeadersWrapperTest {
|
||||
public class HeadersWrapperTests {
|
||||
|
||||
private ServerRequest.Headers mockHeaders;
|
||||
|
||||
|
|
@ -52,6 +51,7 @@ public class HeadersWrapperTest {
|
|||
wrapper = new ServerRequestWrapper.HeadersWrapper(mockHeaders);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void accept() throws Exception {
|
||||
List<MediaType> accept = Collections.singletonList(MediaType.APPLICATION_JSON);
|
||||
|
|
@ -117,4 +117,4 @@ public class HeadersWrapperTest {
|
|||
assertSame(httpHeaders, wrapper.asHttpHeaders());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -66,10 +66,12 @@ public class MockServerRequest implements ServerRequest {
|
|||
|
||||
private final WebSession session;
|
||||
|
||||
|
||||
private MockServerRequest(HttpMethod method, URI uri,
|
||||
MockHeaders headers, Object body, Map<String, Object> attributes,
|
||||
MultiValueMap<String, String> queryParams,
|
||||
Map<String, String> pathVariables, WebSession session) {
|
||||
|
||||
this.method = method;
|
||||
this.uri = uri;
|
||||
this.headers = headers;
|
||||
|
|
@ -80,9 +82,6 @@ public class MockServerRequest implements ServerRequest {
|
|||
this.session = session;
|
||||
}
|
||||
|
||||
public static Builder builder() {
|
||||
return new BuilderImpl();
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpMethod method() {
|
||||
|
|
@ -148,6 +147,12 @@ public class MockServerRequest implements ServerRequest {
|
|||
return Mono.justOrEmpty(this.session);
|
||||
}
|
||||
|
||||
|
||||
public static Builder builder() {
|
||||
return new BuilderImpl();
|
||||
}
|
||||
|
||||
|
||||
public interface Builder {
|
||||
|
||||
Builder method(HttpMethod method);
|
||||
|
|
@ -175,9 +180,9 @@ public class MockServerRequest implements ServerRequest {
|
|||
MockServerRequest body(Object body);
|
||||
|
||||
MockServerRequest build();
|
||||
|
||||
}
|
||||
|
||||
|
||||
private static class BuilderImpl implements Builder {
|
||||
|
||||
private HttpMethod method = HttpMethod.GET;
|
||||
|
|
@ -289,14 +294,13 @@ public class MockServerRequest implements ServerRequest {
|
|||
return new MockServerRequest(this.method, this.uri, this.headers, null,
|
||||
this.attributes, this.queryParams, this.pathVariables, this.session);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
private static class MockHeaders implements Headers {
|
||||
|
||||
private final HttpHeaders headers;
|
||||
|
||||
|
||||
public MockHeaders(HttpHeaders headers) {
|
||||
this.headers = headers;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,6 @@
|
|||
|
||||
package org.springframework.web.reactive.function.server;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
|
@ -25,25 +24,18 @@ import org.springframework.http.HttpStatus;
|
|||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.springframework.web.reactive.function.BodyInserters.fromObject;
|
||||
import static org.springframework.web.reactive.function.server.RequestPredicates.GET;
|
||||
import static org.springframework.web.reactive.function.server.RequestPredicates.pathPrefix;
|
||||
import static org.springframework.web.reactive.function.server.RouterFunctions.nest;
|
||||
import static org.springframework.web.reactive.function.server.RouterFunctions.route;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.springframework.web.reactive.function.BodyInserters.*;
|
||||
import static org.springframework.web.reactive.function.server.RequestPredicates.*;
|
||||
import static org.springframework.web.reactive.function.server.RouterFunctions.*;
|
||||
|
||||
/**
|
||||
* @author Arjen Poutsma
|
||||
*/
|
||||
public class NestedRouteIntegrationTests
|
||||
extends AbstractRouterFunctionIntegrationTests {
|
||||
public class NestedRouteIntegrationTests extends AbstractRouterFunctionIntegrationTests {
|
||||
|
||||
private RestTemplate restTemplate;
|
||||
private final RestTemplate restTemplate = new RestTemplate();
|
||||
|
||||
@Before
|
||||
public void createRestTemplate() {
|
||||
this.restTemplate = new RestTemplate();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected RouterFunction<?> routerFunction() {
|
||||
|
|
@ -73,6 +65,7 @@ public class NestedRouteIntegrationTests
|
|||
assertEquals("baz", result.getBody());
|
||||
}
|
||||
|
||||
|
||||
private static class NestedHandler {
|
||||
|
||||
public Mono<ServerResponse> bar(ServerRequest request) {
|
||||
|
|
@ -82,7 +75,6 @@ public class NestedRouteIntegrationTests
|
|||
public Mono<ServerResponse> baz(ServerRequest request) {
|
||||
return ServerResponse.ok().body(fromObject("baz"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2017 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.
|
||||
|
|
@ -19,7 +19,6 @@ package org.springframework.web.reactive.function.server;
|
|||
import java.net.URI;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
|
@ -31,25 +30,19 @@ import org.springframework.http.RequestEntity;
|
|||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.springframework.web.reactive.function.BodyExtractors.toMono;
|
||||
import static org.springframework.web.reactive.function.BodyInserters.fromPublisher;
|
||||
import static org.springframework.web.reactive.function.server.RequestPredicates.GET;
|
||||
import static org.springframework.web.reactive.function.server.RequestPredicates.POST;
|
||||
import static org.springframework.web.reactive.function.server.RouterFunctions.route;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.springframework.web.reactive.function.BodyExtractors.*;
|
||||
import static org.springframework.web.reactive.function.BodyInserters.*;
|
||||
import static org.springframework.web.reactive.function.server.RequestPredicates.*;
|
||||
import static org.springframework.web.reactive.function.server.RouterFunctions.*;
|
||||
|
||||
/**
|
||||
* @author Arjen Poutsma
|
||||
*/
|
||||
public class PublisherHandlerFunctionIntegrationTests
|
||||
extends AbstractRouterFunctionIntegrationTests {
|
||||
public class PublisherHandlerFunctionIntegrationTests extends AbstractRouterFunctionIntegrationTests {
|
||||
|
||||
private RestTemplate restTemplate;
|
||||
private final RestTemplate restTemplate = new RestTemplate();
|
||||
|
||||
@Before
|
||||
public void createRestTemplate() {
|
||||
this.restTemplate = new RestTemplate();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected RouterFunction<?> routerFunction() {
|
||||
|
|
@ -112,9 +105,9 @@ public class PublisherHandlerFunctionIntegrationTests
|
|||
return ServerResponse.ok().body(
|
||||
fromPublisher(Flux.just(person1, person2), Person.class));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
private static class Person {
|
||||
|
||||
private String name;
|
||||
|
|
@ -154,11 +147,8 @@ public class PublisherHandlerFunctionIntegrationTests
|
|||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Person{" +
|
||||
"name='" + name + '\'' +
|
||||
'}';
|
||||
return "Person{" + "name='" + name + '\'' + '}';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2017 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.
|
||||
|
|
@ -18,8 +18,7 @@ package org.springframework.web.reactive.function.server;
|
|||
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* @author Arjen Poutsma
|
||||
|
|
@ -63,4 +62,5 @@ public class RequestPredicateTests {
|
|||
assertTrue(predicate2.or(predicate1).test(request));
|
||||
assertFalse(predicate2.or(predicate3).test(request));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,8 +26,7 @@ import org.springframework.http.HttpMethod;
|
|||
import org.springframework.http.MediaType;
|
||||
import org.springframework.web.util.patterns.PathPatternParser;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* @author Arjen Poutsma
|
||||
|
|
@ -191,5 +190,4 @@ public class RequestPredicatesTests {
|
|||
assertFalse(predicate.test(request));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2017 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.
|
||||
|
|
@ -35,8 +35,7 @@ import org.springframework.web.server.ServerWebExchange;
|
|||
import org.springframework.web.server.adapter.DefaultServerWebExchange;
|
||||
import org.springframework.web.server.session.MockWebSessionManager;
|
||||
|
||||
import static org.junit.Assert.assertArrayEquals;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* @author Arjen Poutsma
|
||||
|
|
@ -61,13 +60,13 @@ public class ResourceHandlerFunctionTests {
|
|||
|
||||
Mono<Void> result = responseMono.then(response -> {
|
||||
assertEquals(HttpStatus.OK, response.statusCode());
|
||||
/*
|
||||
TODO: enable when ServerEntityResponse is reintroduced
|
||||
/*
|
||||
TODO: enable when ServerEntityResponse is reintroduced
|
||||
StepVerifier.create(response.body())
|
||||
.expectNext(this.resource)
|
||||
.expectComplete()
|
||||
.verify();
|
||||
*/
|
||||
*/
|
||||
return response.writeTo(exchange, HandlerStrategies.withDefaults());
|
||||
});
|
||||
|
||||
|
|
@ -132,12 +131,12 @@ TODO: enable when ServerEntityResponse is reintroduced
|
|||
assertEquals(HttpStatus.OK, response.statusCode());
|
||||
assertEquals(EnumSet.of(HttpMethod.GET, HttpMethod.HEAD, HttpMethod.OPTIONS),
|
||||
response.headers().getAllow());
|
||||
/*
|
||||
TODO: enable when ServerEntityResponse is reintroduced
|
||||
/*
|
||||
TODO: enable when ServerEntityResponse is reintroduced
|
||||
StepVerifier.create(response.body())
|
||||
.expectComplete()
|
||||
.verify();
|
||||
*/
|
||||
*/
|
||||
return response.writeTo(exchange, HandlerStrategies.withDefaults());
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -20,8 +20,8 @@ import org.junit.Test;
|
|||
import reactor.core.publisher.Mono;
|
||||
import reactor.test.StepVerifier;
|
||||
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.springframework.web.reactive.function.BodyInserters.fromObject;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.springframework.web.reactive.function.BodyInserters.*;
|
||||
|
||||
/**
|
||||
* @author Arjen Poutsma
|
||||
|
|
@ -84,10 +84,6 @@ public class RouterFunctionTests {
|
|||
.verify();
|
||||
}
|
||||
|
||||
private Mono<ServerResponse> handlerMethod(ServerRequest request) {
|
||||
return ServerResponse.ok().body(fromObject("42"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void filter() throws Exception {
|
||||
Mono<String> stringMono = Mono.just("42");
|
||||
|
|
@ -120,4 +116,9 @@ public class RouterFunctionTests {
|
|||
.verify();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private Mono<ServerResponse> handlerMethod(ServerRequest request) {
|
||||
return ServerResponse.ok().body(fromObject("42"));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,11 +30,8 @@ import org.springframework.mock.http.server.reactive.test.MockServerHttpResponse
|
|||
import org.springframework.web.reactive.result.view.ViewResolver;
|
||||
import org.springframework.web.server.ServerWebExchange;
|
||||
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.mockito.Mockito.any;
|
||||
import static org.mockito.Mockito.eq;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
/**
|
||||
* @author Arjen Poutsma
|
||||
|
|
|
|||
|
|
@ -27,13 +27,12 @@ import reactor.test.StepVerifier;
|
|||
import org.springframework.http.codec.ServerSentEvent;
|
||||
import org.springframework.web.reactive.function.client.WebClient;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.springframework.core.ResolvableType.forClassWithGenerics;
|
||||
import static org.springframework.http.MediaType.TEXT_EVENT_STREAM;
|
||||
import static org.springframework.web.reactive.function.BodyExtractors.toFlux;
|
||||
import static org.springframework.web.reactive.function.BodyInserters.fromServerSentEvents;
|
||||
import static org.springframework.web.reactive.function.server.RouterFunctions.route;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.springframework.core.ResolvableType.*;
|
||||
import static org.springframework.http.MediaType.*;
|
||||
import static org.springframework.web.reactive.function.BodyExtractors.*;
|
||||
import static org.springframework.web.reactive.function.BodyInserters.*;
|
||||
import static org.springframework.web.reactive.function.server.RouterFunctions.*;
|
||||
|
||||
/**
|
||||
* @author Arjen Poutsma
|
||||
|
|
@ -43,12 +42,6 @@ public class SseHandlerFunctionIntegrationTests extends AbstractRouterFunctionIn
|
|||
private WebClient webClient;
|
||||
|
||||
|
||||
@Before
|
||||
public void setup() throws Exception {
|
||||
super.setup();
|
||||
this.webClient = WebClient.create("http://localhost:" + this.port);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected RouterFunction<?> routerFunction() {
|
||||
SseHandler sseHandler = new SseHandler();
|
||||
|
|
@ -57,6 +50,13 @@ public class SseHandlerFunctionIntegrationTests extends AbstractRouterFunctionIn
|
|||
.and(route(RequestPredicates.GET("/event"), sseHandler::sse));
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setup() throws Exception {
|
||||
super.setup();
|
||||
this.webClient = WebClient.create("http://localhost:" + this.port);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void sseAsString() throws Exception {
|
||||
Flux<String> result = this.webClient.get()
|
||||
|
|
@ -71,6 +71,7 @@ public class SseHandlerFunctionIntegrationTests extends AbstractRouterFunctionIn
|
|||
.expectComplete()
|
||||
.verify(Duration.ofSeconds(5L));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void sseAsPerson() throws Exception {
|
||||
Flux<Person> result = this.webClient.get()
|
||||
|
|
@ -114,6 +115,7 @@ public class SseHandlerFunctionIntegrationTests extends AbstractRouterFunctionIn
|
|||
.verify(Duration.ofSeconds(5L));
|
||||
}
|
||||
|
||||
|
||||
private static class SseHandler {
|
||||
|
||||
public Mono<ServerResponse> string(ServerRequest request) {
|
||||
|
|
@ -133,11 +135,11 @@ public class SseHandlerFunctionIntegrationTests extends AbstractRouterFunctionIn
|
|||
.id(Long.toString(l))
|
||||
.comment("bar")
|
||||
.build()).take(2);
|
||||
|
||||
return ServerResponse.ok().body(fromServerSentEvents(flux));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static class Person {
|
||||
|
||||
private String name;
|
||||
|
|
@ -177,9 +179,7 @@ public class SseHandlerFunctionIntegrationTests extends AbstractRouterFunctionIn
|
|||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Person{" +
|
||||
"name='" + name + '\'' +
|
||||
'}';
|
||||
return "Person{" + "name='" + name + '\'' + '}';
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue