SPR-7591 - HttpStatusCodeException should contain response body
This commit is contained in:
parent
6e516b7281
commit
70cb81b4b5
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
* Copyright 2002-2010 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.
|
||||
|
|
@ -17,9 +17,12 @@
|
|||
package org.springframework.web.client;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.Charset;
|
||||
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.client.ClientHttpResponse;
|
||||
import org.springframework.util.FileCopyUtils;
|
||||
|
||||
/**
|
||||
* Default implementation of the {@link ResponseErrorHandler} interface.
|
||||
|
|
@ -64,14 +67,18 @@ public class DefaultResponseErrorHandler implements ResponseErrorHandler {
|
|||
*/
|
||||
public void handleError(ClientHttpResponse response) throws IOException {
|
||||
HttpStatus statusCode = response.getStatusCode();
|
||||
MediaType contentType = response.getHeaders().getContentType();
|
||||
Charset charset = contentType != null ? contentType.getCharSet() : null;
|
||||
byte[] body = FileCopyUtils.copyToByteArray(response.getBody());
|
||||
switch (statusCode.series()) {
|
||||
case CLIENT_ERROR:
|
||||
throw new HttpClientErrorException(statusCode, response.getStatusText());
|
||||
throw new HttpClientErrorException(statusCode, response.getStatusText(), body, charset);
|
||||
case SERVER_ERROR:
|
||||
throw new HttpServerErrorException(statusCode, response.getStatusText());
|
||||
throw new HttpServerErrorException(statusCode, response.getStatusText(), body, charset);
|
||||
default:
|
||||
throw new RestClientException("Unknown status code [" + statusCode + "]");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -16,6 +16,8 @@
|
|||
|
||||
package org.springframework.web.client;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
|
||||
import org.springframework.http.HttpStatus;
|
||||
|
||||
/**
|
||||
|
|
@ -44,4 +46,19 @@ public class HttpClientErrorException extends HttpStatusCodeException {
|
|||
super(statusCode, statusText);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new instance of {@code HttpClientErrorException} based on a {@link HttpStatus}, status text, and
|
||||
* response body content.
|
||||
*
|
||||
* @param statusCode the status code
|
||||
* @param statusText the status text
|
||||
* @param responseBody the response body content, may be {@code null}
|
||||
* @param responseCharset the response body charset, may be {@code null}
|
||||
*/
|
||||
public HttpClientErrorException(HttpStatus statusCode,
|
||||
String statusText,
|
||||
byte[] responseBody,
|
||||
Charset responseCharset) {
|
||||
super(statusCode, statusText, responseBody, responseCharset);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,19 +16,22 @@
|
|||
|
||||
package org.springframework.web.client;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
|
||||
import org.springframework.http.HttpStatus;
|
||||
|
||||
/**
|
||||
* Exception thrown when an HTTP 5xx is received.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
* @since 3.0
|
||||
* @see DefaultResponseErrorHandler
|
||||
* @since 3.0
|
||||
*/
|
||||
public class HttpServerErrorException extends HttpStatusCodeException {
|
||||
|
||||
/**
|
||||
* Construct a new instance of {@code HttpServerErrorException} based on a {@link HttpStatus}.
|
||||
*
|
||||
* @param statusCode the status code
|
||||
*/
|
||||
public HttpServerErrorException(HttpStatus statusCode) {
|
||||
|
|
@ -37,6 +40,7 @@ public class HttpServerErrorException extends HttpStatusCodeException {
|
|||
|
||||
/**
|
||||
* Construct a new instance of {@code HttpServerErrorException} based on a {@link HttpStatus} and status text.
|
||||
*
|
||||
* @param statusCode the status code
|
||||
* @param statusText the status text
|
||||
*/
|
||||
|
|
@ -44,4 +48,20 @@ public class HttpServerErrorException extends HttpStatusCodeException {
|
|||
super(statusCode, statusText);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new instance of {@code HttpServerErrorException} based on a {@link HttpStatus}, status text, and
|
||||
* response body content.
|
||||
*
|
||||
* @param statusCode the status code
|
||||
* @param statusText the status text
|
||||
* @param responseBody the response body content, may be {@code null}
|
||||
* @param responseCharset the response body charset, may be {@code null}
|
||||
* @since 3.0.5
|
||||
*/
|
||||
public HttpServerErrorException(HttpStatus statusCode,
|
||||
String statusText,
|
||||
byte[] responseBody,
|
||||
Charset responseCharset) {
|
||||
super(statusCode, statusText, responseBody, responseCharset);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
* Copyright 2002-2010 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,6 +16,9 @@
|
|||
|
||||
package org.springframework.web.client;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.nio.charset.Charset;
|
||||
|
||||
import org.springframework.http.HttpStatus;
|
||||
|
||||
/**
|
||||
|
|
@ -26,33 +29,56 @@ import org.springframework.http.HttpStatus;
|
|||
*/
|
||||
public abstract class HttpStatusCodeException extends RestClientException {
|
||||
|
||||
private static final Charset DEFAULT_CHARSET = Charset.forName("ISO-8859-1");
|
||||
|
||||
private final HttpStatus statusCode;
|
||||
|
||||
private final String statusText;
|
||||
|
||||
private final byte[] responseBody;
|
||||
|
||||
private final Charset responseCharset;
|
||||
|
||||
/**
|
||||
* Construct a new instance of {@code HttpStatusCodeException} based on a {@link HttpStatus}.
|
||||
*
|
||||
* @param statusCode the status code
|
||||
*/
|
||||
protected HttpStatusCodeException(HttpStatus statusCode) {
|
||||
super(statusCode.toString());
|
||||
this.statusCode = statusCode;
|
||||
this.statusText = statusCode.name();
|
||||
this(statusCode, statusCode.name(), null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new instance of {@code HttpStatusCodeException} based on a {@link HttpStatus} and status text.
|
||||
*
|
||||
* @param statusCode the status code
|
||||
* @param statusText the status text
|
||||
*/
|
||||
protected HttpStatusCodeException(HttpStatus statusCode, String statusText) {
|
||||
this(statusCode, statusText, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new instance of {@code HttpStatusCodeException} based on a {@link HttpStatus}, status text, and
|
||||
* response body content.
|
||||
*
|
||||
* @param statusCode the status code
|
||||
* @param statusText the status text
|
||||
* @param responseBody the response body content, may be {@code null}
|
||||
* @param responseCharset the response body charset, may be {@code null}
|
||||
* @since 3.0.5
|
||||
*/
|
||||
protected HttpStatusCodeException(HttpStatus statusCode,
|
||||
String statusText,
|
||||
byte[] responseBody,
|
||||
Charset responseCharset) {
|
||||
super(statusCode.value() + " " + statusText);
|
||||
this.statusCode = statusCode;
|
||||
this.statusText = statusText;
|
||||
this.responseBody = responseBody != null ? responseBody : new byte[0];
|
||||
this.responseCharset = responseCharset != null ? responseCharset : DEFAULT_CHARSET;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the HTTP status code.
|
||||
*/
|
||||
|
|
@ -67,4 +93,27 @@ public abstract class HttpStatusCodeException extends RestClientException {
|
|||
return this.statusText;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the response body as a byte array.
|
||||
*
|
||||
* @since 3.0.5
|
||||
*/
|
||||
public byte[] getResponseBodyAsByteArray() {
|
||||
return responseBody;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the response body as a string.
|
||||
*
|
||||
* @since 3.0.5
|
||||
*/
|
||||
public String getResponseBodyAsString() {
|
||||
try {
|
||||
return new String(responseBody, responseCharset.name());
|
||||
}
|
||||
catch (UnsupportedEncodingException ex) {
|
||||
// should not occur
|
||||
throw new InternalError(ex.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -145,14 +145,30 @@ public class RestTemplateIntegrationTests {
|
|||
assertEquals("Invalid content", helloWorld, s);
|
||||
}
|
||||
|
||||
@Test(expected = HttpClientErrorException.class)
|
||||
@Test
|
||||
public void notFound() {
|
||||
try {
|
||||
template.execute(URI + "/errors/notfound", HttpMethod.GET, null, null);
|
||||
fail("HttpClientErrorException expected");
|
||||
}
|
||||
catch (HttpClientErrorException ex) {
|
||||
assertEquals(HttpStatus.NOT_FOUND, ex.getStatusCode());
|
||||
assertNotNull(ex.getStatusText());
|
||||
assertNotNull(ex.getResponseBodyAsString());
|
||||
}
|
||||
}
|
||||
|
||||
@Test(expected = HttpServerErrorException.class)
|
||||
@Test
|
||||
public void serverError() {
|
||||
try {
|
||||
template.execute(URI + "/errors/server", HttpMethod.GET, null, null);
|
||||
fail("HttpServerErrorException expected");
|
||||
}
|
||||
catch (HttpServerErrorException ex) {
|
||||
assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, ex.getStatusCode());
|
||||
assertNotNull(ex.getStatusText());
|
||||
assertNotNull(ex.getResponseBodyAsString());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
|||
Loading…
Reference in New Issue