Skip to content

Commit 9a8e59b

Browse files
committed
Added response HttpHeaders to HttpStatusCodeException and subclasses
Default HTTP errors from RestTemplate now include the response headers in addition to the response body. In particular, this enables inspection of the Content-Type header allowing manual deserialization of the response body without guessing as to the content type. * introduced HttpStatusCodeException#getResponseHeaders * added constructor with headers param for HttpStatusCodeException, HttpClientErrorException and HttpServerErrorException * preserved exsisting constructor signatures * marked HttpHeaders as Serializable * generated new serialVersionUID where needed Issue: SPR-7938
1 parent 94f8393 commit 9a8e59b

File tree

6 files changed

+98
-14
lines changed

6 files changed

+98
-14
lines changed

Diff for: spring-web/src/main/java/org/springframework/http/HttpHeaders.java

+5-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2011 the original author or authors.
2+
* Copyright 2002-2012 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -16,6 +16,7 @@
1616

1717
package org.springframework.http;
1818

19+
import java.io.Serializable;
1920
import java.net.URI;
2021
import java.nio.charset.Charset;
2122
import java.text.ParseException;
@@ -54,7 +55,9 @@
5455
* @author Arjen Poutsma
5556
* @since 3.0
5657
*/
57-
public class HttpHeaders implements MultiValueMap<String, String> {
58+
public class HttpHeaders implements MultiValueMap<String, String>, Serializable {
59+
60+
private static final long serialVersionUID = -8578554704772377436L;
5861

5962
private static final String ACCEPT = "Accept";
6063

Diff for: spring-web/src/main/java/org/springframework/web/client/DefaultResponseErrorHandler.java

+6-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2011 the original author or authors.
2+
* Copyright 2002-2012 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -20,6 +20,7 @@
2020
import java.io.InputStream;
2121
import java.nio.charset.Charset;
2222

23+
import org.springframework.http.HttpHeaders;
2324
import org.springframework.http.HttpStatus;
2425
import org.springframework.http.MediaType;
2526
import org.springframework.http.client.ClientHttpResponse;
@@ -68,14 +69,15 @@ protected boolean hasError(HttpStatus statusCode) {
6869
*/
6970
public void handleError(ClientHttpResponse response) throws IOException {
7071
HttpStatus statusCode = response.getStatusCode();
71-
MediaType contentType = response.getHeaders().getContentType();
72+
HttpHeaders headers = response.getHeaders();
73+
MediaType contentType = headers.getContentType();
7274
Charset charset = contentType != null ? contentType.getCharSet() : null;
7375
byte[] body = getResponseBody(response);
7476
switch (statusCode.series()) {
7577
case CLIENT_ERROR:
76-
throw new HttpClientErrorException(statusCode, response.getStatusText(), body, charset);
78+
throw new HttpClientErrorException(statusCode, response.getStatusText(), headers, body, charset);
7779
case SERVER_ERROR:
78-
throw new HttpServerErrorException(statusCode, response.getStatusText(), body, charset);
80+
throw new HttpServerErrorException(statusCode, response.getStatusText(), headers, body, charset);
7981
default:
8082
throw new RestClientException("Unknown status code [" + statusCode + "]");
8183
}

Diff for: spring-web/src/main/java/org/springframework/web/client/HttpClientErrorException.java

+20-1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
import java.nio.charset.Charset;
2020

21+
import org.springframework.http.HttpHeaders;
2122
import org.springframework.http.HttpStatus;
2223

2324
/**
@@ -29,7 +30,7 @@
2930
*/
3031
public class HttpClientErrorException extends HttpStatusCodeException {
3132

32-
private static final long serialVersionUID = 6777393766937023392L;
33+
private static final long serialVersionUID = 5177019431887513952L;
3334

3435
/**
3536
* Construct a new instance of {@code HttpClientErrorException} based on a {@link HttpStatus}.
@@ -63,4 +64,22 @@ public HttpClientErrorException(HttpStatus statusCode,
6364
Charset responseCharset) {
6465
super(statusCode, statusText, responseBody, responseCharset);
6566
}
67+
68+
/**
69+
* Construct a new instance of {@code HttpClientErrorException} based on a {@link HttpStatus}, status text, and
70+
* response body content.
71+
*
72+
* @param statusCode the status code
73+
* @param statusText the status text
74+
* @param responseHeaders the response headers, may be {@code null}
75+
* @param responseBody the response body content, may be {@code null}
76+
* @param responseCharset the response body charset, may be {@code null}
77+
*/
78+
public HttpClientErrorException(HttpStatus statusCode,
79+
String statusText,
80+
HttpHeaders responseHeaders,
81+
byte[] responseBody,
82+
Charset responseCharset) {
83+
super(statusCode, statusText, responseHeaders, responseBody, responseCharset);
84+
}
6685
}

Diff for: spring-web/src/main/java/org/springframework/web/client/HttpServerErrorException.java

+21-1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
import java.nio.charset.Charset;
2020

21+
import org.springframework.http.HttpHeaders;
2122
import org.springframework.http.HttpStatus;
2223

2324
/**
@@ -29,7 +30,7 @@
2930
*/
3031
public class HttpServerErrorException extends HttpStatusCodeException {
3132

32-
private static final long serialVersionUID = -2565832100451369997L;
33+
private static final long serialVersionUID = -2915754006618138282L;
3334

3435
/**
3536
* Construct a new instance of {@code HttpServerErrorException} based on a {@link HttpStatus}.
@@ -66,4 +67,23 @@ public HttpServerErrorException(HttpStatus statusCode,
6667
Charset responseCharset) {
6768
super(statusCode, statusText, responseBody, responseCharset);
6869
}
70+
71+
/**
72+
* Construct a new instance of {@code HttpServerErrorException} based on a {@link HttpStatus}, status text, and
73+
* response body content.
74+
*
75+
* @param statusCode the status code
76+
* @param statusText the status text
77+
* @param responseHeaders the response headers, may be {@code null}
78+
* @param responseBody the response body content, may be {@code null}
79+
* @param responseCharset the response body charset, may be {@code null}
80+
* @since 3.2.0
81+
*/
82+
public HttpServerErrorException(HttpStatus statusCode,
83+
String statusText,
84+
HttpHeaders responseHeaders,
85+
byte[] responseBody,
86+
Charset responseCharset) {
87+
super(statusCode, statusText, responseHeaders, responseBody, responseCharset);
88+
}
6989
}

Diff for: spring-web/src/main/java/org/springframework/web/client/HttpStatusCodeException.java

+35-3
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import java.io.UnsupportedEncodingException;
2020
import java.nio.charset.Charset;
2121

22+
import org.springframework.http.HttpHeaders;
2223
import org.springframework.http.HttpStatus;
2324

2425
/**
@@ -30,7 +31,7 @@
3031
*/
3132
public abstract class HttpStatusCodeException extends RestClientException {
3233

33-
private static final long serialVersionUID = 1549626836533638803L;
34+
private static final long serialVersionUID = -5807494703720513267L;
3435

3536
private static final String DEFAULT_CHARSET = "ISO-8859-1";
3637

@@ -40,6 +41,8 @@ public abstract class HttpStatusCodeException extends RestClientException {
4041

4142
private final byte[] responseBody;
4243

44+
private final HttpHeaders responseHeaders;
45+
4346
private final String responseCharset;
4447

4548
/**
@@ -48,7 +51,7 @@ public abstract class HttpStatusCodeException extends RestClientException {
4851
* @param statusCode the status code
4952
*/
5053
protected HttpStatusCodeException(HttpStatus statusCode) {
51-
this(statusCode, statusCode.name(), null, null);
54+
this(statusCode, statusCode.name(), null, null, null);
5255
}
5356

5457
/**
@@ -58,7 +61,7 @@ protected HttpStatusCodeException(HttpStatus statusCode) {
5861
* @param statusText the status text
5962
*/
6063
protected HttpStatusCodeException(HttpStatus statusCode, String statusText) {
61-
this(statusCode, statusText, null, null);
64+
this(statusCode, statusText, null, null, null);
6265
}
6366

6467
/**
@@ -75,9 +78,29 @@ protected HttpStatusCodeException(HttpStatus statusCode,
7578
String statusText,
7679
byte[] responseBody,
7780
Charset responseCharset) {
81+
this(statusCode, statusText, null, responseBody, responseCharset);
82+
}
83+
84+
/**
85+
* Construct a new instance of {@code HttpStatusCodeException} based on a {@link HttpStatus}, status text, and
86+
* response body content.
87+
*
88+
* @param statusCode the status code
89+
* @param statusText the status text
90+
* @param responseHeaders the response headers, may be {@code null}
91+
* @param responseBody the response body content, may be {@code null}
92+
* @param responseCharset the response body charset, may be {@code null}
93+
* @since 3.2.0
94+
*/
95+
protected HttpStatusCodeException(HttpStatus statusCode,
96+
String statusText,
97+
HttpHeaders responseHeaders,
98+
byte[] responseBody,
99+
Charset responseCharset) {
78100
super(statusCode.value() + " " + statusText);
79101
this.statusCode = statusCode;
80102
this.statusText = statusText;
103+
this.responseHeaders = responseHeaders;
81104
this.responseBody = responseBody != null ? responseBody : new byte[0];
82105
this.responseCharset = responseCharset != null ? responseCharset.name() : DEFAULT_CHARSET;
83106
}
@@ -96,6 +119,15 @@ public String getStatusText() {
96119
return this.statusText;
97120
}
98121

122+
/**
123+
* Returns the HTTP response headers.
124+
*
125+
* @since 3.2.0
126+
*/
127+
public HttpHeaders getResponseHeaders() {
128+
return this.responseHeaders;
129+
}
130+
99131
/**
100132
* Returns the response body as a byte array.
101133
*

Diff for: spring-web/src/test/java/org/springframework/web/client/DefaultResponseErrorHandlerTests.java

+11-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2011 the original author or authors.
2+
* Copyright 2002-2012 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -29,7 +29,9 @@
2929

3030
import static org.easymock.EasyMock.*;
3131
import static org.junit.Assert.assertFalse;
32+
import static org.junit.Assert.assertSame;
3233
import static org.junit.Assert.assertTrue;
34+
import static org.junit.Assert.fail;
3335

3436
/** @author Arjen Poutsma */
3537
public class DefaultResponseErrorHandlerTests {
@@ -64,7 +66,7 @@ public void hasErrorFalse() throws Exception {
6466
verify(response);
6567
}
6668

67-
@Test(expected = HttpClientErrorException.class)
69+
@Test
6870
public void handleError() throws Exception {
6971
HttpHeaders headers = new HttpHeaders();
7072
headers.setContentType(MediaType.TEXT_PLAIN);
@@ -76,7 +78,13 @@ public void handleError() throws Exception {
7678

7779
replay(response);
7880

79-
handler.handleError(response);
81+
try {
82+
handler.handleError(response);
83+
fail("expected HttpClientErrorException");
84+
}
85+
catch (HttpClientErrorException e) {
86+
assertSame(headers, e.getResponseHeaders());
87+
}
8088

8189
verify(response);
8290
}

0 commit comments

Comments
 (0)