Skip to content

Commit 2ff4372

Browse files
committed
Restore serializability of HttpStatusCodeException
SPR-7591 introduced a java.nio.charset.Charset field within HttpStatusCodeException. The former is non-serializable, thus by extension the latter also became non-serializable. Because the Charset field is only used for outputting the charset name in HttpStatusCodeException#getResponseBodyAsString, it is reasonable to store the value returned by Charset#name() instead of the actual Charset object itself. This commit refactors HttpStatusCodeException's responseCharset field to be of type String instead of Charset and adds tests to prove that HttpStatusCodeException objects are once again serializable as expected. Issue: SPR-9273, SPR-7591
1 parent 9a856c0 commit 2ff4372

File tree

4 files changed

+71
-7
lines changed

4 files changed

+71
-7
lines changed

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2010 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,6 +29,8 @@
2929
*/
3030
public class HttpClientErrorException extends HttpStatusCodeException {
3131

32+
private static final long serialVersionUID = 6777393766937023392L;
33+
3234
/**
3335
* Construct a new instance of {@code HttpClientErrorException} based on a {@link HttpStatus}.
3436
* @param statusCode the status code

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2010 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,6 +29,8 @@
2929
*/
3030
public class HttpServerErrorException extends HttpStatusCodeException {
3131

32+
private static final long serialVersionUID = -2565832100451369997L;
33+
3234
/**
3335
* Construct a new instance of {@code HttpServerErrorException} based on a {@link HttpStatus}.
3436
*

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

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2010 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.
@@ -25,19 +25,22 @@
2525
* Abstract base class for exceptions based on an {@link HttpStatus}.
2626
*
2727
* @author Arjen Poutsma
28+
* @author Chris Beams
2829
* @since 3.0
2930
*/
3031
public abstract class HttpStatusCodeException extends RestClientException {
3132

32-
private static final Charset DEFAULT_CHARSET = Charset.forName("ISO-8859-1");
33+
private static final long serialVersionUID = 1549626836533638803L;
34+
35+
private static final String DEFAULT_CHARSET = "ISO-8859-1";
3336

3437
private final HttpStatus statusCode;
3538

3639
private final String statusText;
3740

3841
private final byte[] responseBody;
3942

40-
private final Charset responseCharset;
43+
private final String responseCharset;
4144

4245
/**
4346
* Construct a new instance of {@code HttpStatusCodeException} based on a {@link HttpStatus}.
@@ -76,7 +79,7 @@ protected HttpStatusCodeException(HttpStatus statusCode,
7679
this.statusCode = statusCode;
7780
this.statusText = statusText;
7881
this.responseBody = responseBody != null ? responseBody : new byte[0];
79-
this.responseCharset = responseCharset != null ? responseCharset : DEFAULT_CHARSET;
82+
this.responseCharset = responseCharset != null ? responseCharset.name() : DEFAULT_CHARSET;
8083
}
8184

8285
/**
@@ -109,7 +112,7 @@ public byte[] getResponseBodyAsByteArray() {
109112
*/
110113
public String getResponseBodyAsString() {
111114
try {
112-
return new String(responseBody, responseCharset.name());
115+
return new String(responseBody, responseCharset);
113116
}
114117
catch (UnsupportedEncodingException ex) {
115118
// should not occur
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
/*
2+
* Copyright 2002-2012 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.web.client;
18+
19+
import java.io.ByteArrayInputStream;
20+
import java.io.ByteArrayOutputStream;
21+
import java.io.IOException;
22+
import java.io.ObjectInputStream;
23+
import java.io.ObjectOutputStream;
24+
import java.nio.charset.Charset;
25+
26+
import org.junit.Test;
27+
import org.springframework.http.HttpStatus;
28+
29+
import static org.hamcrest.CoreMatchers.*;
30+
31+
import static org.junit.Assert.*;
32+
33+
/**
34+
* Unit tests for {@link HttpStatusCodeException} and subclasses.
35+
*
36+
* @author Chris Beams
37+
*/
38+
public class HttpStatusCodeExceptionTests {
39+
40+
/**
41+
* Corners bug SPR-9273, which reported the fact that following the changes made in
42+
* SPR-7591, {@link HttpStatusCodeException} and subtypes became no longer
43+
* serializable due to the addition of a non-serializable {@link Charset} field.
44+
*/
45+
@Test
46+
public void testSerializability() throws IOException, ClassNotFoundException {
47+
HttpStatusCodeException ex1 = new HttpClientErrorException(
48+
HttpStatus.BAD_REQUEST, null, null, Charset.forName("US-ASCII"));
49+
ByteArrayOutputStream out = new ByteArrayOutputStream();
50+
new ObjectOutputStream(out).writeObject(ex1);
51+
ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
52+
HttpStatusCodeException ex2 =
53+
(HttpStatusCodeException) new ObjectInputStream(in).readObject();
54+
assertThat(ex2.getResponseBodyAsString(), equalTo(ex1.getResponseBodyAsString()));
55+
}
56+
57+
}

0 commit comments

Comments
 (0)