3

When I am posting form request, spring is adding charset like application/x-www-form-urlencoded; charset=UTF-8 which causing problem to consume restful service. How can I remove the charset from RestTemplate to so the content-type is exactly application/x-www-form-urlencoded?

Tamim Addari
  • 7,591
  • 9
  • 40
  • 59
  • The issue is not clear.Can you provide more data like logs,sample code etc ? .Seems like a issue in this post : https://stackoverflow.com/questions/33796218/content-type-application-x-www-form-urlencodedcharset-utf-8-not-supported-for – Ananthapadmanabhan May 10 '19 at 05:42
  • Which method you use to send your request? How is your request body defined (String, Map)? As a consequence, what converter is used to encode your request body? – Lesiak May 10 '19 at 09:40
  • FormMessage converter, I actually went through the code. It seems like spring explicitly sets the charset in that converter. There is no way around. By the way, I use multivaluemap and used both postforentity and exchange. – Tamim Addari May 11 '19 at 10:06

2 Answers2

2

FormHttpMessageConverter makes a lot of validations to make sure you are using a MediaType with a valid charset. I would try either subclassing it and registering a new converter (there are a lot of private methods though), or converting your MultiValueMap to String payload manually (StringHttpMessageConverter is a lot less restrictive about Media Types)

HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
HttpEntity<String> entity = new HttpEntity<>("param1=value1", headers);
String result = restTemplate.postForObject( url, entity, String.class);
Lesiak
  • 22,088
  • 2
  • 41
  • 65
  • 1
    I ended up subclassing MediaType, HttpHeaders to work around it. But, I think there should a method to exclude contentType being added to the actual request. – Tamim Addari May 14 '19 at 03:35
1

I had the same problem. I solved it by removing the charset from the contenttype in the header after it was added.

class MyFormHttpMessageConverter extends FormHttpMessageConverter {


  @Override
  public void write(final MultiValueMap<String, ?> map, final MediaType contentType, final HttpOutputMessage outputMessage) throws IOException,
                                                                                                                                   HttpMessageNotWritableException {
    super.write(map, contentType, outputMessage);

    HttpHeaders headers = outputMessage.getHeaders();
    MediaType mediaType = headers.getContentType();
    if(Objects.nonNull(mediaType) && MapUtils.isNotEmpty(mediaType.getParameters())){
      Map<String, String> filteredParams =  mediaType.getParameters()
                                                     .entrySet()
                                                     .stream()
                                                     .filter(entry -> !entry.getKey().equals("charset"))
                                                     .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
      headers.setContentType(new MediaType(mediaType, filteredParams));
    }
  }
}
sge
  • 391
  • 2
  • 16