Java Spring RestTemplate sets unwanted headers

Even upgrading to spring-web 5.2 solves the problem as writeAcceptCharset is default set to false in it


This values are adding by StringHttpMessageConverter class. To solve your issue you need to add following code:

List<HttpMessageConverter<?>> converters = new ArrayList<>();
StringHttpMessageConverter stringConverter = new StringHttpMessageConverter();
stringConverter.setWriteAcceptCharset(false);
converters.add(stringConverter);
restTemplate.setMessageConverters(converters);

The problem is that you are using a default configured RestTemplate and are writing a String body. This combination leads to a default configured StringHttpMessageConverter being used, which has the writeAcceptCharset set to true. Which will lead to all available charsets being added as a header.

Now you have 2 ways of fixing this.

  1. Don't write a plain String but write another object which will marshal the object to a String bypassing the StringHttpMessageConverter.
  2. Reconfigure the StringHttpMessageConverter and set the writeAcceptCharset to false.

Using Marshalling

public class Message {
    private String message;
    Message() {}
    public String getMessage() { this.message;}
    public void setMessage(String message) { this.message=message;}
}

Next use this Message class instead of the plain String JSON body.

Message msg = new Message();
msg.setMessage("I am very frustrated.");
RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
List<Charset> acceptCharset = Collections.singletonList(StandardCharsets.UTF_8);
headers.setAcceptCharset(acceptCharset);
log.info(headers.toString());

HttpEntity<Message> entity = new HttpEntity<>(msg, headers);
ResponseEntity<String> res = restTemplate.exchange("http://httpbin.org/post", HttpMethod.POST, entity, String.class);
String httpbin = res.getBody();

log.info("httpbin result: " + httpbin);

However there is a slight change in the request, the Content-Type header changes from text/plain to application/json. Not sure if that is what you want (although you are actually sending JSON and not plain text).

Reconfigure the StringHttpMessageConverter

 RestTemplate restTemplate = new RestTemplate();
 for (HttpMessageConverter converter : restTemplate.getMessageConverters) {
     if (converter instanceof StringHttpMessageConverter) {
         ((StringHttpMessageConverter) converter).setWriteAcceptCharset(false);
     }
 }

This will only write the configured charsets to the response.

Tags:

Java

Spring