001/* 002 * Copyright 2002-2019 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * https://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.springframework.web.client; 018 019import java.io.UnsupportedEncodingException; 020import java.nio.charset.Charset; 021import java.nio.charset.StandardCharsets; 022 023import org.springframework.http.HttpHeaders; 024import org.springframework.lang.Nullable; 025 026/** 027 * Common base class for exceptions that contain actual HTTP response data. 028 * 029 * @author Rossen Stoyanchev 030 * @since 4.3 031 */ 032public class RestClientResponseException extends RestClientException { 033 034 private static final long serialVersionUID = -8803556342728481792L; 035 036 private static final Charset DEFAULT_CHARSET = StandardCharsets.UTF_8; 037 038 039 private final int rawStatusCode; 040 041 private final String statusText; 042 043 private final byte[] responseBody; 044 045 @Nullable 046 private final HttpHeaders responseHeaders; 047 048 @Nullable 049 private final String responseCharset; 050 051 052 /** 053 * Construct a new instance of with the given response data. 054 * @param statusCode the raw status code value 055 * @param statusText the status text 056 * @param responseHeaders the response headers (may be {@code null}) 057 * @param responseBody the response body content (may be {@code null}) 058 * @param responseCharset the response body charset (may be {@code null}) 059 */ 060 public RestClientResponseException(String message, int statusCode, String statusText, 061 @Nullable HttpHeaders responseHeaders, @Nullable byte[] responseBody, @Nullable Charset responseCharset) { 062 063 super(message); 064 this.rawStatusCode = statusCode; 065 this.statusText = statusText; 066 this.responseHeaders = responseHeaders; 067 this.responseBody = (responseBody != null ? responseBody : new byte[0]); 068 this.responseCharset = (responseCharset != null ? responseCharset.name() : null); 069 } 070 071 072 /** 073 * Return the raw HTTP status code value. 074 */ 075 public int getRawStatusCode() { 076 return this.rawStatusCode; 077 } 078 079 /** 080 * Return the HTTP status text. 081 */ 082 public String getStatusText() { 083 return this.statusText; 084 } 085 086 /** 087 * Return the HTTP response headers. 088 */ 089 @Nullable 090 public HttpHeaders getResponseHeaders() { 091 return this.responseHeaders; 092 } 093 094 /** 095 * Return the response body as a byte array. 096 */ 097 public byte[] getResponseBodyAsByteArray() { 098 return this.responseBody; 099 } 100 101 /** 102 * Return the response body converted to String. The charset used is that 103 * of the response "Content-Type" or otherwise {@code "UTF-8"}. 104 */ 105 public String getResponseBodyAsString() { 106 return getResponseBodyAsString(DEFAULT_CHARSET); 107 } 108 109 /** 110 * Return the response body converted to String. The charset used is that 111 * of the response "Content-Type" or otherwise the one given. 112 * @param fallbackCharset the charset to use on if the response doesn't specify. 113 * @since 5.1.11 114 */ 115 public String getResponseBodyAsString(Charset fallbackCharset) { 116 if (this.responseCharset == null) { 117 return new String(this.responseBody, fallbackCharset); 118 } 119 try { 120 return new String(this.responseBody, this.responseCharset); 121 } 122 catch (UnsupportedEncodingException ex) { 123 // should not occur 124 throw new IllegalStateException(ex); 125 } 126 } 127 128}