Browse Source

Polishing

pull/29033/head
Juergen Hoeller 7 years ago
parent
commit
215caedd30
  1. 4
      spring-beans/src/main/java/org/springframework/beans/factory/config/DependencyDescriptor.java
  2. 4
      spring-context/src/main/java/org/springframework/validation/ObjectError.java
  3. 5
      spring-jms/src/main/java/org/springframework/jms/connection/CachingConnectionFactory.java
  4. 35
      spring-messaging/src/main/java/org/springframework/messaging/handler/invocation/HandlerMethodArgumentResolverComposite.java
  5. 4
      spring-test/src/main/java/org/springframework/test/context/web/WebMergedContextConfiguration.java
  6. 7
      spring-web/src/main/java/org/springframework/http/HttpStatus.java
  7. 4
      spring-web/src/main/java/org/springframework/http/ResponseEntity.java
  8. 4
      spring-web/src/main/java/org/springframework/http/client/reactive/ClientHttpResponseDecorator.java
  9. 40
      spring-web/src/main/java/org/springframework/web/method/support/HandlerMethodArgumentResolverComposite.java
  10. 24
      spring-webflux/src/main/java/org/springframework/web/reactive/function/client/DefaultWebClientBuilder.java
  11. 151
      spring-webflux/src/main/java/org/springframework/web/reactive/function/client/WebClient.java

4
spring-beans/src/main/java/org/springframework/beans/factory/config/DependencyDescriptor.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2018 the original author or authors. * Copyright 2002-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -279,7 +279,7 @@ public class DependencyDescriptor extends InjectionPoint implements Serializable
} }
/** /**
* Build a ResolvableType object for the wrapped parameter/field. * Build a {@link ResolvableType} object for the wrapped parameter/field.
* @since 4.0 * @since 4.0
*/ */
public ResolvableType getResolvableType() { public ResolvableType getResolvableType() {

4
spring-context/src/main/java/org/springframework/validation/ObjectError.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2018 the original author or authors. * Copyright 2002-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -144,7 +144,7 @@ public class ObjectError extends DefaultMessageSourceResolvable {
@Override @Override
public int hashCode() { public int hashCode() {
return super.hashCode() * 29 + getObjectName().hashCode(); return (29 * super.hashCode() + getObjectName().hashCode());
} }
@Override @Override

5
spring-jms/src/main/java/org/springframework/jms/connection/CachingConnectionFactory.java

@ -522,7 +522,8 @@ public class CachingConnectionFactory extends SingleConnectionFactory {
public boolean equals(Object other) { public boolean equals(Object other) {
// Effectively checking object equality as well as toString equality. // Effectively checking object equality as well as toString equality.
// On WebSphere MQ, Destination objects do not implement equals... // On WebSphere MQ, Destination objects do not implement equals...
return (this == other || destinationEquals((DestinationCacheKey) other)); return (this == other || (other instanceof DestinationCacheKey &&
destinationEquals((DestinationCacheKey) other)));
} }
@Override @Override
@ -590,7 +591,7 @@ public class CachingConnectionFactory extends SingleConnectionFactory {
@Override @Override
public int hashCode() { public int hashCode() {
return 31 * super.hashCode() + ObjectUtils.nullSafeHashCode(this.selector); return (31 * super.hashCode() + ObjectUtils.nullSafeHashCode(this.selector));
} }
@Override @Override

35
spring-messaging/src/main/java/org/springframework/messaging/handler/invocation/HandlerMethodArgumentResolverComposite.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2018 the original author or authors. * Copyright 2002-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -28,8 +28,8 @@ import org.springframework.messaging.Message;
/** /**
* Resolves method parameters by delegating to a list of registered * Resolves method parameters by delegating to a list of registered
* {@link HandlerMethodArgumentResolver}. Previously resolved method parameters are cached * {@link HandlerMethodArgumentResolver HandlerMethodArgumentResolvers}.
* for faster lookups. * Previously resolved method parameters are cached for faster lookups.
* *
* @author Rossen Stoyanchev * @author Rossen Stoyanchev
* @author Juergen Hoeller * @author Juergen Hoeller
@ -52,28 +52,24 @@ public class HandlerMethodArgumentResolverComposite implements HandlerMethodArgu
} }
/** /**
* Add the given {@link HandlerMethodArgumentResolver}s. * Add the given {@link HandlerMethodArgumentResolver HandlerMethodArgumentResolvers}.
* @since 4.3 * @since 4.3
*/ */
public HandlerMethodArgumentResolverComposite addResolvers(@Nullable HandlerMethodArgumentResolver... resolvers) { public HandlerMethodArgumentResolverComposite addResolvers(@Nullable HandlerMethodArgumentResolver... resolvers) {
if (resolvers != null) { if (resolvers != null) {
for (HandlerMethodArgumentResolver resolver : resolvers) { Collections.addAll(this.argumentResolvers, resolvers);
this.argumentResolvers.add(resolver);
}
} }
return this; return this;
} }
/** /**
* Add the given {@link HandlerMethodArgumentResolver}s. * Add the given {@link HandlerMethodArgumentResolver HandlerMethodArgumentResolvers}.
*/ */
public HandlerMethodArgumentResolverComposite addResolvers( public HandlerMethodArgumentResolverComposite addResolvers(
@Nullable List<? extends HandlerMethodArgumentResolver> argumentResolvers) { @Nullable List<? extends HandlerMethodArgumentResolver> argumentResolvers) {
if (argumentResolvers != null) { if (argumentResolvers != null) {
for (HandlerMethodArgumentResolver resolver : argumentResolvers) { this.argumentResolvers.addAll(argumentResolvers);
this.argumentResolvers.add(resolver);
}
} }
return this; return this;
} }
@ -94,8 +90,8 @@ public class HandlerMethodArgumentResolverComposite implements HandlerMethodArgu
/** /**
* Whether the given {@linkplain MethodParameter method parameter} is supported by any registered * Whether the given {@linkplain MethodParameter method parameter} is
* {@link HandlerMethodArgumentResolver}. * supported by any registered {@link HandlerMethodArgumentResolver}.
*/ */
@Override @Override
public boolean supportsParameter(MethodParameter parameter) { public boolean supportsParameter(MethodParameter parameter) {
@ -103,21 +99,26 @@ public class HandlerMethodArgumentResolverComposite implements HandlerMethodArgu
} }
/** /**
* Iterate over registered {@link HandlerMethodArgumentResolver}s and invoke the one that supports it. * Iterate over registered
* @throws IllegalStateException if no suitable {@link HandlerMethodArgumentResolver} is found. * {@link HandlerMethodArgumentResolver HandlerMethodArgumentResolvers}
* and invoke the one that supports it.
* @throws IllegalStateException if no suitable
* {@link HandlerMethodArgumentResolver} is found.
*/ */
@Override @Override
@Nullable @Nullable
public Object resolveArgument(MethodParameter parameter, Message<?> message) throws Exception { public Object resolveArgument(MethodParameter parameter, Message<?> message) throws Exception {
HandlerMethodArgumentResolver resolver = getArgumentResolver(parameter); HandlerMethodArgumentResolver resolver = getArgumentResolver(parameter);
if (resolver == null) { if (resolver == null) {
throw new IllegalStateException("Unknown parameter type [" + parameter.getParameterType().getName() + "]"); throw new IllegalArgumentException("Unsupported parameter type [" +
parameter.getParameterType().getName() + "]. supportsParameter should be called first.");
} }
return resolver.resolveArgument(parameter, message); return resolver.resolveArgument(parameter, message);
} }
/** /**
* Find a registered {@link HandlerMethodArgumentResolver} that supports the given method parameter. * Find a registered {@link HandlerMethodArgumentResolver} that supports
* the given method parameter.
*/ */
@Nullable @Nullable
private HandlerMethodArgumentResolver getArgumentResolver(MethodParameter parameter) { private HandlerMethodArgumentResolver getArgumentResolver(MethodParameter parameter) {

4
spring-test/src/main/java/org/springframework/test/context/web/WebMergedContextConfiguration.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2017 the original author or authors. * Copyright 2002-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -178,7 +178,7 @@ public class WebMergedContextConfiguration extends MergedContextConfiguration {
*/ */
@Override @Override
public int hashCode() { public int hashCode() {
return super.hashCode() * 31 + this.resourceBasePath.hashCode(); return (31 * super.hashCode() + this.resourceBasePath.hashCode());
} }
/** /**

7
spring-web/src/main/java/org/springframework/http/HttpStatus.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2018 the original author or authors. * Copyright 2002-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -447,6 +447,7 @@ public enum HttpStatus {
* Whether this status code is in the HTTP series * Whether this status code is in the HTTP series
* {@link org.springframework.http.HttpStatus.Series#INFORMATIONAL}. * {@link org.springframework.http.HttpStatus.Series#INFORMATIONAL}.
* This is a shortcut for checking the value of {@link #series()}. * This is a shortcut for checking the value of {@link #series()}.
* @since 4.0
* @see #series() * @see #series()
*/ */
public boolean is1xxInformational() { public boolean is1xxInformational() {
@ -457,6 +458,7 @@ public enum HttpStatus {
* Whether this status code is in the HTTP series * Whether this status code is in the HTTP series
* {@link org.springframework.http.HttpStatus.Series#SUCCESSFUL}. * {@link org.springframework.http.HttpStatus.Series#SUCCESSFUL}.
* This is a shortcut for checking the value of {@link #series()}. * This is a shortcut for checking the value of {@link #series()}.
* @since 4.0
* @see #series() * @see #series()
*/ */
public boolean is2xxSuccessful() { public boolean is2xxSuccessful() {
@ -467,6 +469,7 @@ public enum HttpStatus {
* Whether this status code is in the HTTP series * Whether this status code is in the HTTP series
* {@link org.springframework.http.HttpStatus.Series#REDIRECTION}. * {@link org.springframework.http.HttpStatus.Series#REDIRECTION}.
* This is a shortcut for checking the value of {@link #series()}. * This is a shortcut for checking the value of {@link #series()}.
* @since 4.0
* @see #series() * @see #series()
*/ */
public boolean is3xxRedirection() { public boolean is3xxRedirection() {
@ -477,6 +480,7 @@ public enum HttpStatus {
* Whether this status code is in the HTTP series * Whether this status code is in the HTTP series
* {@link org.springframework.http.HttpStatus.Series#CLIENT_ERROR}. * {@link org.springframework.http.HttpStatus.Series#CLIENT_ERROR}.
* This is a shortcut for checking the value of {@link #series()}. * This is a shortcut for checking the value of {@link #series()}.
* @since 4.0
* @see #series() * @see #series()
*/ */
public boolean is4xxClientError() { public boolean is4xxClientError() {
@ -487,6 +491,7 @@ public enum HttpStatus {
* Whether this status code is in the HTTP series * Whether this status code is in the HTTP series
* {@link org.springframework.http.HttpStatus.Series#SERVER_ERROR}. * {@link org.springframework.http.HttpStatus.Series#SERVER_ERROR}.
* This is a shortcut for checking the value of {@link #series()}. * This is a shortcut for checking the value of {@link #series()}.
* @since 4.0
* @see #series() * @see #series()
*/ */
public boolean is5xxServerError() { public boolean is5xxServerError() {

4
spring-web/src/main/java/org/springframework/http/ResponseEntity.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2018 the original author or authors. * Copyright 2002-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -166,7 +166,7 @@ public class ResponseEntity<T> extends HttpEntity<T> {
@Override @Override
public int hashCode() { public int hashCode() {
return (super.hashCode() * 29 + ObjectUtils.nullSafeHashCode(this.status)); return (29 * super.hashCode() + ObjectUtils.nullSafeHashCode(this.status));
} }
@Override @Override

4
spring-web/src/main/java/org/springframework/http/client/reactive/ClientHttpResponseDecorator.java

@ -33,7 +33,7 @@ import org.springframework.util.MultiValueMap;
* @since 5.0 * @since 5.0
*/ */
public class ClientHttpResponseDecorator implements ClientHttpResponse { public class ClientHttpResponseDecorator implements ClientHttpResponse {
private final ClientHttpResponse delegate; private final ClientHttpResponse delegate;
@ -48,7 +48,7 @@ public class ClientHttpResponseDecorator implements ClientHttpResponse {
} }
// ServerHttpResponse delegation methods... // ClientHttpResponse delegation methods...
@Override @Override
public HttpStatus getStatusCode() { public HttpStatus getStatusCode() {

40
spring-web/src/main/java/org/springframework/web/method/support/HandlerMethodArgumentResolverComposite.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2017 the original author or authors. * Copyright 2002-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -31,7 +31,8 @@ import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest; import org.springframework.web.context.request.NativeWebRequest;
/** /**
* Resolves method parameters by delegating to a list of registered {@link HandlerMethodArgumentResolver}s. * Resolves method parameters by delegating to a list of registered
* {@link HandlerMethodArgumentResolver HandlerMethodArgumentResolvers}.
* Previously resolved method parameters are cached for faster lookups. * Previously resolved method parameters are cached for faster lookups.
* *
* @author Rossen Stoyanchev * @author Rossen Stoyanchev
@ -57,28 +58,24 @@ public class HandlerMethodArgumentResolverComposite implements HandlerMethodArgu
} }
/** /**
* Add the given {@link HandlerMethodArgumentResolver}s. * Add the given {@link HandlerMethodArgumentResolver HandlerMethodArgumentResolvers}.
* @since 4.3 * @since 4.3
*/ */
public HandlerMethodArgumentResolverComposite addResolvers(@Nullable HandlerMethodArgumentResolver... resolvers) { public HandlerMethodArgumentResolverComposite addResolvers(@Nullable HandlerMethodArgumentResolver... resolvers) {
if (resolvers != null) { if (resolvers != null) {
for (HandlerMethodArgumentResolver resolver : resolvers) { Collections.addAll(this.argumentResolvers, resolvers);
this.argumentResolvers.add(resolver);
}
} }
return this; return this;
} }
/** /**
* Add the given {@link HandlerMethodArgumentResolver}s. * Add the given {@link HandlerMethodArgumentResolver HandlerMethodArgumentResolvers}.
*/ */
public HandlerMethodArgumentResolverComposite addResolvers( public HandlerMethodArgumentResolverComposite addResolvers(
@Nullable List<? extends HandlerMethodArgumentResolver> resolvers) { @Nullable List<? extends HandlerMethodArgumentResolver> resolvers) {
if (resolvers != null) { if (resolvers != null) {
for (HandlerMethodArgumentResolver resolver : resolvers) { this.argumentResolvers.addAll(resolvers);
this.argumentResolvers.add(resolver);
}
} }
return this; return this;
} }
@ -100,17 +97,20 @@ public class HandlerMethodArgumentResolverComposite implements HandlerMethodArgu
/** /**
* Whether the given {@linkplain MethodParameter method parameter} is supported by any registered * Whether the given {@linkplain MethodParameter method parameter} is
* {@link HandlerMethodArgumentResolver}. * supported by any registered {@link HandlerMethodArgumentResolver}.
*/ */
@Override @Override
public boolean supportsParameter(MethodParameter parameter) { public boolean supportsParameter(MethodParameter parameter) {
return (getArgumentResolver(parameter) != null); return getArgumentResolver(parameter) != null;
} }
/** /**
* Iterate over registered {@link HandlerMethodArgumentResolver}s and invoke the one that supports it. * Iterate over registered
* @throws IllegalStateException if no suitable {@link HandlerMethodArgumentResolver} is found. * {@link HandlerMethodArgumentResolver HandlerMethodArgumentResolvers} and
* invoke the one that supports it.
* @throws IllegalStateException if no suitable
* {@link HandlerMethodArgumentResolver} is found.
*/ */
@Override @Override
@Nullable @Nullable
@ -119,23 +119,21 @@ public class HandlerMethodArgumentResolverComposite implements HandlerMethodArgu
HandlerMethodArgumentResolver resolver = getArgumentResolver(parameter); HandlerMethodArgumentResolver resolver = getArgumentResolver(parameter);
if (resolver == null) { if (resolver == null) {
throw new IllegalArgumentException("Unknown parameter type [" + parameter.getParameterType().getName() + "]"); throw new IllegalArgumentException("Unsupported parameter type [" +
parameter.getParameterType().getName() + "]. supportsParameter should be called first.");
} }
return resolver.resolveArgument(parameter, mavContainer, webRequest, binderFactory); return resolver.resolveArgument(parameter, mavContainer, webRequest, binderFactory);
} }
/** /**
* Find a registered {@link HandlerMethodArgumentResolver} that supports the given method parameter. * Find a registered {@link HandlerMethodArgumentResolver} that supports
* the given method parameter.
*/ */
@Nullable @Nullable
private HandlerMethodArgumentResolver getArgumentResolver(MethodParameter parameter) { private HandlerMethodArgumentResolver getArgumentResolver(MethodParameter parameter) {
HandlerMethodArgumentResolver result = this.argumentResolverCache.get(parameter); HandlerMethodArgumentResolver result = this.argumentResolverCache.get(parameter);
if (result == null) { if (result == null) {
for (HandlerMethodArgumentResolver methodArgumentResolver : this.argumentResolvers) { for (HandlerMethodArgumentResolver methodArgumentResolver : this.argumentResolvers) {
if (logger.isTraceEnabled()) {
logger.trace("Testing if argument resolver [" + methodArgumentResolver + "] supports [" +
parameter.getGenericParameterType() + "]");
}
if (methodArgumentResolver.supportsParameter(parameter)) { if (methodArgumentResolver.supportsParameter(parameter)) {
result = methodArgumentResolver; result = methodArgumentResolver;
this.argumentResolverCache.put(parameter, result); this.argumentResolverCache.put(parameter, result);

24
spring-webflux/src/main/java/org/springframework/web/reactive/function/client/DefaultWebClientBuilder.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2018 the original author or authors. * Copyright 2002-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -63,11 +63,11 @@ final class DefaultWebClientBuilder implements WebClient.Builder {
@Nullable @Nullable
private ClientHttpConnector connector; private ClientHttpConnector connector;
private ExchangeStrategies exchangeStrategies;
@Nullable @Nullable
private ExchangeFunction exchangeFunction; private ExchangeFunction exchangeFunction;
private ExchangeStrategies exchangeStrategies;
public DefaultWebClientBuilder() { public DefaultWebClientBuilder() {
this.exchangeStrategies = ExchangeStrategies.withDefaults(); this.exchangeStrategies = ExchangeStrategies.withDefaults();
@ -91,8 +91,8 @@ final class DefaultWebClientBuilder implements WebClient.Builder {
new LinkedMultiValueMap<>(other.defaultCookies) : null); new LinkedMultiValueMap<>(other.defaultCookies) : null);
this.filters = (other.filters != null ? new ArrayList<>(other.filters) : null); this.filters = (other.filters != null ? new ArrayList<>(other.filters) : null);
this.connector = other.connector; this.connector = other.connector;
this.exchangeFunction = other.exchangeFunction;
this.exchangeStrategies = other.exchangeStrategies; this.exchangeStrategies = other.exchangeStrategies;
this.exchangeFunction = other.exchangeFunction;
} }
@ -155,12 +155,6 @@ final class DefaultWebClientBuilder implements WebClient.Builder {
return this.defaultCookies; return this.defaultCookies;
} }
@Override
public WebClient.Builder clientConnector(ClientHttpConnector connector) {
this.connector = connector;
return this;
}
@Override @Override
public WebClient.Builder filter(ExchangeFilterFunction filter) { public WebClient.Builder filter(ExchangeFilterFunction filter) {
Assert.notNull(filter, "ExchangeFilterFunction must not be null"); Assert.notNull(filter, "ExchangeFilterFunction must not be null");
@ -182,8 +176,8 @@ final class DefaultWebClientBuilder implements WebClient.Builder {
} }
@Override @Override
public WebClient.Builder exchangeFunction(ExchangeFunction exchangeFunction) { public WebClient.Builder clientConnector(ClientHttpConnector connector) {
this.exchangeFunction = exchangeFunction; this.connector = connector;
return this; return this;
} }
@ -194,6 +188,12 @@ final class DefaultWebClientBuilder implements WebClient.Builder {
return this; return this;
} }
@Override
public WebClient.Builder exchangeFunction(ExchangeFunction exchangeFunction) {
this.exchangeFunction = exchangeFunction;
return this;
}
@Override @Override
public WebClient build() { public WebClient build() {
ExchangeFunction exchange = initExchangeFunction(); ExchangeFunction exchange = initExchangeFunction();

151
spring-webflux/src/main/java/org/springframework/web/reactive/function/client/WebClient.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2018 the original author or authors. * Copyright 2002-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -49,13 +49,17 @@ import org.springframework.web.util.UriBuilderFactory;
* <p>Use static factory methods {@link #create()} or {@link #create(String)}, * <p>Use static factory methods {@link #create()} or {@link #create(String)},
* or {@link WebClient#builder()} to prepare an instance. * or {@link WebClient#builder()} to prepare an instance.
* *
* <p>For examples with a response body see * <p>For examples with a response body see:
* {@link RequestHeadersSpec#retrieve() retrieve()} and * <ul>
* {@link RequestHeadersSpec#exchange() exchange()}. * <li>{@link RequestHeadersSpec#retrieve() retrieve()}
* For examples with a request body see * <li>{@link RequestHeadersSpec#exchange() exchange()}
* {@link RequestBodySpec#body(Publisher, Class) body(Publisher,Class)}, * </ul>
* {@link RequestBodySpec#syncBody(Object) syncBody(Object)}, and * <p>For examples with a request body see:
* {@link RequestBodySpec#body(BodyInserter) body(BodyInserter)}. * <ul>
* <li>{@link RequestBodySpec#body(Publisher, Class) body(Publisher,Class)}
* <li>{@link RequestBodySpec#syncBody(Object) syncBody(Object)}
* <li>{@link RequestBodySpec#body(BodyInserter) body(BodyInserter)}
* </ul>
* *
* @author Rossen Stoyanchev * @author Rossen Stoyanchev
* @author Arjen Poutsma * @author Arjen Poutsma
@ -64,57 +68,57 @@ import org.springframework.web.util.UriBuilderFactory;
public interface WebClient { public interface WebClient {
/** /**
* Prepare an HTTP GET request. * Start building an HTTP GET request.
* @return a spec for specifying the target URL * @return a spec for specifying the target URL
*/ */
RequestHeadersUriSpec<?> get(); RequestHeadersUriSpec<?> get();
/** /**
* Prepare an HTTP HEAD request. * Start building an HTTP HEAD request.
* @return a spec for specifying the target URL * @return a spec for specifying the target URL
*/ */
RequestHeadersUriSpec<?> head(); RequestHeadersUriSpec<?> head();
/** /**
* Prepare an HTTP POST request. * Start building an HTTP POST request.
* @return a spec for specifying the target URL * @return a spec for specifying the target URL
*/ */
RequestBodyUriSpec post(); RequestBodyUriSpec post();
/** /**
* Prepare an HTTP PUT request. * Start building an HTTP PUT request.
* @return a spec for specifying the target URL * @return a spec for specifying the target URL
*/ */
RequestBodyUriSpec put(); RequestBodyUriSpec put();
/** /**
* Prepare an HTTP PATCH request. * Start building an HTTP PATCH request.
* @return a spec for specifying the target URL * @return a spec for specifying the target URL
*/ */
RequestBodyUriSpec patch(); RequestBodyUriSpec patch();
/** /**
* Prepare an HTTP DELETE request. * Start building an HTTP DELETE request.
* @return a spec for specifying the target URL * @return a spec for specifying the target URL
*/ */
RequestHeadersUriSpec<?> delete(); RequestHeadersUriSpec<?> delete();
/** /**
* Prepare an HTTP OPTIONS request. * Start building an HTTP OPTIONS request.
* @return a spec for specifying the target URL * @return a spec for specifying the target URL
*/ */
RequestHeadersUriSpec<?> options(); RequestHeadersUriSpec<?> options();
/** /**
* Prepare a request for the specified {@code HttpMethod}. * Start building a request for the given {@code HttpMethod}.
* @return a spec for specifying the target URL * @return a spec for specifying the target URL
*/ */
RequestBodyUriSpec method(HttpMethod method); RequestBodyUriSpec method(HttpMethod method);
/** /**
* Return a builder for a new {@code WebClient} with properties replicated * Return a builder to create a new {@code WebClient} whose settings are
* from the current {@code WebClient} instance, but without affecting it. * replicated from the current {@code WebClient}.
*/ */
Builder mutate(); Builder mutate();
@ -122,7 +126,7 @@ public interface WebClient {
// Static, factory methods // Static, factory methods
/** /**
* Create a new {@code WebClient} with a Reactor Netty connector. * Create a new {@code WebClient} with Reactor Netty by default.
* @see #create(String) * @see #create(String)
* @see #builder() * @see #builder()
*/ */
@ -131,7 +135,7 @@ public interface WebClient {
} }
/** /**
* A variant of {@link #create()} that accepts a default base URL. For more * Variant of {@link #create()} that accepts a default base URL. For more
* details see {@link Builder#baseUrl(String) Builder.baseUrl(String)}. * details see {@link Builder#baseUrl(String) Builder.baseUrl(String)}.
* @param baseUrl the base URI for all requests * @param baseUrl the base URI for all requests
* @see #builder() * @see #builder()
@ -256,19 +260,6 @@ public interface WebClient {
*/ */
Builder defaultCookies(Consumer<MultiValueMap<String, String>> cookiesConsumer); Builder defaultCookies(Consumer<MultiValueMap<String, String>> cookiesConsumer);
/**
* Configure the {@link ClientHttpConnector} to use.
* <p>By default an instance of
* {@link org.springframework.http.client.reactive.ReactorClientHttpConnector
* ReactorClientHttpConnector} is created if this is not set. However a
* shared instance may be passed instead, e.g. for use with multiple
* {@code WebClient}'s targeting different base URIs.
* @param connector the connector to use
* @see #exchangeStrategies(ExchangeStrategies)
* @see #exchangeFunction(ExchangeFunction)
*/
Builder clientConnector(ClientHttpConnector connector);
/** /**
* Add the given filter to the filter chain. * Add the given filter to the filter chain.
* @param filter the filter to be added to the chain * @param filter the filter to be added to the chain
@ -276,8 +267,8 @@ public interface WebClient {
Builder filter(ExchangeFilterFunction filter); Builder filter(ExchangeFilterFunction filter);
/** /**
* Manipulate the filters with the given consumer. The * Manipulate the filters with the given consumer. The list provided to
* list provided to the consumer is "live", so that the consumer can be used to remove * the consumer is "live", so that the consumer can be used to remove
* filters, change ordering, etc. * filters, change ordering, etc.
* @param filtersConsumer a function that consumes the filter list * @param filtersConsumer a function that consumes the filter list
* @return this builder * @return this builder
@ -285,34 +276,40 @@ public interface WebClient {
Builder filters(Consumer<List<ExchangeFilterFunction>> filtersConsumer); Builder filters(Consumer<List<ExchangeFilterFunction>> filtersConsumer);
/** /**
* Provide a pre-configured {@link ExchangeFunction} instance. This is * Configure the {@link ClientHttpConnector} to use. This is useful for
* an alternative to and effectively overrides the following: * plugging in and/or customizing options of the underlying HTTP client
* <ul> * library (e.g. SSL).
* <li>{@link #clientConnector(ClientHttpConnector)} * <p>By default this is set to
* <li>{@link #exchangeStrategies(ExchangeStrategies)}. * {@link org.springframework.http.client.reactive.ReactorClientHttpConnector
* </ul> * ReactorClientHttpConnector}.
* @param exchangeFunction the exchange function to use * @param connector the connector to use
* @see #clientConnector(ClientHttpConnector)
* @see #exchangeStrategies(ExchangeStrategies)
*/ */
Builder exchangeFunction(ExchangeFunction exchangeFunction); Builder clientConnector(ClientHttpConnector connector);
/** /**
* Configure the {@link ExchangeStrategies} to use. * Configure the {@link ExchangeStrategies} to use.
* <p>By default {@link ExchangeStrategies#withDefaults()} is used. * <p>By default this is obtained from {@link ExchangeStrategies#withDefaults()}.
* @param strategies the strategies to use * @param strategies the strategies to use
* @see #clientConnector(ClientHttpConnector)
* @see #exchangeFunction(ExchangeFunction)
*/ */
Builder exchangeStrategies(ExchangeStrategies strategies); Builder exchangeStrategies(ExchangeStrategies strategies);
/** /**
* Clone this {@code WebClient.Builder} * Provide an {@link ExchangeFunction} pre-configured with
* {@link ClientHttpConnector} and {@link ExchangeStrategies}.
* <p>This is an alternative to, and effectively overrides
* {@link #clientConnector}, and {@link #exchangeStrategies}.
* @param exchangeFunction the exchange function to use
*/
Builder exchangeFunction(ExchangeFunction exchangeFunction);
/**
* Clone this {@code WebClient.Builder}.
*/ */
Builder clone(); Builder clone();
/** /**
* Shortcut for pre-packaged customizations to WebTest builder. * Apply the given {@code Consumer} to this builder instance.
* <p>This can be useful for applying pre-packaged customizations.
* @param builderConsumer the consumer to apply * @param builderConsumer the consumer to apply
*/ */
Builder apply(Consumer<Builder> builderConsumer); Builder apply(Consumer<Builder> builderConsumer);
@ -327,6 +324,7 @@ public interface WebClient {
/** /**
* Contract for specifying the URI for a request. * Contract for specifying the URI for a request.
* @param <S> a self reference to the spec type
*/ */
interface UriSpec<S extends RequestHeadersSpec<?>> { interface UriSpec<S extends RequestHeadersSpec<?>> {
@ -359,6 +357,7 @@ public interface WebClient {
/** /**
* Contract for specifying request headers leading up to the exchange. * Contract for specifying request headers leading up to the exchange.
* @param <S> a self reference to the spec type
*/ */
interface RequestHeadersSpec<S extends RequestHeadersSpec<S>> { interface RequestHeadersSpec<S extends RequestHeadersSpec<S>> {
@ -387,12 +386,9 @@ public interface WebClient {
S cookie(String name, String value); S cookie(String name, String value);
/** /**
* Manipulate the request's cookies with the given consumer. The * Provides access to every cookie declared so far with the possibility
* map provided to the consumer is "live", so that the consumer can be used to * to add, replace, or remove values.
* {@linkplain MultiValueMap#set(Object, Object) overwrite} existing header values, * @param cookiesConsumer the consumer to provide access to
* {@linkplain MultiValueMap#remove(Object) remove} values, or use any of the other
* {@link MultiValueMap} methods.
* @param cookiesConsumer a function that consumes the cookies map
* @return this builder * @return this builder
*/ */
S cookies(Consumer<MultiValueMap<String, String>> cookiesConsumer); S cookies(Consumer<MultiValueMap<String, String>> cookiesConsumer);
@ -422,12 +418,9 @@ public interface WebClient {
S header(String headerName, String... headerValues); S header(String headerName, String... headerValues);
/** /**
* Manipulate the request's headers with the given consumer. The * Provides access to every header declared so far with the possibility
* headers provided to the consumer are "live", so that the consumer can be used to * to add, replace, or remove values.
* {@linkplain HttpHeaders#set(String, String) overwrite} existing header values, * @param headersConsumer the consumer to provide access to
* {@linkplain HttpHeaders#remove(Object) remove} values, or use any of the other
* {@link HttpHeaders} methods.
* @param headersConsumer a function that consumes the {@code HttpHeaders}
* @return this builder * @return this builder
*/ */
S headers(Consumer<HttpHeaders> headersConsumer); S headers(Consumer<HttpHeaders> headersConsumer);
@ -441,10 +434,9 @@ public interface WebClient {
S attribute(String name, Object value); S attribute(String name, Object value);
/** /**
* Manipulate the request attributes with the given consumer. The attributes provided to * Provides access to every attribute declared so far with the
* the consumer are "live", so that the consumer can be used to inspect attributes, * possibility to add, replace, or remove values.
* remove attributes, or use any of the other map-provided methods. * @param attributesConsumer the consumer to provide access to
* @param attributesConsumer a function that consumes the attributes
* @return this builder * @return this builder
*/ */
S attributes(Consumer<Map<String, Object>> attributesConsumer); S attributes(Consumer<Map<String, Object>> attributesConsumer);
@ -474,13 +466,13 @@ public interface WebClient {
* .uri("/persons/1") * .uri("/persons/1")
* .accept(MediaType.APPLICATION_JSON) * .accept(MediaType.APPLICATION_JSON)
* .exchange() * .exchange()
* .flatMap(response -> response.bodyToMono(Person.class)); * .flatMap(response -&gt; response.bodyToMono(Person.class));
* *
* Flux&lt;Person&gt; flux = client.get() * Flux&lt;Person&gt; flux = client.get()
* .uri("/persons") * .uri("/persons")
* .accept(MediaType.APPLICATION_STREAM_JSON) * .accept(MediaType.APPLICATION_STREAM_JSON)
* .exchange() * .exchange()
* .flatMapMany(response -> response.bodyToFlux(Person.class)); * .flatMapMany(response -&gt; response.bodyToFlux(Person.class));
* </pre> * </pre>
* <p><strong>NOTE:</strong> You must always use one of the body or * <p><strong>NOTE:</strong> You must always use one of the body or
* entity methods of the response to ensure resources are released. * entity methods of the response to ensure resources are released.
@ -492,6 +484,9 @@ public interface WebClient {
} }
/**
* Contract for specifying request headers and body leading up to the exchange.
*/
interface RequestBodySpec extends RequestHeadersSpec<RequestBodySpec> { interface RequestBodySpec extends RequestHeadersSpec<RequestBodySpec> {
/** /**
@ -527,9 +522,9 @@ public interface WebClient {
* {@linkplain BodyInserters#fromPublisher Publisher inserter}. * {@linkplain BodyInserters#fromPublisher Publisher inserter}.
* For example: * For example:
* <p><pre> * <p><pre>
* Mono<Person> personMono = ... ; * Mono&lt;Person&gt; personMono = ... ;
* *
* Mono<Void> result = client.post() * Mono&lt;Void&gt; result = client.post()
* .uri("/persons/{id}", id) * .uri("/persons/{id}", id)
* .contentType(MediaType.APPLICATION_JSON) * .contentType(MediaType.APPLICATION_JSON)
* .body(personMono, Person.class) * .body(personMono, Person.class)
@ -564,7 +559,7 @@ public interface WebClient {
* <p><pre class="code"> * <p><pre class="code">
* Person person = ... ; * Person person = ... ;
* *
* Mono<Void> result = client.post() * Mono&lt;Void&gt; result = client.post()
* .uri("/persons/{id}", id) * .uri("/persons/{id}", id)
* .contentType(MediaType.APPLICATION_JSON) * .contentType(MediaType.APPLICATION_JSON)
* .syncBody(person) * .syncBody(person)
@ -586,13 +581,16 @@ public interface WebClient {
} }
/**
* Contract for specifying response operations following the exchange.
*/
interface ResponseSpec { interface ResponseSpec {
/** /**
* Register a custom error function that gets invoked when the given {@link HttpStatus} * Register a custom error function that gets invoked when the given {@link HttpStatus}
* predicate applies. The exception returned from the function will be returned from * predicate applies. The exception returned from the function will be returned from
* {@link #bodyToMono(Class)} and {@link #bodyToFlux(Class)}. * {@link #bodyToMono(Class)} and {@link #bodyToFlux(Class)}.
* <p>By default, an error handler is register that throws a * <p>By default, an error handler is registered that throws a
* {@link WebClientResponseException} when the response status code is 4xx or 5xx. * {@link WebClientResponseException} when the response status code is 4xx or 5xx.
* @param statusPredicate a predicate that indicates whether {@code exceptionFunction} * @param statusPredicate a predicate that indicates whether {@code exceptionFunction}
* applies * applies
@ -648,17 +646,22 @@ public interface WebClient {
* status code is 4xx or 5xx * status code is 4xx or 5xx
*/ */
<T> Flux<T> bodyToFlux(ParameterizedTypeReference<T> typeReference); <T> Flux<T> bodyToFlux(ParameterizedTypeReference<T> typeReference);
} }
/**
* Contract for specifying request headers and URI for a request.
* @param <S> a self reference to the spec type
*/
interface RequestHeadersUriSpec<S extends RequestHeadersSpec<S>> interface RequestHeadersUriSpec<S extends RequestHeadersSpec<S>>
extends UriSpec<S>, RequestHeadersSpec<S> { extends UriSpec<S>, RequestHeadersSpec<S> {
} }
/**
* Contract for specifying request headers, body and URI for a request.
*/
interface RequestBodyUriSpec extends RequestBodySpec, RequestHeadersUriSpec<RequestBodySpec> { interface RequestBodyUriSpec extends RequestBodySpec, RequestHeadersUriSpec<RequestBodySpec> {
} }
} }

Loading…
Cancel
Save