Browse Source

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
pull/64/merge
Chris Beams 13 years ago
parent
commit
2ff43726be
  1. 4
      spring-web/src/main/java/org/springframework/web/client/HttpClientErrorException.java
  2. 4
      spring-web/src/main/java/org/springframework/web/client/HttpServerErrorException.java
  3. 13
      spring-web/src/main/java/org/springframework/web/client/HttpStatusCodeException.java
  4. 57
      spring-web/src/test/java/org/springframework/web/client/HttpStatusCodeExceptionTests.java

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

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* 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.
@ -29,6 +29,8 @@ import org.springframework.http.HttpStatus; @@ -29,6 +29,8 @@ import org.springframework.http.HttpStatus;
*/
public class HttpClientErrorException extends HttpStatusCodeException {
private static final long serialVersionUID = 6777393766937023392L;
/**
* Construct a new instance of {@code HttpClientErrorException} based on a {@link HttpStatus}.
* @param statusCode the status code

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

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* 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.
@ -29,6 +29,8 @@ import org.springframework.http.HttpStatus; @@ -29,6 +29,8 @@ import org.springframework.http.HttpStatus;
*/
public class HttpServerErrorException extends HttpStatusCodeException {
private static final long serialVersionUID = -2565832100451369997L;
/**
* Construct a new instance of {@code HttpServerErrorException} based on a {@link HttpStatus}.
*

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

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* 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.
@ -25,11 +25,14 @@ import org.springframework.http.HttpStatus; @@ -25,11 +25,14 @@ import org.springframework.http.HttpStatus;
* Abstract base class for exceptions based on an {@link HttpStatus}.
*
* @author Arjen Poutsma
* @author Chris Beams
* @since 3.0
*/
public abstract class HttpStatusCodeException extends RestClientException {
private static final Charset DEFAULT_CHARSET = Charset.forName("ISO-8859-1");
private static final long serialVersionUID = 1549626836533638803L;
private static final String DEFAULT_CHARSET = "ISO-8859-1";
private final HttpStatus statusCode;
@ -37,7 +40,7 @@ public abstract class HttpStatusCodeException extends RestClientException { @@ -37,7 +40,7 @@ public abstract class HttpStatusCodeException extends RestClientException {
private final byte[] responseBody;
private final Charset responseCharset;
private final String responseCharset;
/**
* Construct a new instance of {@code HttpStatusCodeException} based on a {@link HttpStatus}.
@ -76,7 +79,7 @@ public abstract class HttpStatusCodeException extends RestClientException { @@ -76,7 +79,7 @@ public abstract class HttpStatusCodeException extends RestClientException {
this.statusCode = statusCode;
this.statusText = statusText;
this.responseBody = responseBody != null ? responseBody : new byte[0];
this.responseCharset = responseCharset != null ? responseCharset : DEFAULT_CHARSET;
this.responseCharset = responseCharset != null ? responseCharset.name() : DEFAULT_CHARSET;
}
/**
@ -109,7 +112,7 @@ public abstract class HttpStatusCodeException extends RestClientException { @@ -109,7 +112,7 @@ public abstract class HttpStatusCodeException extends RestClientException {
*/
public String getResponseBodyAsString() {
try {
return new String(responseBody, responseCharset.name());
return new String(responseBody, responseCharset);
}
catch (UnsupportedEncodingException ex) {
// should not occur

57
spring-web/src/test/java/org/springframework/web/client/HttpStatusCodeExceptionTests.java

@ -0,0 +1,57 @@ @@ -0,0 +1,57 @@
/*
* 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.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.nio.charset.Charset;
import org.junit.Test;
import org.springframework.http.HttpStatus;
import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.*;
/**
* Unit tests for {@link HttpStatusCodeException} and subclasses.
*
* @author Chris Beams
*/
public class HttpStatusCodeExceptionTests {
/**
* Corners bug SPR-9273, which reported the fact that following the changes made in
* SPR-7591, {@link HttpStatusCodeException} and subtypes became no longer
* serializable due to the addition of a non-serializable {@link Charset} field.
*/
@Test
public void testSerializability() throws IOException, ClassNotFoundException {
HttpStatusCodeException ex1 = new HttpClientErrorException(
HttpStatus.BAD_REQUEST, null, null, Charset.forName("US-ASCII"));
ByteArrayOutputStream out = new ByteArrayOutputStream();
new ObjectOutputStream(out).writeObject(ex1);
ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
HttpStatusCodeException ex2 =
(HttpStatusCodeException) new ObjectInputStream(in).readObject();
assertThat(ex2.getResponseBodyAsString(), equalTo(ex1.getResponseBodyAsString()));
}
}
Loading…
Cancel
Save