diff --git a/spring-web/src/main/java/org/springframework/web/client/DefaultHttpErrorDetailsExtractor.java b/spring-web/src/main/java/org/springframework/web/client/DefaultHttpErrorDetailsExtractor.java deleted file mode 100644 index a1aefcabd315..000000000000 --- a/spring-web/src/main/java/org/springframework/web/client/DefaultHttpErrorDetailsExtractor.java +++ /dev/null @@ -1,138 +0,0 @@ -package org.springframework.web.client; - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.Reader; -import java.net.URI; -import java.nio.CharBuffer; -import java.nio.charset.Charset; -import java.nio.charset.StandardCharsets; - -import org.jetbrains.annotations.NotNull; -import org.springframework.http.HttpMethod; -import org.springframework.lang.Nullable; - -/** - * Spring's default implementation of the {@link HttpErrorDetailsExtractor} interface. - * - *
This extractor will compose a short summary of the http error response, including: - *
- * 404 Not Found after GET http://example.com:8080/my-endpoint : [{'id': 123, 'message': 'my very long... (500 bytes)] - *- * - * @author Jerzy Krolak - * @since 5.1 - * @see DefaultResponseErrorHandler#setHttpErrorDetailsExtractor(HttpErrorDetailsExtractor) - */ -public class DefaultHttpErrorDetailsExtractor implements HttpErrorDetailsExtractor { - - private static final int MAX_BODY_BYTES_LENGTH = 400; - - private static final int MAX_BODY_CHARS_LENGTH = 200; - - /** - * Assemble a short summary of the HTTP error response. - * @param rawStatusCode HTTP status code - * @param statusText HTTP status text - * @param responseBody response body - * @param responseCharset response charset - * @param url request URI - * @param method request method - * @return error details string. Example:
404 Not Found after GET http://example.com:8080/my-endpoint : [{'id': 123, 'message': 'my very long... (500 bytes)]- */ - @Override - @NotNull - public String getErrorDetails(int rawStatusCode, String statusText, @Nullable byte[] responseBody, - @Nullable Charset responseCharset, @Nullable URI url, @Nullable HttpMethod method) { - - if (url == null || method == null) { - return getSimpleErrorDetails(rawStatusCode, statusText); - } - - return getCompleteErrorDetails(rawStatusCode, statusText, responseBody, responseCharset, url, method); - } - - @NotNull - private String getCompleteErrorDetails(int rawStatusCode, String statusText, @Nullable byte[] responseBody, - @Nullable Charset responseCharset, @Nullable URI url, @Nullable HttpMethod method) { - - StringBuilder result = new StringBuilder(); - - result.append(getSimpleErrorDetails(rawStatusCode, statusText)) - .append(" after ") - .append(method) - .append(" ") - .append(url) - .append(" : "); - - if (responseBody == null || responseBody.length == 0) { - result.append("[no body]"); - } - else { - result - .append("[") - .append(getResponseBody(responseBody, responseCharset)) - .append("]"); - } - - return result.toString(); - } - - @NotNull - private String getSimpleErrorDetails(int rawStatusCode, String statusText) { - return rawStatusCode + " " + statusText; - } - - private String getResponseBody(byte[] responseBody, @Nullable Charset responseCharset) { - Charset charset = getCharsetOrDefault(responseCharset); - if (responseBody.length < MAX_BODY_BYTES_LENGTH) { - return getCompleteResponseBody(responseBody, charset); - } - return getResponseBodyPreview(responseBody, charset); - } - - @NotNull - private String getCompleteResponseBody(byte[] responseBody, Charset responseCharset) { - return new String(responseBody, responseCharset); - } - - private String getResponseBodyPreview(byte[] responseBody, Charset responseCharset) { - try { - String bodyPreview = readBodyAsString(responseBody, responseCharset); - return bodyPreview + "... (" + responseBody.length + " bytes)"; - } - catch (IOException e) { - // should never happen - throw new IllegalStateException(e); - } - } - - @NotNull - private String readBodyAsString(byte[] responseBody, Charset responseCharset) throws IOException { - - Reader reader = new InputStreamReader(new ByteArrayInputStream(responseBody), responseCharset); - CharBuffer result = CharBuffer.allocate(MAX_BODY_CHARS_LENGTH); - - reader.read(result); - reader.close(); - result.flip(); - - return result.toString(); - } - - private Charset getCharsetOrDefault(@Nullable Charset responseCharset) { - if (responseCharset == null) { - return StandardCharsets.ISO_8859_1; - } - return responseCharset; - } - -} diff --git a/spring-web/src/main/java/org/springframework/web/client/DefaultResponseErrorHandler.java b/spring-web/src/main/java/org/springframework/web/client/DefaultResponseErrorHandler.java index 8a9ebdeb1d59..ff72eb1e465d 100644 --- a/spring-web/src/main/java/org/springframework/web/client/DefaultResponseErrorHandler.java +++ b/spring-web/src/main/java/org/springframework/web/client/DefaultResponseErrorHandler.java @@ -16,18 +16,21 @@ package org.springframework.web.client; +import java.io.ByteArrayInputStream; import java.io.IOException; -import java.net.URI; +import java.io.InputStreamReader; +import java.io.Reader; +import java.nio.CharBuffer; import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpMethod; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.client.ClientHttpResponse; import org.springframework.lang.Nullable; -import org.springframework.util.Assert; import org.springframework.util.FileCopyUtils; +import org.springframework.util.ObjectUtils; /** * Spring's default implementation of the {@link ResponseErrorHandler} interface. @@ -46,17 +49,6 @@ */ public class DefaultResponseErrorHandler implements ResponseErrorHandler { - private HttpErrorDetailsExtractor httpErrorDetailsExtractor = new DefaultHttpErrorDetailsExtractor(); - - /** - * Set the error summary extractor. - *
By default, DefaultResponseErrorHandler uses a {@link DefaultHttpErrorDetailsExtractor}. - */ - public void setHttpErrorDetailsExtractor(HttpErrorDetailsExtractor httpErrorDetailsExtractor) { - Assert.notNull(httpErrorDetailsExtractor, "HttpErrorDetailsExtractor must not be null"); - this.httpErrorDetailsExtractor = httpErrorDetailsExtractor; - } - /** * Delegates to {@link #hasError(HttpStatus)} (for a standard status enum value) or * {@link #hasError(int)} (for an unknown status code) with the response status code. @@ -101,31 +93,58 @@ protected boolean hasError(int unknownStatusCode) { } /** - * Delegates to {@link #handleError(URI, HttpMethod, ClientHttpResponse, HttpStatus)} with the + * Delegates to {@link #handleError(ClientHttpResponse, HttpStatus)} with the * response status code. * @throws UnknownHttpStatusCodeException in case of an unresolvable status code - * @see #handleError(URI, HttpMethod, ClientHttpResponse, HttpStatus) + * @see #handleError(ClientHttpResponse, HttpStatus) */ @Override public void handleError(ClientHttpResponse response) throws IOException { - handleError(null, null, response); + HttpStatus statusCode = HttpStatus.resolve(response.getRawStatusCode()); + if (statusCode == null) { + String message = getErrorMessage( + response.getRawStatusCode(), response.getStatusText(), + getResponseBody(response), getCharset(response)); + throw new UnknownHttpStatusCodeException(message, + response.getRawStatusCode(), response.getStatusText(), + response.getHeaders(), getResponseBody(response), getCharset(response)); + } + handleError(response, statusCode); } /** - * Delegates to {@link #handleError(URI, HttpMethod, ClientHttpResponse, HttpStatus)} with the - * response status code. - * @throws UnknownHttpStatusCodeException in case of an unresolvable status code - * @see #handleError(URI, HttpMethod, ClientHttpResponse, HttpStatus) + * Return error message with details from the response body, possibly truncated: + *
+ * 404 Not Found: [{'id': 123, 'message': 'my very long... (500 bytes)] + **/ - @Override - public void handleError(URI url, HttpMethod method, ClientHttpResponse response) throws IOException { - HttpStatus statusCode = HttpStatus.resolve(response.getRawStatusCode()); - if (statusCode == null) { - String message = httpErrorDetailsExtractor.getErrorDetails(response.getRawStatusCode(), response.getStatusText(), getResponseBody(response), getCharset(response), url, method); - throw new UnknownHttpStatusCodeException(message, response.getRawStatusCode(), response.getStatusText(), - response.getHeaders(), getResponseBody(response), getCharset(response), url, method); + private String getErrorMessage( + int rawStatusCode, String statusText, @Nullable byte[] responseBody, @Nullable Charset charset) { + + String preface = rawStatusCode + " " + statusText + ": "; + if (ObjectUtils.isEmpty(responseBody)) { + return preface + "[no body]"; + } + + charset = charset == null ? StandardCharsets.UTF_8 : charset; + int maxChars = 200; + + if (responseBody.length < maxChars * 2) { + return preface + "[" + new String(responseBody, charset) + "]"; + } + + try { + Reader reader = new InputStreamReader(new ByteArrayInputStream(responseBody), charset); + CharBuffer buffer = CharBuffer.allocate(maxChars); + reader.read(buffer); + reader.close(); + buffer.flip(); + return preface + "[" + buffer.toString() + "... (" + responseBody.length + " bytes)]"; + } + catch (IOException ex) { + // should never happen + throw new IllegalStateException(ex); } - handleError(url, method, response, statusCode); } /** @@ -140,34 +159,19 @@ public void handleError(URI url, HttpMethod method, ClientHttpResponse response) * @see HttpServerErrorException#create */ protected void handleError(ClientHttpResponse response, HttpStatus statusCode) throws IOException { - handleError(null, null, response, statusCode); - } - - /** - * Handle the error in the given response with the given resolved status code. - *
This default implementation throws a {@link HttpClientErrorException} if the response status code
- * is {@link org.springframework.http.HttpStatus.Series#CLIENT_ERROR}, a {@link HttpServerErrorException}
- * if it is {@link org.springframework.http.HttpStatus.Series#SERVER_ERROR},
- * and a {@link RestClientException} in other cases.
- * @since 5.0
- */
- protected void handleError(@Nullable URI url, @Nullable HttpMethod method, ClientHttpResponse response,
- HttpStatus statusCode) throws IOException {
-
String statusText = response.getStatusText();
HttpHeaders headers = response.getHeaders();
byte[] body = getResponseBody(response);
Charset charset = getCharset(response);
- String message = httpErrorDetailsExtractor.getErrorDetails(statusCode.value(), statusText, body, charset, url, method);
+ String message = getErrorMessage(statusCode.value(), statusText, body, charset);
switch (statusCode.series()) {
case CLIENT_ERROR:
- throw HttpClientErrorException.create(message, statusCode, statusText, headers, body, charset, url, method);
+ throw HttpClientErrorException.create(message, statusCode, statusText, headers, body, charset);
case SERVER_ERROR:
- throw HttpServerErrorException.create(message, statusCode, statusText, headers, body, charset, url, method);
+ throw HttpServerErrorException.create(message, statusCode, statusText, headers, body, charset);
default:
- throw new UnknownHttpStatusCodeException(message, statusCode.value(), statusText, headers, body,
- charset, url, method);
+ throw new UnknownHttpStatusCodeException(message, statusCode.value(), statusText, headers, body, charset);
}
}
diff --git a/spring-web/src/main/java/org/springframework/web/client/HttpClientErrorException.java b/spring-web/src/main/java/org/springframework/web/client/HttpClientErrorException.java
index 70c92265a3c6..ff6e3f83085a 100644
--- a/spring-web/src/main/java/org/springframework/web/client/HttpClientErrorException.java
+++ b/spring-web/src/main/java/org/springframework/web/client/HttpClientErrorException.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");
* you may not use this file except in compliance with the License.
@@ -16,11 +16,9 @@
package org.springframework.web.client;
-import java.net.URI;
import java.nio.charset.Charset;
import org.springframework.http.HttpHeaders;
-import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.lang.Nullable;
@@ -69,48 +67,84 @@ public HttpClientErrorException(HttpStatus statusCode, String statusText,
}
/**
- * Constructor with a status code and status text, headers, content, request URL and method.
+ * Constructor with a status code and status text, headers, and content,
+ * and an prepared message.
+ * @since 5.2.2
*/
public HttpClientErrorException(String message, HttpStatus statusCode, String statusText,
- @Nullable HttpHeaders headers, @Nullable byte[] body, @Nullable Charset responseCharset,
- @Nullable URI url, @Nullable HttpMethod method) {
+ @Nullable HttpHeaders headers, @Nullable byte[] body, @Nullable Charset responseCharset) {
- super(message, statusCode, statusText, headers, body, responseCharset, url, method);
+ super(message, statusCode, statusText, headers, body, responseCharset);
}
+
/**
* Create {@code HttpClientErrorException} or an HTTP status specific sub-class.
* @since 5.1
*/
public static HttpClientErrorException create(
- String message, HttpStatus statusCode, String statusText, HttpHeaders headers, byte[] body,
- @Nullable Charset charset, @Nullable URI url, @Nullable HttpMethod method) {
+ HttpStatus statusCode, String statusText, HttpHeaders headers, byte[] body, @Nullable Charset charset) {
+
+ return create(null, statusCode, statusText, headers, body, charset);
+ }
+
+ /**
+ * Variant of {@link #create(HttpStatus, String, HttpHeaders, byte[], Charset)}
+ * with an optional prepared message.
+ * @since 5.2.2
+ */
+ public static HttpClientErrorException create(@Nullable String message, HttpStatus statusCode,
+ String statusText, HttpHeaders headers, byte[] body, @Nullable Charset charset) {
switch (statusCode) {
case BAD_REQUEST:
- return new HttpClientErrorException.BadRequest(message, statusText, headers, body, charset, url, method);
+ return message != null ?
+ new HttpClientErrorException.BadRequest(message, statusText, headers, body, charset) :
+ new HttpClientErrorException.BadRequest(statusText, headers, body, charset);
case UNAUTHORIZED:
- return new HttpClientErrorException.Unauthorized(message, statusText, headers, body, charset, url, method);
+ return message != null ?
+ new HttpClientErrorException.Unauthorized(message, statusText, headers, body, charset) :
+ new HttpClientErrorException.Unauthorized(statusText, headers, body, charset);
case FORBIDDEN:
- return new HttpClientErrorException.Forbidden(message, statusText, headers, body, charset, url, method);
+ return message != null ?
+ new HttpClientErrorException.Forbidden(message, statusText, headers, body, charset) :
+ new HttpClientErrorException.Forbidden(statusText, headers, body, charset);
case NOT_FOUND:
- return new HttpClientErrorException.NotFound(message, statusText, headers, body, charset, url, method);
+ return message != null ?
+ new HttpClientErrorException.NotFound(message, statusText, headers, body, charset) :
+ new HttpClientErrorException.NotFound(statusText, headers, body, charset);
case METHOD_NOT_ALLOWED:
- return new HttpClientErrorException.MethodNotAllowed(message, statusText, headers, body, charset, url, method);
+ return message != null ?
+ new HttpClientErrorException.MethodNotAllowed(message, statusText, headers, body, charset) :
+ new HttpClientErrorException.MethodNotAllowed(statusText, headers, body, charset);
case NOT_ACCEPTABLE:
- return new HttpClientErrorException.NotAcceptable(message, statusText, headers, body, charset, url, method);
+ return message != null ?
+ new HttpClientErrorException.NotAcceptable(message, statusText, headers, body, charset) :
+ new HttpClientErrorException.NotAcceptable(statusText, headers, body, charset);
case CONFLICT:
- return new HttpClientErrorException.Conflict(message, statusText, headers, body, charset, url, method);
+ return message != null ?
+ new HttpClientErrorException.Conflict(message, statusText, headers, body, charset) :
+ new HttpClientErrorException.Conflict(statusText, headers, body, charset);
case GONE:
- return new HttpClientErrorException.Gone(message, statusText, headers, body, charset, url, method);
+ return message != null ?
+ new HttpClientErrorException.Gone(message, statusText, headers, body, charset) :
+ new HttpClientErrorException.Gone(statusText, headers, body, charset);
case UNSUPPORTED_MEDIA_TYPE:
- return new HttpClientErrorException.UnsupportedMediaType(message, statusText, headers, body, charset, url, method);
+ return message != null ?
+ new HttpClientErrorException.UnsupportedMediaType(message, statusText, headers, body, charset) :
+ new HttpClientErrorException.UnsupportedMediaType(statusText, headers, body, charset);
case TOO_MANY_REQUESTS:
- return new HttpClientErrorException.TooManyRequests(message, statusText, headers, body, charset, url, method);
+ return message != null ?
+ new HttpClientErrorException.TooManyRequests(message, statusText, headers, body, charset) :
+ new HttpClientErrorException.TooManyRequests(statusText, headers, body, charset);
case UNPROCESSABLE_ENTITY:
- return new HttpClientErrorException.UnprocessableEntity(message, statusText, headers, body, charset, url, method);
+ return message != null ?
+ new HttpClientErrorException.UnprocessableEntity(message, statusText, headers, body, charset) :
+ new HttpClientErrorException.UnprocessableEntity(statusText, headers, body, charset);
default:
- return new HttpClientErrorException(message, statusCode, statusText, headers, body, charset, url, method);
+ return message != null ?
+ new HttpClientErrorException(message, statusCode, statusText, headers, body, charset) :
+ new HttpClientErrorException(statusCode, statusText, headers, body, charset);
}
}
@@ -122,12 +156,16 @@ public static HttpClientErrorException create(
* @since 5.1
*/
@SuppressWarnings("serial")
- public static class BadRequest extends HttpClientErrorException {
+ public static final class BadRequest extends HttpClientErrorException {
- BadRequest(String message, String statusText, HttpHeaders headers, byte[] body, @Nullable Charset charset,
- @Nullable URI url, @Nullable HttpMethod method) {
+ private BadRequest(String statusText, HttpHeaders headers, byte[] body, @Nullable Charset charset) {
+ super(HttpStatus.BAD_REQUEST, statusText, headers, body, charset);
+ }
+
+ private BadRequest(String message, String statusText,
+ HttpHeaders headers, byte[] body, @Nullable Charset charset) {
- super(message, HttpStatus.BAD_REQUEST, statusText, headers, body, charset, url, method);
+ super(message, HttpStatus.BAD_REQUEST, statusText, headers, body, charset);
}
}
@@ -136,12 +174,16 @@ public static class BadRequest extends HttpClientErrorException {
* @since 5.1
*/
@SuppressWarnings("serial")
- public static class Unauthorized extends HttpClientErrorException {
+ public static final class Unauthorized extends HttpClientErrorException {
+
+ private Unauthorized(String statusText, HttpHeaders headers, byte[] body, @Nullable Charset charset) {
+ super(HttpStatus.UNAUTHORIZED, statusText, headers, body, charset);
+ }
- Unauthorized(String message, String statusText, HttpHeaders headers, byte[] body, @Nullable Charset charset,
- @Nullable URI url, @Nullable HttpMethod method) {
+ private Unauthorized(String message, String statusText,
+ HttpHeaders headers, byte[] body, @Nullable Charset charset) {
- super(message, HttpStatus.UNAUTHORIZED, statusText, headers, body, charset, url, method);
+ super(message, HttpStatus.UNAUTHORIZED, statusText, headers, body, charset);
}
}
@@ -150,12 +192,16 @@ public static class Unauthorized extends HttpClientErrorException {
* @since 5.1
*/
@SuppressWarnings("serial")
- public static class Forbidden extends HttpClientErrorException {
+ public static final class Forbidden extends HttpClientErrorException {
- Forbidden(String message, String statusText, HttpHeaders headers, byte[] body, @Nullable Charset charset,
- @Nullable URI url, @Nullable HttpMethod method) {
+ private Forbidden(String statusText, HttpHeaders headers, byte[] body, @Nullable Charset charset) {
+ super(HttpStatus.FORBIDDEN, statusText, headers, body, charset);
+ }
+
+ private Forbidden(String message, String statusText,
+ HttpHeaders headers, byte[] body, @Nullable Charset charset) {
- super(message, HttpStatus.FORBIDDEN, statusText, headers, body, charset, url, method);
+ super(message, HttpStatus.FORBIDDEN, statusText, headers, body, charset);
}
}
@@ -164,12 +210,16 @@ public static class Forbidden extends HttpClientErrorException {
* @since 5.1
*/
@SuppressWarnings("serial")
- public static class NotFound extends HttpClientErrorException {
+ public static final class NotFound extends HttpClientErrorException {
- NotFound(String message, String statusText, HttpHeaders headers, byte[] body, @Nullable Charset charset,
- @Nullable URI url, @Nullable HttpMethod method) {
+ private NotFound(String statusText, HttpHeaders headers, byte[] body, @Nullable Charset charset) {
+ super(HttpStatus.NOT_FOUND, statusText, headers, body, charset);
+ }
- super(message, HttpStatus.NOT_FOUND, statusText, headers, body, charset, url, method);
+ private NotFound(String message, String statusText,
+ HttpHeaders headers, byte[] body, @Nullable Charset charset) {
+
+ super(message, HttpStatus.NOT_FOUND, statusText, headers, body, charset);
}
}
@@ -178,12 +228,16 @@ public static class NotFound extends HttpClientErrorException {
* @since 5.1
*/
@SuppressWarnings("serial")
- public static class MethodNotAllowed extends HttpClientErrorException {
+ public static final class MethodNotAllowed extends HttpClientErrorException {
+
+ private MethodNotAllowed(String statusText, HttpHeaders headers, byte[] body, @Nullable Charset charset) {
+ super(HttpStatus.METHOD_NOT_ALLOWED, statusText, headers, body, charset);
+ }
- MethodNotAllowed(String message, String statusText, HttpHeaders headers, byte[] body, @Nullable Charset charset,
- @Nullable URI url, @Nullable HttpMethod method) {
+ private MethodNotAllowed(String message, String statusText,
+ HttpHeaders headers, byte[] body, @Nullable Charset charset) {
- super(message, HttpStatus.METHOD_NOT_ALLOWED, statusText, headers, body, charset, url, method);
+ super(message, HttpStatus.METHOD_NOT_ALLOWED, statusText, headers, body, charset);
}
}
@@ -192,12 +246,16 @@ public static class MethodNotAllowed extends HttpClientErrorException {
* @since 5.1
*/
@SuppressWarnings("serial")
- public static class NotAcceptable extends HttpClientErrorException {
+ public static final class NotAcceptable extends HttpClientErrorException {
- NotAcceptable(String message, String statusText, HttpHeaders headers, byte[] body, @Nullable Charset charset,
- @Nullable URI url, @Nullable HttpMethod method) {
+ private NotAcceptable(String statusText, HttpHeaders headers, byte[] body, @Nullable Charset charset) {
+ super(HttpStatus.NOT_ACCEPTABLE, statusText, headers, body, charset);
+ }
- super(message, HttpStatus.NOT_ACCEPTABLE, statusText, headers, body, charset, url, method);
+ private NotAcceptable(String message, String statusText,
+ HttpHeaders headers, byte[] body, @Nullable Charset charset) {
+
+ super(message, HttpStatus.NOT_ACCEPTABLE, statusText, headers, body, charset);
}
}
@@ -206,12 +264,14 @@ public static class NotAcceptable extends HttpClientErrorException {
* @since 5.1
*/
@SuppressWarnings("serial")
- public static class Conflict extends HttpClientErrorException {
+ public static final class Conflict extends HttpClientErrorException {
- Conflict(String message, String statusText, HttpHeaders headers, byte[] body, @Nullable Charset charset,
- @Nullable URI url, @Nullable HttpMethod method) {
+ private Conflict(String statusText, HttpHeaders headers, byte[] body, @Nullable Charset charset) {
+ super(HttpStatus.CONFLICT, statusText, headers, body, charset);
+ }
- super(message, HttpStatus.CONFLICT, statusText, headers, body, charset, url, method);
+ private Conflict(String message, String statusText, HttpHeaders headers, byte[] body, @Nullable Charset charset) {
+ super(message, HttpStatus.CONFLICT, statusText, headers, body, charset);
}
}
@@ -220,12 +280,14 @@ public static class Conflict extends HttpClientErrorException {
* @since 5.1
*/
@SuppressWarnings("serial")
- public static class Gone extends HttpClientErrorException {
+ public static final class Gone extends HttpClientErrorException {
- Gone(String message, String statusText, HttpHeaders headers, byte[] body, @Nullable Charset charset,
- @Nullable URI url, @Nullable HttpMethod method) {
+ private Gone(String statusText, HttpHeaders headers, byte[] body, @Nullable Charset charset) {
+ super(HttpStatus.GONE, statusText, headers, body, charset);
+ }
- super(message, HttpStatus.GONE, statusText, headers, body, charset, url, method);
+ private Gone(String message, String statusText, HttpHeaders headers, byte[] body, @Nullable Charset charset) {
+ super(message, HttpStatus.GONE, statusText, headers, body, charset);
}
}
@@ -234,12 +296,16 @@ public static class Gone extends HttpClientErrorException {
* @since 5.1
*/
@SuppressWarnings("serial")
- public static class UnsupportedMediaType extends HttpClientErrorException {
+ public static final class UnsupportedMediaType extends HttpClientErrorException {
- UnsupportedMediaType(String message, String statusText, HttpHeaders headers, byte[] body, @Nullable Charset charset,
- @Nullable URI url, @Nullable HttpMethod method) {
+ private UnsupportedMediaType(String statusText, HttpHeaders headers, byte[] body, @Nullable Charset charset) {
+ super(HttpStatus.UNSUPPORTED_MEDIA_TYPE, statusText, headers, body, charset);
+ }
+
+ private UnsupportedMediaType(String message, String statusText,
+ HttpHeaders headers, byte[] body, @Nullable Charset charset) {
- super(message, HttpStatus.UNSUPPORTED_MEDIA_TYPE, statusText, headers, body, charset, url, method);
+ super(message, HttpStatus.UNSUPPORTED_MEDIA_TYPE, statusText, headers, body, charset);
}
}
@@ -248,12 +314,16 @@ public static class UnsupportedMediaType extends HttpClientErrorException {
* @since 5.1
*/
@SuppressWarnings("serial")
- public static class UnprocessableEntity extends HttpClientErrorException {
+ public static final class UnprocessableEntity extends HttpClientErrorException {
+
+ private UnprocessableEntity(String statusText, HttpHeaders headers, byte[] body, @Nullable Charset charset) {
+ super(HttpStatus.UNPROCESSABLE_ENTITY, statusText, headers, body, charset);
+ }
- UnprocessableEntity(String message, String statusText, HttpHeaders headers, byte[] body, @Nullable Charset charset,
- @Nullable URI url, @Nullable HttpMethod method) {
+ private UnprocessableEntity(String message, String statusText,
+ HttpHeaders headers, byte[] body, @Nullable Charset charset) {
- super(message, HttpStatus.UNPROCESSABLE_ENTITY, statusText, headers, body, charset, url, method);
+ super(message, HttpStatus.UNPROCESSABLE_ENTITY, statusText, headers, body, charset);
}
}
@@ -262,12 +332,16 @@ public static class UnprocessableEntity extends HttpClientErrorException {
* @since 5.1
*/
@SuppressWarnings("serial")
- public static class TooManyRequests extends HttpClientErrorException {
+ public static final class TooManyRequests extends HttpClientErrorException {
+
+ private TooManyRequests(String statusText, HttpHeaders headers, byte[] body, @Nullable Charset charset) {
+ super(HttpStatus.TOO_MANY_REQUESTS, statusText, headers, body, charset);
+ }
- TooManyRequests(String message, String statusText, HttpHeaders headers, byte[] body, @Nullable Charset charset,
- @Nullable URI url, @Nullable HttpMethod method) {
+ private TooManyRequests(String message, String statusText,
+ HttpHeaders headers, byte[] body, @Nullable Charset charset) {
- super(message, HttpStatus.TOO_MANY_REQUESTS, statusText, headers, body, charset, url, method);
+ super(message, HttpStatus.TOO_MANY_REQUESTS, statusText, headers, body, charset);
}
}
diff --git a/spring-web/src/main/java/org/springframework/web/client/HttpErrorDetailsExtractor.java b/spring-web/src/main/java/org/springframework/web/client/HttpErrorDetailsExtractor.java
deleted file mode 100644
index d141549c8569..000000000000
--- a/spring-web/src/main/java/org/springframework/web/client/HttpErrorDetailsExtractor.java
+++ /dev/null
@@ -1,33 +0,0 @@
-package org.springframework.web.client;
-
-import java.net.URI;
-import java.nio.charset.Charset;
-
-import org.jetbrains.annotations.NotNull;
-import org.springframework.http.HttpMethod;
-import org.springframework.lang.Nullable;
-
-/**
- * Strategy interface used by the {@link DefaultResponseErrorHandler} to compose
- * a summary of the http error.
- *
- * @author Jerzy Krolak
- * @since 5.1
- */
-public interface HttpErrorDetailsExtractor {
-
- /**
- * Assemble HTTP error response details string, based on the provided response details.
- * @param rawStatusCode HTTP status code
- * @param statusText HTTP status text
- * @param responseBody response body
- * @param responseCharset response charset
- * @param url request URI
- * @param method request method
- * @return error details string
- */
- @NotNull
- String getErrorDetails(int rawStatusCode, String statusText, @Nullable byte[] responseBody,
- @Nullable Charset responseCharset, @Nullable URI url, @Nullable HttpMethod method);
-
-}
diff --git a/spring-web/src/main/java/org/springframework/web/client/HttpServerErrorException.java b/spring-web/src/main/java/org/springframework/web/client/HttpServerErrorException.java
index 4a63be5cf160..d45eb16da9ce 100644
--- a/spring-web/src/main/java/org/springframework/web/client/HttpServerErrorException.java
+++ b/spring-web/src/main/java/org/springframework/web/client/HttpServerErrorException.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");
* you may not use this file except in compliance with the License.
@@ -16,11 +16,9 @@
package org.springframework.web.client;
-import java.net.URI;
import java.nio.charset.Charset;
import org.springframework.http.HttpHeaders;
-import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.lang.Nullable;
@@ -69,35 +67,59 @@ public HttpServerErrorException(HttpStatus statusCode, String statusText,
}
/**
- * Constructor with a status code and status text, headers, content, request URL, and method.
+ * Constructor with a status code and status text, headers, content, and an
+ * prepared message.
+ * @since 5.2.2
*/
public HttpServerErrorException(String message, HttpStatus statusCode, String statusText,
- @Nullable HttpHeaders headers, @Nullable byte[] body, @Nullable Charset charset,
- @Nullable URI url, @Nullable HttpMethod method) {
- super(message, statusCode, statusText, headers, body, charset, url, method);
+ @Nullable HttpHeaders headers, @Nullable byte[] body, @Nullable Charset charset) {
+
+ super(message, statusCode, statusText, headers, body, charset);
}
/**
* Create an {@code HttpServerErrorException} or an HTTP status specific sub-class.
* @since 5.1
*/
- public static HttpServerErrorException create(
- String message, HttpStatus statusCode, String statusText, HttpHeaders headers, byte[] body,
- @Nullable Charset charset, @Nullable URI url, @Nullable HttpMethod method) {
+ public static HttpServerErrorException create(HttpStatus statusCode,
+ String statusText, HttpHeaders headers, byte[] body, @Nullable Charset charset) {
+
+ return create(null, statusCode, statusText, headers, body, charset);
+ }
+
+ /**
+ * Variant of {@link #create(String, HttpStatus, String, HttpHeaders, byte[], Charset)}
+ * with an optional prepared message.
+ * @since 5.2.2.
+ */
+ public static HttpServerErrorException create(@Nullable String message, HttpStatus statusCode,
+ String statusText, HttpHeaders headers, byte[] body, @Nullable Charset charset) {
switch (statusCode) {
case INTERNAL_SERVER_ERROR:
- return new HttpServerErrorException.InternalServerError(message, statusText, headers, body, charset, url, method);
+ return message != null ?
+ new HttpServerErrorException.InternalServerError(message, statusText, headers, body, charset) :
+ new HttpServerErrorException.InternalServerError(statusText, headers, body, charset);
case NOT_IMPLEMENTED:
- return new HttpServerErrorException.NotImplemented(message, statusText, headers, body, charset, url, method);
+ return message != null ?
+ new HttpServerErrorException.NotImplemented(message, statusText, headers, body, charset) :
+ new HttpServerErrorException.NotImplemented(statusText, headers, body, charset);
case BAD_GATEWAY:
- return new HttpServerErrorException.BadGateway(message, statusText, headers, body, charset, url, method);
+ return message != null ?
+ new HttpServerErrorException.BadGateway(message, statusText, headers, body, charset) :
+ new HttpServerErrorException.BadGateway(statusText, headers, body, charset);
case SERVICE_UNAVAILABLE:
- return new HttpServerErrorException.ServiceUnavailable(message, statusText, headers, body, charset, url, method);
+ return message != null ?
+ new HttpServerErrorException.ServiceUnavailable(message, statusText, headers, body, charset) :
+ new HttpServerErrorException.ServiceUnavailable(statusText, headers, body, charset);
case GATEWAY_TIMEOUT:
- return new HttpServerErrorException.GatewayTimeout(message, statusText, headers, body, charset, url, method);
+ return message != null ?
+ new HttpServerErrorException.GatewayTimeout(message, statusText, headers, body, charset) :
+ new HttpServerErrorException.GatewayTimeout(statusText, headers, body, charset);
default:
- return new HttpServerErrorException(message, statusCode, statusText, headers, body, charset, url, method);
+ return message != null ?
+ new HttpServerErrorException(message, statusCode, statusText, headers, body, charset) :
+ new HttpServerErrorException(statusCode, statusText, headers, body, charset);
}
}
@@ -109,12 +131,16 @@ public static HttpServerErrorException create(
* @since 5.1
*/
@SuppressWarnings("serial")
- public static class InternalServerError extends HttpServerErrorException {
+ public static final class InternalServerError extends HttpServerErrorException {
+
+ private InternalServerError(String statusText, HttpHeaders headers, byte[] body, @Nullable Charset charset) {
+ super(HttpStatus.INTERNAL_SERVER_ERROR, statusText, headers, body, charset);
+ }
- InternalServerError(String message, String statusText, HttpHeaders headers, byte[] body, @Nullable Charset charset,
- @Nullable URI url, @Nullable HttpMethod method) {
+ private InternalServerError(String message, String statusText,
+ HttpHeaders headers, byte[] body, @Nullable Charset charset) {
- super(message, HttpStatus.INTERNAL_SERVER_ERROR, statusText, headers, body, charset, url, method);
+ super(message, HttpStatus.INTERNAL_SERVER_ERROR, statusText, headers, body, charset);
}
}
@@ -123,12 +149,16 @@ public static class InternalServerError extends HttpServerErrorException {
* @since 5.1
*/
@SuppressWarnings("serial")
- public static class NotImplemented extends HttpServerErrorException {
+ public static final class NotImplemented extends HttpServerErrorException {
- NotImplemented(String message, String statusText, HttpHeaders headers, byte[] body, @Nullable Charset charset,
- @Nullable URI url, @Nullable HttpMethod method) {
+ private NotImplemented(String statusText, HttpHeaders headers, byte[] body, @Nullable Charset charset) {
+ super(HttpStatus.NOT_IMPLEMENTED, statusText, headers, body, charset);
+ }
+
+ private NotImplemented(String message, String statusText,
+ HttpHeaders headers, byte[] body, @Nullable Charset charset) {
- super(message, HttpStatus.NOT_IMPLEMENTED, statusText, headers, body, charset, url, method);
+ super(message, HttpStatus.NOT_IMPLEMENTED, statusText, headers, body, charset);
}
}
@@ -137,12 +167,16 @@ public static class NotImplemented extends HttpServerErrorException {
* @since 5.1
*/
@SuppressWarnings("serial")
- public static class BadGateway extends HttpServerErrorException {
+ public static final class BadGateway extends HttpServerErrorException {
+
+ private BadGateway(String statusText, HttpHeaders headers, byte[] body, @Nullable Charset charset) {
+ super(HttpStatus.BAD_GATEWAY, statusText, headers, body, charset);
+ }
- BadGateway(String message, String statusText, HttpHeaders headers, byte[] body, @Nullable Charset charset,
- @Nullable URI url, @Nullable HttpMethod method) {
+ private BadGateway(String message, String statusText,
+ HttpHeaders headers, byte[] body, @Nullable Charset charset) {
- super(message, HttpStatus.BAD_GATEWAY, statusText, headers, body, charset, url, method);
+ super(message, HttpStatus.BAD_GATEWAY, statusText, headers, body, charset);
}
}
@@ -151,12 +185,16 @@ public static class BadGateway extends HttpServerErrorException {
* @since 5.1
*/
@SuppressWarnings("serial")
- public static class ServiceUnavailable extends HttpServerErrorException {
+ public static final class ServiceUnavailable extends HttpServerErrorException {
- ServiceUnavailable(String message, String statusText, HttpHeaders headers, byte[] body, @Nullable Charset charset,
- @Nullable URI url, @Nullable HttpMethod method) {
+ private ServiceUnavailable(String statusText, HttpHeaders headers, byte[] body, @Nullable Charset charset) {
+ super(HttpStatus.SERVICE_UNAVAILABLE, statusText, headers, body, charset);
+ }
+
+ private ServiceUnavailable(String message, String statusText,
+ HttpHeaders headers, byte[] body, @Nullable Charset charset) {
- super(message, HttpStatus.SERVICE_UNAVAILABLE, statusText, headers, body, charset, url, method);
+ super(message, HttpStatus.SERVICE_UNAVAILABLE, statusText, headers, body, charset);
}
}
@@ -165,12 +203,16 @@ public static class ServiceUnavailable extends HttpServerErrorException {
* @since 5.1
*/
@SuppressWarnings("serial")
- public static class GatewayTimeout extends HttpServerErrorException {
+ public static final class GatewayTimeout extends HttpServerErrorException {
+
+ private GatewayTimeout(String statusText, HttpHeaders headers, byte[] body, @Nullable Charset charset) {
+ super(HttpStatus.GATEWAY_TIMEOUT, statusText, headers, body, charset);
+ }
- GatewayTimeout(String message, String statusText, HttpHeaders headers, byte[] body, @Nullable Charset charset,
- @Nullable URI url, @Nullable HttpMethod method) {
+ private GatewayTimeout(String message, String statusText,
+ HttpHeaders headers, byte[] body, @Nullable Charset charset) {
- super(message, HttpStatus.GATEWAY_TIMEOUT, statusText, headers, body, charset, url, method);
+ super(message, HttpStatus.GATEWAY_TIMEOUT, statusText, headers, body, charset);
}
}
diff --git a/spring-web/src/main/java/org/springframework/web/client/HttpStatusCodeException.java b/spring-web/src/main/java/org/springframework/web/client/HttpStatusCodeException.java
index 726e77558737..b660f15be870 100644
--- a/spring-web/src/main/java/org/springframework/web/client/HttpStatusCodeException.java
+++ b/spring-web/src/main/java/org/springframework/web/client/HttpStatusCodeException.java
@@ -16,11 +16,9 @@
package org.springframework.web.client;
-import java.net.URI;
import java.nio.charset.Charset;
import org.springframework.http.HttpHeaders;
-import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.lang.Nullable;
import org.springframework.util.StringUtils;
@@ -85,8 +83,8 @@ protected HttpStatusCodeException(HttpStatus statusCode, String statusText,
protected HttpStatusCodeException(HttpStatus statusCode, String statusText,
@Nullable HttpHeaders responseHeaders, @Nullable byte[] responseBody, @Nullable Charset responseCharset) {
- this(getMessage(statusCode, statusText), statusCode, statusText,
- responseHeaders, responseBody, responseCharset, null, null);
+ this(getMessage(statusCode, statusText),
+ statusCode, statusText, responseHeaders, responseBody, responseCharset);
}
/**
@@ -98,15 +96,12 @@ protected HttpStatusCodeException(HttpStatus statusCode, String statusText,
* @param responseHeaders the response headers, may be {@code null}
* @param responseBody the response body content, may be {@code null}
* @param responseCharset the response body charset, may be {@code null}
- * @param url the request URL, may be {@code null}
- * @param method the request method, may be {@code null}
+ * @since 5.2.2
*/
protected HttpStatusCodeException(String message, HttpStatus statusCode, String statusText,
- @Nullable HttpHeaders responseHeaders, @Nullable byte[] responseBody, @Nullable Charset responseCharset,
- @Nullable URI url, @Nullable HttpMethod method) {
+ @Nullable HttpHeaders responseHeaders, @Nullable byte[] responseBody, @Nullable Charset responseCharset) {
- super(message, statusCode.value(), statusText, responseHeaders, responseBody,
- responseCharset, url, method);
+ super(message, statusCode.value(), statusText, responseHeaders, responseBody, responseCharset);
this.statusCode = statusCode;
}
diff --git a/spring-web/src/main/java/org/springframework/web/client/RestClientResponseException.java b/spring-web/src/main/java/org/springframework/web/client/RestClientResponseException.java
index 5410096477a4..2a927f376905 100644
--- a/spring-web/src/main/java/org/springframework/web/client/RestClientResponseException.java
+++ b/spring-web/src/main/java/org/springframework/web/client/RestClientResponseException.java
@@ -17,12 +17,10 @@
package org.springframework.web.client;
import java.io.UnsupportedEncodingException;
-import java.net.URI;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import org.springframework.http.HttpHeaders;
-import org.springframework.http.HttpMethod;
import org.springframework.lang.Nullable;
/**
@@ -50,12 +48,6 @@ public class RestClientResponseException extends RestClientException {
@Nullable
private final String responseCharset;
- @Nullable
- private final HttpMethod method;
-
- @Nullable
- private final URI url;
-
/**
* Construct a new instance of with the given response data.
@@ -67,22 +59,6 @@ public class RestClientResponseException extends RestClientException {
*/
public RestClientResponseException(String message, int statusCode, String statusText,
@Nullable HttpHeaders responseHeaders, @Nullable byte[] responseBody, @Nullable Charset responseCharset) {
- this(message, statusCode, statusText, responseHeaders, responseBody, responseCharset, null, null);
- }
-
- /**
- * Construct a new instance of with the given response data.
- * @param statusCode the raw status code value
- * @param statusText the status text
- * @param responseHeaders the response headers (may be {@code null})
- * @param responseBody the response body content (may be {@code null})
- * @param responseCharset the response body charset (may be {@code null})
- * @param url the request URL (may be {@code null})
- * @param method the request method (may be {@code null})
- */
- public RestClientResponseException(String message, int statusCode, String statusText,
- @Nullable HttpHeaders responseHeaders, @Nullable byte[] responseBody, @Nullable Charset responseCharset,
- @Nullable URI url, @Nullable HttpMethod method) {
super(message);
this.rawStatusCode = statusCode;
@@ -90,8 +66,6 @@ public RestClientResponseException(String message, int statusCode, String status
this.responseHeaders = responseHeaders;
this.responseBody = (responseBody != null ? responseBody : new byte[0]);
this.responseCharset = (responseCharset != null ? responseCharset.name() : null);
- this.method = method;
- this.url = url;
}
@@ -124,20 +98,6 @@ public byte[] getResponseBodyAsByteArray() {
return this.responseBody;
}
- /**
- * Return the HTTP request method.
- */
- public HttpMethod getMethod() {
- return method;
- }
-
- /**
- * Return the HTTP request url.
- */
- public URI getUrl() {
- return url;
- }
-
/**
* Return the response body converted to String. The charset used is that
* of the response "Content-Type" or otherwise {@code "UTF-8"}.
diff --git a/spring-web/src/main/java/org/springframework/web/client/UnknownHttpStatusCodeException.java b/spring-web/src/main/java/org/springframework/web/client/UnknownHttpStatusCodeException.java
index 79d5544ad022..c7b0319018d4 100644
--- a/spring-web/src/main/java/org/springframework/web/client/UnknownHttpStatusCodeException.java
+++ b/spring-web/src/main/java/org/springframework/web/client/UnknownHttpStatusCodeException.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");
* you may not use this file except in compliance with the License.
@@ -16,11 +16,9 @@
package org.springframework.web.client;
-import java.net.URI;
import java.nio.charset.Charset;
import org.springframework.http.HttpHeaders;
-import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.lang.Nullable;
@@ -48,7 +46,7 @@ public UnknownHttpStatusCodeException(int rawStatusCode, String statusText, @Nul
@Nullable byte[] responseBody, @Nullable Charset responseCharset) {
this("Unknown status code [" + rawStatusCode + "]" + " " + statusText,
- rawStatusCode, statusText, responseHeaders, responseBody, responseCharset, null, null);
+ rawStatusCode, statusText, responseHeaders, responseBody, responseCharset);
}
/**
@@ -59,12 +57,11 @@ public UnknownHttpStatusCodeException(int rawStatusCode, String statusText, @Nul
* @param responseHeaders the response headers (may be {@code null})
* @param responseBody the response body content (may be {@code null})
* @param responseCharset the response body charset (may be {@code null})
- * @param url the request URI (may be {@code null})
- * @param method the request HTTP method (may be {@code null})
+ * @since 5.2.2
*/
- public UnknownHttpStatusCodeException(String message, int rawStatusCode, String statusText, @Nullable HttpHeaders responseHeaders,
- @Nullable byte[] responseBody, @Nullable Charset responseCharset, @Nullable URI url, @Nullable HttpMethod method) {
+ public UnknownHttpStatusCodeException(String message, int rawStatusCode, String statusText,
+ @Nullable HttpHeaders responseHeaders, @Nullable byte[] responseBody, @Nullable Charset responseCharset) {
- super(message, rawStatusCode, statusText, responseHeaders, responseBody, responseCharset, url, method);
+ super(message, rawStatusCode, statusText, responseHeaders, responseBody, responseCharset);
}
}
diff --git a/spring-web/src/test/java/org/springframework/web/client/DefaultHttpErrorDetailsExtractorTests.java b/spring-web/src/test/java/org/springframework/web/client/DefaultHttpErrorDetailsExtractorTests.java
deleted file mode 100644
index 94804ac69f8a..000000000000
--- a/spring-web/src/test/java/org/springframework/web/client/DefaultHttpErrorDetailsExtractorTests.java
+++ /dev/null
@@ -1,97 +0,0 @@
-package org.springframework.web.client;
-
-import java.net.URI;
-
-import com.google.common.base.Strings;
-import org.junit.Test;
-
-import static java.nio.charset.StandardCharsets.*;
-import static org.junit.Assert.*;
-import static org.springframework.http.HttpMethod.*;
-import static org.springframework.http.HttpStatus.*;
-
-public class DefaultHttpErrorDetailsExtractorTests {
-
- private final DefaultHttpErrorDetailsExtractor extractor = new DefaultHttpErrorDetailsExtractor();
-
- @Test
- public void shouldGetSimpleExceptionMessage() {
- String actual = extractor.getErrorDetails(NOT_FOUND.value(), "Not Found", null, null, null, null);
-
- assertEquals("Should get a simple message", "404 Not Found", actual);
- }
-
- @Test
- public void shouldGetCompleteMessageWithoutBody() {
- String actual = extractor.getErrorDetails(NOT_FOUND.value(), "Not Found", null, null, URI.create("http://localhost:8080/my-endpoint"), GET);
-
- assertEquals("Should get a complete message without body", "404 Not Found after GET http://localhost:8080/my-endpoint : [no body]", actual);
- }
-
- @Test
- public void shouldGetCompleteMessageWithShortAsciiBodyNoCharset() {
- String responseBody = "my short response body";
-
- String actual = extractor.getErrorDetails(NOT_FOUND.value(), "Not Found", responseBody.getBytes(), null, URI.create("http://localhost:8080/my-endpoint"), GET);
-
- assertEquals("Should get a simple message", "404 Not Found after GET http://localhost:8080/my-endpoint : [my short response body]", actual);
- }
-
- @Test
- public void shouldGetCompleteMessageWithShortAsciiBodyUtfCharset() {
- String responseBody = "my short response body";
-
- String actual = extractor.getErrorDetails(NOT_FOUND.value(), "Not Found", responseBody.getBytes(), UTF_8, URI.create("http://localhost:8080/my-endpoint"), GET);
-
- assertEquals("Should get a simple message", "404 Not Found after GET http://localhost:8080/my-endpoint : [my short response body]", actual);
- }
-
- @Test
- public void shouldGetCompleteMessageWithShortUtfBodyUtfCharset() {
- String responseBody = "my short response body \u0105\u0119";
-
- String actual = extractor.getErrorDetails(NOT_FOUND.value(), "Not Found", responseBody.getBytes(), UTF_8, URI.create("http://localhost:8080/my-endpoint"), GET);
-
- assertEquals("Should get a simple message", "404 Not Found after GET http://localhost:8080/my-endpoint : [my short response body \u0105\u0119]", actual);
- }
-
- @Test
- public void shouldGetCompleteMessageWithShortUtfBodyNoCharset() {
- String responseBody = "my short response body \u0105\u0119";
-
- String actual = extractor.getErrorDetails(NOT_FOUND.value(), "Not Found", responseBody.getBytes(UTF_8), null, URI.create("http://localhost:8080/my-endpoint"), GET);
-
- assertEquals("Should get a simple message", "404 Not Found after GET http://localhost:8080/my-endpoint : [my short response body \u00c4\u0085\u00c4\u0099]", actual);
- }
-
- @Test
- public void shouldGetCompleteMessageWithLongAsciiBodyNoCharset() {
- String responseBody = Strings.repeat("asdfg", 100);
- String expectedMessage = "404 Not Found after GET http://localhost:8080/my-endpoint : [" + Strings.repeat("asdfg", 40) + "... (500 bytes)]";
-
- String actual = extractor.getErrorDetails(NOT_FOUND.value(), "Not Found", responseBody.getBytes(UTF_8), null, URI.create("http://localhost:8080/my-endpoint"), GET);
-
- assertEquals("Should get a simple message", expectedMessage, actual);
- }
-
- @Test
- public void shouldGetCompleteMessageWithLongUtfBodyNoCharset() {
- String responseBody = Strings.repeat("asd\u0105\u0119", 100);
- String expectedMessage = "404 Not Found after GET http://localhost:8080/my-endpoint : [" + Strings.repeat("asd\u00c4\u0085\u00c4\u0099", 28) + "asd\u00c4... (700 bytes)]";
-
- String actual = extractor.getErrorDetails(NOT_FOUND.value(), "Not Found", responseBody.getBytes(UTF_8), null, URI.create("http://localhost:8080/my-endpoint"), GET);
-
- assertEquals("Should get a simple message", expectedMessage, actual);
- }
-
- @Test
- public void shouldGetCompleteMessageWithLongUtfBodyUtfCharset() {
- String responseBody = Strings.repeat("asd\u0105\u0119", 100);
- String expectedMessage = "404 Not Found after GET http://localhost:8080/my-endpoint : [" + Strings.repeat("asd\u0105\u0119", 40) + "... (700 bytes)]";
-
- String actual = extractor.getErrorDetails(NOT_FOUND.value(), "Not Found", responseBody.getBytes(UTF_8), UTF_8, URI.create("http://localhost:8080/my-endpoint"), GET);
-
- assertEquals("Should get a simple message", expectedMessage, actual);
- }
-
-}
\ No newline at end of file
diff --git a/spring-web/src/test/java/org/springframework/web/client/DefaultResponseErrorHandlerTests.java b/spring-web/src/test/java/org/springframework/web/client/DefaultResponseErrorHandlerTests.java
index e9f782609378..c5c05c48e426 100644
--- a/spring-web/src/test/java/org/springframework/web/client/DefaultResponseErrorHandlerTests.java
+++ b/spring-web/src/test/java/org/springframework/web/client/DefaultResponseErrorHandlerTests.java
@@ -19,8 +19,10 @@
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
+import java.util.function.Function;
import org.junit.jupiter.api.Test;
+import reactor.core.publisher.Flux;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
@@ -69,9 +71,28 @@ public void handleError() throws Exception {
given(response.getHeaders()).willReturn(headers);
given(response.getBody()).willReturn(new ByteArrayInputStream("Hello World".getBytes(StandardCharsets.UTF_8)));
- assertThatExceptionOfType(HttpClientErrorException.class).isThrownBy(() ->
- handler.handleError(response))
- .satisfies(ex -> assertThat(ex.getResponseHeaders()).isSameAs(headers));
+ assertThatExceptionOfType(HttpClientErrorException.class)
+ .isThrownBy(() -> handler.handleError(response))
+ .satisfies(ex -> assertThat(ex.getResponseHeaders()).isSameAs(headers))
+ .satisfies(ex -> assertThat(ex.getMessage()).isEqualTo("404 Not Found: [Hello World]"));
+ }
+
+ @Test
+ public void handleErrorWithLongBody() throws Exception {
+
+ Function