I am using Spring RestTemplate and having issue while catching an HttpClientErrorException
with postForEntity()
. The Exception's getResponseBodyAsString()
method gets some random characters in the String
value.
try{
HttpEntity<Object> reqEntity = new HttpEntity<Object>(objPayload, headers);
ResponseEntity<Object> resEntity = restTemplate.postForEntity(url, reqEntity, Object.class);
} catch(HttpStatusCodeException he) {
log.error("Exception Status: {} - {}", he.getStatusCode(), he.getStatusText());
log.error("Exception - header {} ", he.getResponseHeaders());
log.error("\n Exception - message {} ", he.getResponseBodyAsString());
}
Exception message:
2024-02-01 14:48:28.801 ERROR [http-nio-8888-exec-2][APIController:318] Exception Status: 400 BAD_REQUEST - Bad Request
<br/>
2024-02-01 14:48:28.802 ERROR [http-nio-8888-exec-2][APIController:319] Exception - header : [X-API-Mode:"Sandbox", Content-Encoding:"gzip", Content-Type:"application/json", Content-Length:"192", Server:"server-Gateway", Date:"Thu, 01 Feb 2024 19:48:28 GMT", Connection:"close", Server-Timing:"cdn-cache; desc=MISS", "edge; dur=25", "origin; dur=753", "ak_p; desc="1706816908113_1611090436_118439255_77820_5277_40_0_-";dur=1"]
The returned String
with the strange characters:
2024-02-01 14:48:28.802 ERROR [http-nio-8888-exec-2][APIController:320]
Exception - message � ��
�@F_�2��ҝd� �hQ���\k�f`�&��������F�m@��Y�E!��-a�m�4Y��<�]��jݩ��3���A�Q(�i
˪:�6��Rֱ<^�ZV����1+�'���w-#Ӳ�n0V��p�Ͳq����wg,�ǀ���u ��I� `À/�c����$u^�
Making a request to the same endpoint using Postman I can't reproduce the issue:
{
"transactionId": "063dfe4c-07c3-4dc1-b495-e0ae41520",
"errors": [
{
"code": "INVALID.INPUT.EXCEPTION",
"message": "Invalid field value"
}
]
}
The Content-Encoding
in the log says gzip
which means the API you are calling is returning a response compressed in gzip format, which Postman can decompress and display as JSON. However the default RestTemplate
lacks the ability to decompress JSON, hence the strange characters in the log. You can customize the RestTemplate
bean to internally use Apache HttpClient
, which can handle gzip compressed responses.
Bean definition:
import org.apache.hc.client5.http.impl.classic.HttpClientBuilder;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;
@Configuration
public class AppConfig {
@Bean
public RestTemplate restTemplate(RestTemplateBuilder restTemplateBuilder) {
HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(
HttpClientBuilder.create().build()
);
RestTemplate restTemplate = restTemplateBuilder.build();
restTemplate.setRequestFactory(requestFactory);
return restTemplate;
}
}
Additional dependency:
implementation group: 'org.apache.httpcomponents.client5', name: 'httpclient5', version: '5.3.1'