11/*
2- * Copyright 2002-2012 the original author or authors.
2+ * Copyright 2002-2017 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.
1717package org .springframework .web .client ;
1818
1919import java .io .IOException ;
20- import java .io .InputStream ;
2120import java .nio .charset .Charset ;
2221
2322import org .springframework .http .HttpHeaders ;
2726import org .springframework .util .FileCopyUtils ;
2827
2928/**
30- * Default implementation of the {@link ResponseErrorHandler} interface.
29+ * Spring's default implementation of the {@link ResponseErrorHandler} interface.
3130 *
32- * <p>This error handler checks for the status code on the {@link ClientHttpResponse}: any
33- * code with series {@link org.springframework.http.HttpStatus.Series#CLIENT_ERROR} or
31+ * <p>This error handler checks for the status code on the {@link ClientHttpResponse}:
32+ * Any code with series {@link org.springframework.http.HttpStatus.Series#CLIENT_ERROR} or
3433 * {@link org.springframework.http.HttpStatus.Series#SERVER_ERROR} is considered to be an
35- * error. This behavior can be changed by overriding the {@link #hasError(HttpStatus)}
36- * method.
34+ * error. This behavior can be changed by overriding the {@link #hasError(HttpStatus)} method.
3735 *
3836 * @author Arjen Poutsma
3937 * @author Rossen Stoyanchev
@@ -50,16 +48,45 @@ public boolean hasError(ClientHttpResponse response) throws IOException {
5048 return hasError (getHttpStatusCode (response ));
5149 }
5250
53- private HttpStatus getHttpStatusCode (ClientHttpResponse response ) throws IOException {
54- HttpStatus statusCode ;
51+ /**
52+ * This default implementation throws a {@link HttpClientErrorException} if the response status code
53+ * is {@link org.springframework.http.HttpStatus.Series#CLIENT_ERROR}, a {@link HttpServerErrorException}
54+ * if it is {@link org.springframework.http.HttpStatus.Series#SERVER_ERROR},
55+ * and a {@link RestClientException} in other cases.
56+ */
57+ @ Override
58+ public void handleError (ClientHttpResponse response ) throws IOException {
59+ HttpStatus statusCode = getHttpStatusCode (response );
60+ switch (statusCode .series ()) {
61+ case CLIENT_ERROR :
62+ throw new HttpClientErrorException (statusCode , response .getStatusText (),
63+ response .getHeaders (), getResponseBody (response ), getCharset (response ));
64+ case SERVER_ERROR :
65+ throw new HttpServerErrorException (statusCode , response .getStatusText (),
66+ response .getHeaders (), getResponseBody (response ), getCharset (response ));
67+ default :
68+ throw new RestClientException ("Unknown status code [" + statusCode + "]" );
69+ }
70+ }
71+
72+
73+ /**
74+ * Determine the HTTP status of the given response.
75+ * @param response the response to inspect
76+ * @return the associated HTTP status
77+ * @throws IOException in case of I/O errors
78+ * @throws UnknownHttpStatusCodeException in case of an unknown status code
79+ * that cannot be represented with the {@link HttpStatus} enum
80+ * @since 4.3.8
81+ */
82+ protected HttpStatus getHttpStatusCode (ClientHttpResponse response ) throws IOException {
5583 try {
56- statusCode = response .getStatusCode ();
84+ return response .getStatusCode ();
5785 }
5886 catch (IllegalArgumentException ex ) {
59- throw new UnknownHttpStatusCodeException (response .getRawStatusCode (),
60- response .getStatusText (), response . getHeaders (), getResponseBody (response ), getCharset (response ));
87+ throw new UnknownHttpStatusCodeException (response .getRawStatusCode (), response . getStatusText (),
88+ response .getHeaders (), getResponseBody (response ), getCharset (response ));
6189 }
62- return statusCode ;
6390 }
6491
6592 /**
@@ -70,50 +97,40 @@ private HttpStatus getHttpStatusCode(ClientHttpResponse response) throws IOExcep
7097 * Can be overridden in subclasses.
7198 * @param statusCode the HTTP status code
7299 * @return {@code true} if the response has an error; {@code false} otherwise
100+ * @see #getHttpStatusCode(ClientHttpResponse)
73101 */
74102 protected boolean hasError (HttpStatus statusCode ) {
75103 return (statusCode .series () == HttpStatus .Series .CLIENT_ERROR ||
76104 statusCode .series () == HttpStatus .Series .SERVER_ERROR );
77105 }
78106
79107 /**
80- * This default implementation throws a {@link HttpClientErrorException} if the response status code
81- * is {@link org.springframework.http.HttpStatus.Series#CLIENT_ERROR}, a {@link HttpServerErrorException}
82- * if it is {@link org.springframework.http.HttpStatus.Series#SERVER_ERROR},
83- * and a {@link RestClientException} in other cases.
108+ * Determine the charset of the response (for inclusion in a status exception).
109+ * @param response the response to inspect
110+ * @return the associated charset, or {@code null} if none
111+ * @since 4.3.8
84112 */
85- @ Override
86- public void handleError (ClientHttpResponse response ) throws IOException {
87- HttpStatus statusCode = getHttpStatusCode (response );
88- switch (statusCode .series ()) {
89- case CLIENT_ERROR :
90- throw new HttpClientErrorException (statusCode , response .getStatusText (),
91- response .getHeaders (), getResponseBody (response ), getCharset (response ));
92- case SERVER_ERROR :
93- throw new HttpServerErrorException (statusCode , response .getStatusText (),
94- response .getHeaders (), getResponseBody (response ), getCharset (response ));
95- default :
96- throw new RestClientException ("Unknown status code [" + statusCode + "]" );
97- }
113+ protected Charset getCharset (ClientHttpResponse response ) {
114+ HttpHeaders headers = response .getHeaders ();
115+ MediaType contentType = headers .getContentType ();
116+ return (contentType != null ? contentType .getCharset () : null );
98117 }
99118
100- private byte [] getResponseBody (ClientHttpResponse response ) {
119+ /**
120+ * Read the body of the given response (for inclusion in a status exception).
121+ * @param response the response to inspect
122+ * @return the response body as a byte array,
123+ * or an empty byte array if the body could not be read
124+ * @since 4.3.8
125+ */
126+ protected byte [] getResponseBody (ClientHttpResponse response ) {
101127 try {
102- InputStream responseBody = response .getBody ();
103- if (responseBody != null ) {
104- return FileCopyUtils .copyToByteArray (responseBody );
105- }
128+ return FileCopyUtils .copyToByteArray (response .getBody ());
106129 }
107130 catch (IOException ex ) {
108131 // ignore
109132 }
110133 return new byte [0 ];
111134 }
112135
113- private Charset getCharset (ClientHttpResponse response ) {
114- HttpHeaders headers = response .getHeaders ();
115- MediaType contentType = headers .getContentType ();
116- return contentType != null ? contentType .getCharset () : null ;
117- }
118-
119136}
0 commit comments