Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Add UnknownHttpStatusCodeException

This is more specific exception raised instead of RestClientException
when the raw HTTP status code received from the server is not one of
the HttpStatus enum values.

Issue: SPR-9406
  • Loading branch information...
commit f528c394567373166f36153035072e77d6df748c 1 parent de38c03
Rossen Stoyanchev authored
8 spring-web/src/main/java/org/springframework/http/HttpStatus.java
View
@@ -445,8 +445,8 @@ public int value() {
return this.value;
}
- private static Series valueOf(HttpStatus status) {
- int seriesCode = status.value() / 100;
+ public static Series valueOf(int status) {
+ int seriesCode = status / 100;
for (Series series : values()) {
if (series.value == seriesCode) {
return series;
@@ -455,6 +455,10 @@ private static Series valueOf(HttpStatus status) {
throw new IllegalArgumentException("No matching constant for [" + status + "]");
}
+ public static Series valueOf(HttpStatus status) {
+ return valueOf(status.value);
+ }
+
}
}
26 spring-web/src/main/java/org/springframework/web/client/DefaultResponseErrorHandler.java
View
@@ -36,6 +36,7 @@
* method.
*
* @author Arjen Poutsma
+ * @author Rossen Stoyanchev
* @since 3.0
* @see RestTemplate#setErrorHandler
*/
@@ -45,16 +46,17 @@
* Delegates to {@link #hasError(HttpStatus)} with the response status code.
*/
public boolean hasError(ClientHttpResponse response) throws IOException {
- return hasError(getStatusCode(response));
+ return hasError(getHttpStatusCode(response));
}
- private HttpStatus getStatusCode(ClientHttpResponse response) throws IOException {
+ private HttpStatus getHttpStatusCode(ClientHttpResponse response) throws IOException {
HttpStatus statusCode;
try {
statusCode = response.getStatusCode();
}
catch (IllegalArgumentException ex) {
- throw new RestClientException("Unknown status code [" + response.getRawStatusCode() + "]");
+ throw new UnknownHttpStatusCodeException(response.getRawStatusCode(),
+ response.getStatusText(), response.getHeaders(), getResponseBody(response), getCharset(response));
}
return statusCode;
}
@@ -80,16 +82,14 @@ protected boolean hasError(HttpStatus statusCode) {
* and a {@link RestClientException} in other cases.
*/
public void handleError(ClientHttpResponse response) throws IOException {
- HttpStatus statusCode = getStatusCode(response);
- HttpHeaders headers = response.getHeaders();
- MediaType contentType = headers.getContentType();
- Charset charset = contentType != null ? contentType.getCharSet() : null;
- byte[] body = getResponseBody(response);
+ HttpStatus statusCode = getHttpStatusCode(response);
switch (statusCode.series()) {
case CLIENT_ERROR:
- throw new HttpClientErrorException(statusCode, response.getStatusText(), headers, body, charset);
+ throw new HttpClientErrorException(statusCode, response.getStatusText(),
+ response.getHeaders(), getResponseBody(response), getCharset(response));
case SERVER_ERROR:
- throw new HttpServerErrorException(statusCode, response.getStatusText(), headers, body, charset);
+ throw new HttpServerErrorException(statusCode, response.getStatusText(),
+ response.getHeaders(), getResponseBody(response), getCharset(response));
default:
throw new RestClientException("Unknown status code [" + statusCode + "]");
}
@@ -108,4 +108,10 @@ public void handleError(ClientHttpResponse response) throws IOException {
return new byte[0];
}
+ private Charset getCharset(ClientHttpResponse response) {
+ HttpHeaders headers = response.getHeaders();
+ MediaType contentType = headers.getContentType();
+ return contentType != null ? contentType.getCharSet() : null;
+ }
+
}
108 spring-web/src/main/java/org/springframework/web/client/UnknownHttpStatusCodeException.java
View
@@ -0,0 +1,108 @@
+/*
+ * Copyright 2002-2012 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.springframework.web.client;
+
+import java.io.UnsupportedEncodingException;
+import java.nio.charset.Charset;
+
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpStatus;
+
+/**
+ * Exception thrown when an unknown (or custom) HTTP status code is received.
+ *
+ * @author Rossen Stoyanchev
+ * @since 3.2
+ */
+public class UnknownHttpStatusCodeException extends RestClientException {
+
+ private static final long serialVersionUID = 4702443689088991600L;
+
+ private static final String DEFAULT_CHARSET = "ISO-8859-1";
+
+ private final int rawStatusCode;
+
+ private final String statusText;
+
+ private final byte[] responseBody;
+
+ private final HttpHeaders responseHeaders;
+
+ private final String responseCharset;
+
+
+ /**
+ * Construct a new instance of {@code HttpStatusCodeException} based on an
+ * {@link HttpStatus}, status text, and response body content.
+ * @param rawStatusCode 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}
+ */
+ public UnknownHttpStatusCodeException(int rawStatusCode, String statusText,
+ HttpHeaders responseHeaders, byte[] responseBody, Charset responseCharset) {
+
+ super("Unknown status code [" + String.valueOf(rawStatusCode) + "]" + " " + statusText);
+ this.rawStatusCode = rawStatusCode;
+ this.statusText = statusText;
+ this.responseHeaders = responseHeaders;
+ this.responseBody = responseBody != null ? responseBody : new byte[0];
+ this.responseCharset = responseCharset != null ? responseCharset.name() : DEFAULT_CHARSET;
+ }
+
+ /**
+ * Return the raw HTTP status code value.
+ */
+ public int getRawStatusCode() {
+ return this.rawStatusCode;
+ }
+
+ /**
+ * Return the HTTP status text.
+ */
+ public String getStatusText() {
+ return this.statusText;
+ }
+
+ /**
+ * Return the HTTP response headers.
+ */
+ public HttpHeaders getResponseHeaders() {
+ return this.responseHeaders;
+ }
+
+ /**
+ * Return the response body as a byte array.
+ */
+ public byte[] getResponseBodyAsByteArray() {
+ return responseBody;
+ }
+
+ /**
+ * Return the response body as a string.
+ */
+ public String getResponseBodyAsString() {
+ try {
+ return new String(responseBody, responseCharset);
+ }
+ catch (UnsupportedEncodingException ex) {
+ // should not occur
+ throw new InternalError(ex.getMessage());
+ }
+ }
+
+}
14 spring-web/src/test/java/org/springframework/web/client/DefaultResponseErrorHandlerTests.java
View
@@ -75,7 +75,7 @@ public void handleError() throws Exception {
expect(response.getStatusCode()).andReturn(HttpStatus.NOT_FOUND);
expect(response.getStatusText()).andReturn("Not Found");
- expect(response.getHeaders()).andReturn(headers);
+ expect(response.getHeaders()).andReturn(headers).atLeastOnce();
expect(response.getBody()).andReturn(new ByteArrayInputStream("Hello World".getBytes("UTF-8")));
replay(response);
@@ -98,7 +98,7 @@ public void handleErrorIOException() throws Exception {
expect(response.getStatusCode()).andReturn(HttpStatus.NOT_FOUND);
expect(response.getStatusText()).andReturn("Not Found");
- expect(response.getHeaders()).andReturn(headers);
+ expect(response.getHeaders()).andReturn(headers).atLeastOnce();
expect(response.getBody()).andThrow(new IOException());
replay(response);
@@ -115,7 +115,7 @@ public void handleErrorNullResponse() throws Exception {
expect(response.getStatusCode()).andReturn(HttpStatus.NOT_FOUND);
expect(response.getStatusText()).andReturn("Not Found");
- expect(response.getHeaders()).andReturn(headers);
+ expect(response.getHeaders()).andReturn(headers).atLeastOnce();
expect(response.getBody()).andReturn(null);
replay(response);
@@ -127,10 +127,16 @@ public void handleErrorNullResponse() throws Exception {
// SPR-9406
- @Test(expected=RestClientException.class)
+ @Test(expected=UnknownHttpStatusCodeException.class)
public void unknownStatusCode() throws Exception {
+ HttpHeaders headers = new HttpHeaders();
+ headers.setContentType(MediaType.TEXT_PLAIN);
+
expect(response.getStatusCode()).andThrow(new IllegalArgumentException("No matching constant for 999"));
expect(response.getRawStatusCode()).andReturn(999);
+ expect(response.getStatusText()).andReturn("Custom status code");
+ expect(response.getHeaders()).andReturn(headers).atLeastOnce();
+ expect(response.getBody()).andReturn(null);
replay(response);
2  src/dist/changelog.txt
View
@@ -58,7 +58,7 @@ Changes in version 3.2 RC1 (2012-11-02)
* support inferred base package for @ComponentScan (SPR-9586)
* sort candidate @AspectJ methods deterministically (SPR-9729)
* improve SimpleStreamingClientHttpRequest performance (SPR-9530)
-
+* added UnknownHttpStatusCodeException (SPR-9406)
Changes in version 3.2 M2 (2012-09-11)
--------------------------------------
Please sign in to comment.
Something went wrong with that request. Please try again.