Expose request in WebClientResponseException
This commit exposes the request that lead to it in WebClientResponseException, as a HttpRequest object. Issue: SPR-17087
This commit is contained in:
parent
54f5b7d0ee
commit
3258ac1ec4
|
@ -27,9 +27,11 @@ import java.util.Arrays;
|
|||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.reactivestreams.Publisher;
|
||||
import reactor.core.publisher.Flux;
|
||||
|
@ -39,6 +41,7 @@ import org.springframework.core.ParameterizedTypeReference;
|
|||
import org.springframework.core.io.buffer.DataBufferUtils;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.HttpRequest;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.client.reactive.ClientHttpRequest;
|
||||
|
@ -139,7 +142,6 @@ class DefaultWebClient implements WebClient {
|
|||
return methodInternal(httpMethod);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private RequestBodyUriSpec methodInternal(HttpMethod httpMethod) {
|
||||
return new DefaultRequestBodyUriSpec(httpMethod);
|
||||
}
|
||||
|
@ -364,7 +366,35 @@ class DefaultWebClient implements WebClient {
|
|||
|
||||
@Override
|
||||
public ResponseSpec retrieve() {
|
||||
return new DefaultResponseSpec(exchange());
|
||||
return new DefaultResponseSpec(exchange(), this::createRequest);
|
||||
}
|
||||
|
||||
private HttpRequest createRequest() {
|
||||
return new HttpRequest() {
|
||||
|
||||
private HttpHeaders headers = initHeaders();
|
||||
|
||||
|
||||
@Override
|
||||
public HttpMethod getMethod() {
|
||||
return httpMethod;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMethodValue() {
|
||||
return httpMethod.name();
|
||||
}
|
||||
|
||||
@Override
|
||||
public URI getURI() {
|
||||
return uri;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpHeaders getHeaders() {
|
||||
return headers;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -376,11 +406,15 @@ class DefaultWebClient implements WebClient {
|
|||
|
||||
private final Mono<ClientResponse> responseMono;
|
||||
|
||||
private final Supplier<HttpRequest> requestSupplier;
|
||||
|
||||
private final List<StatusHandler> statusHandlers = new ArrayList<>(1);
|
||||
|
||||
|
||||
DefaultResponseSpec(Mono<ClientResponse> responseMono) {
|
||||
DefaultResponseSpec(Mono<ClientResponse> responseMono,
|
||||
Supplier<HttpRequest> requestSupplier) {
|
||||
this.responseMono = responseMono;
|
||||
this.requestSupplier = requestSupplier;
|
||||
this.statusHandlers.add(DEFAULT_STATUS_HANDLER);
|
||||
}
|
||||
|
||||
|
@ -393,7 +427,8 @@ class DefaultWebClient implements WebClient {
|
|||
if (this.statusHandlers.size() == 1 && this.statusHandlers.get(0) == DEFAULT_STATUS_HANDLER) {
|
||||
this.statusHandlers.clear();
|
||||
}
|
||||
this.statusHandlers.add(new StatusHandler(statusPredicate, exceptionFunction));
|
||||
this.statusHandlers.add(new StatusHandler(statusPredicate,
|
||||
(clientResponse, request) -> exceptionFunction.apply(clientResponse)));
|
||||
|
||||
return this;
|
||||
}
|
||||
|
@ -405,21 +440,18 @@ class DefaultWebClient implements WebClient {
|
|||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> Mono<T> bodyToMono(ParameterizedTypeReference<T> bodyType) {
|
||||
return this.responseMono.flatMap(response ->
|
||||
handleBody(response, response.bodyToMono(bodyType), mono -> mono.flatMap(Mono::error)));
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> Flux<T> bodyToFlux(Class<T> elementType) {
|
||||
return this.responseMono.flatMapMany(response ->
|
||||
handleBody(response, response.bodyToFlux(elementType), mono -> mono.flatMapMany(Flux::error)));
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> Flux<T> bodyToFlux(ParameterizedTypeReference<T> elementType) {
|
||||
return this.responseMono.flatMapMany(response -> handleBody(response,
|
||||
response.bodyToFlux(elementType), mono -> mono.flatMapMany(Flux::error)));
|
||||
|
@ -431,7 +463,8 @@ class DefaultWebClient implements WebClient {
|
|||
if (HttpStatus.resolve(response.rawStatusCode()) != null) {
|
||||
for (StatusHandler handler : this.statusHandlers) {
|
||||
if (handler.test(response.statusCode())) {
|
||||
Mono<? extends Throwable> exMono = handler.apply(response);
|
||||
HttpRequest request = this.requestSupplier.get();
|
||||
Mono<? extends Throwable> exMono = handler.apply(response, request);
|
||||
exMono = exMono.flatMap(ex -> drainBody(response, ex));
|
||||
exMono = exMono.onErrorResume(ex -> drainBody(response, ex));
|
||||
return errorFunction.apply(exMono);
|
||||
|
@ -440,7 +473,8 @@ class DefaultWebClient implements WebClient {
|
|||
return bodyPublisher;
|
||||
}
|
||||
else {
|
||||
return errorFunction.apply(createResponseException(response));
|
||||
return errorFunction.apply(createResponseException(response,
|
||||
this.requestSupplier.get()));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -452,7 +486,8 @@ class DefaultWebClient implements WebClient {
|
|||
.onErrorResume(ex2 -> Mono.empty()).thenReturn(ex);
|
||||
}
|
||||
|
||||
private static Mono<WebClientResponseException> createResponseException(ClientResponse response) {
|
||||
private static Mono<WebClientResponseException> createResponseException(ClientResponse response,
|
||||
HttpRequest request) {
|
||||
return DataBufferUtils.join(response.body(BodyExtractors.toDataBuffers()))
|
||||
.map(dataBuffer -> {
|
||||
byte[] bytes = new byte[dataBuffer.readableByteCount()];
|
||||
|
@ -471,14 +506,16 @@ class DefaultWebClient implements WebClient {
|
|||
response.statusCode().getReasonPhrase(),
|
||||
response.headers().asHttpHeaders(),
|
||||
bodyBytes,
|
||||
charset);
|
||||
charset,
|
||||
request);
|
||||
}
|
||||
else {
|
||||
return new UnknownHttpStatusCodeException(
|
||||
response.rawStatusCode(),
|
||||
response.headers().asHttpHeaders(),
|
||||
bodyBytes,
|
||||
charset);
|
||||
charset,
|
||||
request);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -488,11 +525,11 @@ class DefaultWebClient implements WebClient {
|
|||
|
||||
private final Predicate<HttpStatus> predicate;
|
||||
|
||||
private final Function<ClientResponse, Mono<? extends Throwable>> exceptionFunction;
|
||||
private final BiFunction<ClientResponse, HttpRequest, Mono<? extends Throwable>> exceptionFunction;
|
||||
|
||||
|
||||
public StatusHandler(Predicate<HttpStatus> predicate,
|
||||
Function<ClientResponse, Mono<? extends Throwable>> exceptionFunction) {
|
||||
BiFunction<ClientResponse, HttpRequest, Mono<? extends Throwable>> exceptionFunction) {
|
||||
|
||||
Assert.notNull(predicate, "Predicate must not be null");
|
||||
Assert.notNull(exceptionFunction, "Function must not be null");
|
||||
|
@ -505,8 +542,8 @@ class DefaultWebClient implements WebClient {
|
|||
return this.predicate.test(status);
|
||||
}
|
||||
|
||||
public Mono<? extends Throwable> apply(ClientResponse response) {
|
||||
return this.exceptionFunction.apply(response);
|
||||
public Mono<? extends Throwable> apply(ClientResponse response, HttpRequest request) {
|
||||
return this.exceptionFunction.apply(response, request);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,6 +19,8 @@ package org.springframework.web.reactive.function.client;
|
|||
import java.nio.charset.Charset;
|
||||
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpRequest;
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
* Exception thrown when an unknown (or custom) HTTP status code is received.
|
||||
|
@ -31,6 +33,10 @@ public class UnknownHttpStatusCodeException extends WebClientResponseException {
|
|||
private static final long serialVersionUID = 2407169540168185007L;
|
||||
|
||||
|
||||
/**
|
||||
* Create a new instance of the {@code UnknownHttpStatusCodeException} with the given
|
||||
* parameters.
|
||||
*/
|
||||
public UnknownHttpStatusCodeException(
|
||||
int statusCode, HttpHeaders headers, byte[] responseBody, Charset responseCharset) {
|
||||
|
||||
|
@ -38,4 +44,17 @@ public class UnknownHttpStatusCodeException extends WebClientResponseException {
|
|||
headers, responseBody, responseCharset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new instance of the {@code UnknownHttpStatusCodeException} with the given
|
||||
* parameters.
|
||||
* @since 5.1.4
|
||||
*/
|
||||
public UnknownHttpStatusCodeException(
|
||||
int statusCode, HttpHeaders headers, byte[] responseBody, Charset responseCharset,
|
||||
@Nullable HttpRequest request) {
|
||||
|
||||
super("Unknown status code [" + statusCode + "]", statusCode, "",
|
||||
headers, responseBody, responseCharset, request);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@ import java.nio.charset.Charset;
|
|||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpRequest;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
|
@ -44,6 +45,9 @@ public class WebClientResponseException extends WebClientException {
|
|||
|
||||
private final Charset responseCharset;
|
||||
|
||||
@Nullable
|
||||
private final HttpRequest request;
|
||||
|
||||
|
||||
/**
|
||||
* Constructor with response data only, and a default message.
|
||||
|
@ -52,22 +56,44 @@ public class WebClientResponseException extends WebClientException {
|
|||
public WebClientResponseException(int statusCode, String statusText,
|
||||
@Nullable HttpHeaders headers, @Nullable byte[] body, @Nullable Charset charset) {
|
||||
|
||||
this(statusCode + " " + statusText, statusCode, statusText, headers, body, charset);
|
||||
this(statusCode, statusText, headers, body, charset, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor with response data only, and a default message.
|
||||
* @since 5.1.4
|
||||
*/
|
||||
public WebClientResponseException(int statusCode, String statusText,
|
||||
@Nullable HttpHeaders headers, @Nullable byte[] body, @Nullable Charset charset,
|
||||
@Nullable HttpRequest request) {
|
||||
|
||||
this(statusCode + " " + statusText, statusCode, statusText, headers, body, charset, request);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor with a prepared message.
|
||||
*/
|
||||
public WebClientResponseException(String message, int statusCode, String statusText,
|
||||
@Nullable HttpHeaders headers, @Nullable byte[] responsebody, @Nullable Charset charset) {
|
||||
@Nullable HttpHeaders headers, @Nullable byte[] responseBody, @Nullable Charset charset) {
|
||||
this(message, statusCode, statusText, headers, responseBody, charset, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor with a prepared message.
|
||||
* @since 5.1.4
|
||||
*/
|
||||
public WebClientResponseException(String message, int statusCode, String statusText,
|
||||
@Nullable HttpHeaders headers, @Nullable byte[] responseBody, @Nullable Charset charset,
|
||||
@Nullable HttpRequest request) {
|
||||
|
||||
super(message);
|
||||
|
||||
this.statusCode = statusCode;
|
||||
this.statusText = statusText;
|
||||
this.headers = (headers != null ? headers : HttpHeaders.EMPTY);
|
||||
this.responseBody = (responsebody != null ? responsebody : new byte[0]);
|
||||
this.responseBody = (responseBody != null ? responseBody : new byte[0]);
|
||||
this.responseCharset = (charset != null ? charset : StandardCharsets.ISO_8859_1);
|
||||
this.request = request;
|
||||
}
|
||||
|
||||
|
||||
|
@ -114,6 +140,14 @@ public class WebClientResponseException extends WebClientException {
|
|||
return new String(this.responseBody, this.responseCharset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the corresponding request.
|
||||
* @since 5.1.4
|
||||
*/
|
||||
@Nullable
|
||||
public HttpRequest getRequest() {
|
||||
return this.request;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create {@code WebClientResponseException} or an HTTP status specific sub-class.
|
||||
|
@ -122,44 +156,55 @@ public class WebClientResponseException extends WebClientException {
|
|||
public static WebClientResponseException create(
|
||||
int statusCode, String statusText, HttpHeaders headers, byte[] body, @Nullable Charset charset) {
|
||||
|
||||
return create(statusCode, statusText, headers, body, charset, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create {@code WebClientResponseException} or an HTTP status specific sub-class.
|
||||
* @since 5.1.4
|
||||
*/
|
||||
public static WebClientResponseException create(
|
||||
int statusCode, String statusText, HttpHeaders headers, byte[] body,
|
||||
@Nullable Charset charset, @Nullable HttpRequest request) {
|
||||
|
||||
HttpStatus httpStatus = HttpStatus.resolve(statusCode);
|
||||
if (httpStatus != null) {
|
||||
switch (httpStatus) {
|
||||
case BAD_REQUEST:
|
||||
return new WebClientResponseException.BadRequest(statusText, headers, body, charset);
|
||||
return new WebClientResponseException.BadRequest(statusText, headers, body, charset, request);
|
||||
case UNAUTHORIZED:
|
||||
return new WebClientResponseException.Unauthorized(statusText, headers, body, charset);
|
||||
return new WebClientResponseException.Unauthorized(statusText, headers, body, charset, request);
|
||||
case FORBIDDEN:
|
||||
return new WebClientResponseException.Forbidden(statusText, headers, body, charset);
|
||||
return new WebClientResponseException.Forbidden(statusText, headers, body, charset, request);
|
||||
case NOT_FOUND:
|
||||
return new WebClientResponseException.NotFound(statusText, headers, body, charset);
|
||||
return new WebClientResponseException.NotFound(statusText, headers, body, charset, request);
|
||||
case METHOD_NOT_ALLOWED:
|
||||
return new WebClientResponseException.MethodNotAllowed(statusText, headers, body, charset);
|
||||
return new WebClientResponseException.MethodNotAllowed(statusText, headers, body, charset, request);
|
||||
case NOT_ACCEPTABLE:
|
||||
return new WebClientResponseException.NotAcceptable(statusText, headers, body, charset);
|
||||
return new WebClientResponseException.NotAcceptable(statusText, headers, body, charset, request);
|
||||
case CONFLICT:
|
||||
return new WebClientResponseException.Conflict(statusText, headers, body, charset);
|
||||
return new WebClientResponseException.Conflict(statusText, headers, body, charset, request);
|
||||
case GONE:
|
||||
return new WebClientResponseException.Gone(statusText, headers, body, charset);
|
||||
return new WebClientResponseException.Gone(statusText, headers, body, charset, request);
|
||||
case UNSUPPORTED_MEDIA_TYPE:
|
||||
return new WebClientResponseException.UnsupportedMediaType(statusText, headers, body, charset);
|
||||
return new WebClientResponseException.UnsupportedMediaType(statusText, headers, body, charset, request);
|
||||
case TOO_MANY_REQUESTS:
|
||||
return new WebClientResponseException.TooManyRequests(statusText, headers, body, charset);
|
||||
return new WebClientResponseException.TooManyRequests(statusText, headers, body, charset, request);
|
||||
case UNPROCESSABLE_ENTITY:
|
||||
return new WebClientResponseException.UnprocessableEntity(statusText, headers, body, charset);
|
||||
return new WebClientResponseException.UnprocessableEntity(statusText, headers, body, charset, request);
|
||||
case INTERNAL_SERVER_ERROR:
|
||||
return new WebClientResponseException.InternalServerError(statusText, headers, body, charset);
|
||||
return new WebClientResponseException.InternalServerError(statusText, headers, body, charset, request);
|
||||
case NOT_IMPLEMENTED:
|
||||
return new WebClientResponseException.NotImplemented(statusText, headers, body, charset);
|
||||
return new WebClientResponseException.NotImplemented(statusText, headers, body, charset, request);
|
||||
case BAD_GATEWAY:
|
||||
return new WebClientResponseException.BadGateway(statusText, headers, body, charset);
|
||||
return new WebClientResponseException.BadGateway(statusText, headers, body, charset, request);
|
||||
case SERVICE_UNAVAILABLE:
|
||||
return new WebClientResponseException.ServiceUnavailable(statusText, headers, body, charset);
|
||||
return new WebClientResponseException.ServiceUnavailable(statusText, headers, body, charset, request);
|
||||
case GATEWAY_TIMEOUT:
|
||||
return new WebClientResponseException.GatewayTimeout(statusText, headers, body, charset);
|
||||
return new WebClientResponseException.GatewayTimeout(statusText, headers, body, charset, request);
|
||||
}
|
||||
}
|
||||
return new WebClientResponseException(statusCode, statusText, headers, body, charset);
|
||||
return new WebClientResponseException(statusCode, statusText, headers, body, charset, request);
|
||||
}
|
||||
|
||||
|
||||
|
@ -173,9 +218,11 @@ public class WebClientResponseException extends WebClientException {
|
|||
@SuppressWarnings("serial")
|
||||
public static class BadRequest extends WebClientResponseException {
|
||||
|
||||
BadRequest(String statusText, HttpHeaders headers, byte[] body, @Nullable Charset charset) {
|
||||
super(HttpStatus.BAD_REQUEST.value(), statusText, headers, body, charset);
|
||||
BadRequest(String statusText, HttpHeaders headers, byte[] body, @Nullable Charset charset,
|
||||
@Nullable HttpRequest request) {
|
||||
super(HttpStatus.BAD_REQUEST.value(), statusText, headers, body, charset, request);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -185,8 +232,9 @@ public class WebClientResponseException extends WebClientException {
|
|||
@SuppressWarnings("serial")
|
||||
public static class Unauthorized extends WebClientResponseException {
|
||||
|
||||
Unauthorized(String statusText, HttpHeaders headers, byte[] body, @Nullable Charset charset) {
|
||||
super(HttpStatus.UNAUTHORIZED.value(), statusText, headers, body, charset);
|
||||
Unauthorized(String statusText, HttpHeaders headers, byte[] body, @Nullable Charset charset,
|
||||
@Nullable HttpRequest request) {
|
||||
super(HttpStatus.UNAUTHORIZED.value(), statusText, headers, body, charset, request);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -197,8 +245,9 @@ public class WebClientResponseException extends WebClientException {
|
|||
@SuppressWarnings("serial")
|
||||
public static class Forbidden extends WebClientResponseException {
|
||||
|
||||
Forbidden(String statusText, HttpHeaders headers, byte[] body, @Nullable Charset charset) {
|
||||
super(HttpStatus.FORBIDDEN.value(), statusText, headers, body, charset);
|
||||
Forbidden(String statusText, HttpHeaders headers, byte[] body, @Nullable Charset charset,
|
||||
@Nullable HttpRequest request) {
|
||||
super(HttpStatus.FORBIDDEN.value(), statusText, headers, body, charset, request);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -209,8 +258,9 @@ public class WebClientResponseException extends WebClientException {
|
|||
@SuppressWarnings("serial")
|
||||
public static class NotFound extends WebClientResponseException {
|
||||
|
||||
NotFound(String statusText, HttpHeaders headers, byte[] body, @Nullable Charset charset) {
|
||||
super(HttpStatus.NOT_FOUND.value(), statusText, headers, body, charset);
|
||||
NotFound(String statusText, HttpHeaders headers, byte[] body, @Nullable Charset charset,
|
||||
@Nullable HttpRequest request) {
|
||||
super(HttpStatus.NOT_FOUND.value(), statusText, headers, body, charset, request);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -221,8 +271,10 @@ public class WebClientResponseException extends WebClientException {
|
|||
@SuppressWarnings("serial")
|
||||
public static class MethodNotAllowed extends WebClientResponseException {
|
||||
|
||||
MethodNotAllowed(String statusText, HttpHeaders headers, byte[] body, @Nullable Charset charset) {
|
||||
super(HttpStatus.METHOD_NOT_ALLOWED.value(), statusText, headers, body, charset);
|
||||
MethodNotAllowed(String statusText, HttpHeaders headers, byte[] body,
|
||||
@Nullable Charset charset, @Nullable HttpRequest request) {
|
||||
super(HttpStatus.METHOD_NOT_ALLOWED.value(), statusText, headers, body, charset,
|
||||
request);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -233,8 +285,9 @@ public class WebClientResponseException extends WebClientException {
|
|||
@SuppressWarnings("serial")
|
||||
public static class NotAcceptable extends WebClientResponseException {
|
||||
|
||||
NotAcceptable(String statusText, HttpHeaders headers, byte[] body, @Nullable Charset charset) {
|
||||
super(HttpStatus.NOT_ACCEPTABLE.value(), statusText, headers, body, charset);
|
||||
NotAcceptable(String statusText, HttpHeaders headers, byte[] body,
|
||||
@Nullable Charset charset, @Nullable HttpRequest request) {
|
||||
super(HttpStatus.NOT_ACCEPTABLE.value(), statusText, headers, body, charset, request);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -245,8 +298,9 @@ public class WebClientResponseException extends WebClientException {
|
|||
@SuppressWarnings("serial")
|
||||
public static class Conflict extends WebClientResponseException {
|
||||
|
||||
Conflict(String statusText, HttpHeaders headers, byte[] body, @Nullable Charset charset) {
|
||||
super(HttpStatus.CONFLICT.value(), statusText, headers, body, charset);
|
||||
Conflict(String statusText, HttpHeaders headers, byte[] body, @Nullable Charset charset,
|
||||
@Nullable HttpRequest request) {
|
||||
super(HttpStatus.CONFLICT.value(), statusText, headers, body, charset, request);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -257,8 +311,9 @@ public class WebClientResponseException extends WebClientException {
|
|||
@SuppressWarnings("serial")
|
||||
public static class Gone extends WebClientResponseException {
|
||||
|
||||
Gone(String statusText, HttpHeaders headers, byte[] body, @Nullable Charset charset) {
|
||||
super(HttpStatus.GONE.value(), statusText, headers, body, charset);
|
||||
Gone(String statusText, HttpHeaders headers, byte[] body, @Nullable Charset charset,
|
||||
@Nullable HttpRequest request) {
|
||||
super(HttpStatus.GONE.value(), statusText, headers, body, charset, request);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -269,8 +324,11 @@ public class WebClientResponseException extends WebClientException {
|
|||
@SuppressWarnings("serial")
|
||||
public static class UnsupportedMediaType extends WebClientResponseException {
|
||||
|
||||
UnsupportedMediaType(String statusText, HttpHeaders headers, byte[] body, @Nullable Charset charset) {
|
||||
super(HttpStatus.UNSUPPORTED_MEDIA_TYPE.value(), statusText, headers, body, charset);
|
||||
UnsupportedMediaType(String statusText, HttpHeaders headers, byte[] body,
|
||||
@Nullable Charset charset, @Nullable HttpRequest request) {
|
||||
|
||||
super(HttpStatus.UNSUPPORTED_MEDIA_TYPE.value(), statusText, headers, body, charset,
|
||||
request);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -281,8 +339,10 @@ public class WebClientResponseException extends WebClientException {
|
|||
@SuppressWarnings("serial")
|
||||
public static class UnprocessableEntity extends WebClientResponseException {
|
||||
|
||||
UnprocessableEntity(String statusText, HttpHeaders headers, byte[] body, @Nullable Charset charset) {
|
||||
super(HttpStatus.UNPROCESSABLE_ENTITY.value(), statusText, headers, body, charset);
|
||||
UnprocessableEntity(String statusText, HttpHeaders headers, byte[] body,
|
||||
@Nullable Charset charset, @Nullable HttpRequest request) {
|
||||
super(HttpStatus.UNPROCESSABLE_ENTITY.value(), statusText, headers, body, charset,
|
||||
request);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -293,8 +353,10 @@ public class WebClientResponseException extends WebClientException {
|
|||
@SuppressWarnings("serial")
|
||||
public static class TooManyRequests extends WebClientResponseException {
|
||||
|
||||
TooManyRequests(String statusText, HttpHeaders headers, byte[] body, @Nullable Charset charset) {
|
||||
super(HttpStatus.TOO_MANY_REQUESTS.value(), statusText, headers, body, charset);
|
||||
TooManyRequests(String statusText, HttpHeaders headers, byte[] body,
|
||||
@Nullable Charset charset, @Nullable HttpRequest request) {
|
||||
super(HttpStatus.TOO_MANY_REQUESTS.value(), statusText, headers, body, charset,
|
||||
request);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -309,8 +371,10 @@ public class WebClientResponseException extends WebClientException {
|
|||
@SuppressWarnings("serial")
|
||||
public static class InternalServerError extends WebClientResponseException {
|
||||
|
||||
InternalServerError(String statusText, HttpHeaders headers, byte[] body, @Nullable Charset charset) {
|
||||
super(HttpStatus.INTERNAL_SERVER_ERROR.value(), statusText, headers, body, charset);
|
||||
InternalServerError(String statusText, HttpHeaders headers, byte[] body,
|
||||
@Nullable Charset charset, @Nullable HttpRequest request) {
|
||||
super(HttpStatus.INTERNAL_SERVER_ERROR.value(), statusText, headers, body, charset,
|
||||
request);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -321,8 +385,9 @@ public class WebClientResponseException extends WebClientException {
|
|||
@SuppressWarnings("serial")
|
||||
public static class NotImplemented extends WebClientResponseException {
|
||||
|
||||
NotImplemented(String statusText, HttpHeaders headers, byte[] body, @Nullable Charset charset) {
|
||||
super(HttpStatus.NOT_IMPLEMENTED.value(), statusText, headers, body, charset);
|
||||
NotImplemented(String statusText, HttpHeaders headers, byte[] body,
|
||||
@Nullable Charset charset, @Nullable HttpRequest request) {
|
||||
super(HttpStatus.NOT_IMPLEMENTED.value(), statusText, headers, body, charset, request);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -333,8 +398,9 @@ public class WebClientResponseException extends WebClientException {
|
|||
@SuppressWarnings("serial")
|
||||
public static class BadGateway extends WebClientResponseException {
|
||||
|
||||
BadGateway(String statusText, HttpHeaders headers, byte[] body, @Nullable Charset charset) {
|
||||
super(HttpStatus.BAD_GATEWAY.value(), statusText, headers, body, charset);
|
||||
BadGateway(String statusText, HttpHeaders headers, byte[] body, @Nullable Charset charset,
|
||||
@Nullable HttpRequest request) {
|
||||
super(HttpStatus.BAD_GATEWAY.value(), statusText, headers, body, charset, request);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -345,8 +411,10 @@ public class WebClientResponseException extends WebClientException {
|
|||
@SuppressWarnings("serial")
|
||||
public static class ServiceUnavailable extends WebClientResponseException {
|
||||
|
||||
ServiceUnavailable(String statusText, HttpHeaders headers, byte[] body, @Nullable Charset charset) {
|
||||
super(HttpStatus.SERVICE_UNAVAILABLE.value(), statusText, headers, body, charset);
|
||||
ServiceUnavailable(String statusText, HttpHeaders headers, byte[] body,
|
||||
@Nullable Charset charset, @Nullable HttpRequest request) {
|
||||
super(HttpStatus.SERVICE_UNAVAILABLE.value(), statusText, headers, body, charset,
|
||||
request);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -357,8 +425,10 @@ public class WebClientResponseException extends WebClientException {
|
|||
@SuppressWarnings("serial")
|
||||
public static class GatewayTimeout extends WebClientResponseException {
|
||||
|
||||
GatewayTimeout(String statusText, HttpHeaders headers, byte[] body, @Nullable Charset charset) {
|
||||
super(HttpStatus.GATEWAY_TIMEOUT.value(), statusText, headers, body, charset);
|
||||
GatewayTimeout(String statusText, HttpHeaders headers, byte[] body,
|
||||
@Nullable Charset charset, @Nullable HttpRequest request) {
|
||||
super(HttpStatus.GATEWAY_TIMEOUT.value(), statusText, headers, body, charset,
|
||||
request);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@ package org.springframework.web.reactive.function.client;
|
|||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.nio.file.Files;
|
||||
import java.time.Duration;
|
||||
import java.util.Arrays;
|
||||
|
@ -45,6 +46,8 @@ import org.springframework.core.io.buffer.DataBuffer;
|
|||
import org.springframework.core.io.buffer.DataBufferUtils;
|
||||
import org.springframework.core.io.buffer.DefaultDataBufferFactory;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.HttpRequest;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
|
@ -494,8 +497,9 @@ public class WebClientIntegrationTests {
|
|||
prepareResponse(response -> response.setResponseCode(500)
|
||||
.setHeader("Content-Type", "text/plain").setBody(errorMessage));
|
||||
|
||||
String path = "/greeting?name=Spring";
|
||||
Mono<String> result = this.webClient.get()
|
||||
.uri("/greeting?name=Spring")
|
||||
.uri(path)
|
||||
.retrieve()
|
||||
.bodyToMono(String.class);
|
||||
|
||||
|
@ -509,13 +513,18 @@ public class WebClientIntegrationTests {
|
|||
ex.getStatusText());
|
||||
assertEquals(MediaType.TEXT_PLAIN, ex.getHeaders().getContentType());
|
||||
assertEquals(errorMessage, ex.getResponseBodyAsString());
|
||||
|
||||
HttpRequest request = ex.getRequest();
|
||||
assertEquals(HttpMethod.GET, request.getMethod());
|
||||
assertEquals(URI.create(this.server.url(path).toString()), request.getURI());
|
||||
assertNotNull(request.getHeaders());
|
||||
})
|
||||
.verify(Duration.ofSeconds(3));
|
||||
|
||||
expectRequestCount(1);
|
||||
expectRequest(request -> {
|
||||
assertEquals("*/*", request.getHeader(HttpHeaders.ACCEPT));
|
||||
assertEquals("/greeting?name=Spring", request.getPath());
|
||||
assertEquals(path, request.getPath());
|
||||
});
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue