How to set MediaType to UTF-8 in restTemplate with json format

15,767

Solution 1

If the handler method return String type for @ResponseBody, default Message Converter is StringHttpMessageConverter, you can config the converter like this

    <mvc:annotation-driven >
    <mvc:message-converters>
        <bean class="org.springframework.http.converter.StringHttpMessageConverter">
            <property name="supportedMediaTypes">
                <list>
                    <value>text/plain;charset=UTF-8</value>
                </list>
            </property>
        </bean>
    </mvc:message-converters>
</mvc:annotation-driven>

Solution 2

Obviously it's a dirty hack, but Spring forced me to do it :) It works fine in our project. We're calling a method that changes StringHttpMessageConverter.DEFAULT_CHARSET reflectively after context initialization.

Create a class somewhere in your package:

public class CharsetPostProcessor implements InitializingBean, ApplicationContextAware {

    private ApplicationContext applicationContext;

    static void setFinalStatic(Field field, Object newValue) throws Exception {
        field.setAccessible(true);

        Field modifiersField = Field.class.getDeclaredField("modifiers");
        modifiersField.setAccessible(true);
        modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);

        field.set(null, newValue);
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

    @Override
    public void afterPropertiesSet() throws Exception {

        Field charsetField = applicationContext.getBean("stringHttpMessageConverter").getClass().getField("DEFAULT_CHARSET");
        Charset charset = Charset.forName("UTF-8");
        setFinalStatic(charsetField, charset);
    }
}

And add following into your Spring context definition:

<bean class="your.package.CharsetPostProcessor" />
<bean id="stringHttpMessageConverter" class="org.springframework.http.converter.StringHttpMessageConverter" />
Share:
15,767
Eric
Author by

Eric

I am working and living in Phnom Penh, Cambodia.

Updated on November 24, 2022

Comments

  • Eric
    Eric over 1 year

    I have one problem that I can't convert the data in json format to UTF-8 when the server response. I have set MediaType in spring configuration xml, but it seems not work. And here is my server side code to response:

        @RequestMapping(value = "/post",  method = RequestMethod.POST)
        public @ResponseBody String postData(@RequestBody ObjectNode request){
            // do something with request
            return response;
        }
    

    When server response, data in json format will contain value as unicode. And in client side configuration:

        <bean id="restTemplate" class="org.springframework.web.client.RestTemplate">
          <property name="messageConverters">
            <list>
                <bean id="formConverter" class="org.springframework.http.converter.FormHttpMessageConverter" />
                <bean id="stringConverter" class="org.springframework.http.converter.StringHttpMessageConverter" />
                <bean id="jsonConverter" class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter" >
                    <property name="supportedMediaTypes">
                          <list>
                            <bean class="org.springframework.http.MediaType">
                               <constructor-arg value="application" />
                               <constructor-arg value="json" />
                               <constructor-arg value="#{T(java.nio.charset.Charset).forName('UTF-8')}"/>
                             </bean>
                          </list>
                    </property>
                </bean>
            </list>
          </property>
        </bean>
    

    And here is my client side code to request for data, and I use postForObject method:

        @Autowired
        private RestTemplate restTemplate;
    
        public ObjectNode postObjectNode(ObjectNode request){
              ObjectNode node = restTemplate.postForObject("http://localhost:8080/server/post", request, ObjectNode.class);
              return node;
    }
    

    And as a result, data that contain the unicode will convert to ????. Is it cause by server or cause by restTemplate client. please help me. Thanks in advance...

    • chrylis -cautiouslyoptimistic-
      chrylis -cautiouslyoptimistic- over 10 years
      Start by checking the actual return results from the server. I recommend either using telnet to make the HTTP request by hand or using a tool like Wireshark to inspect the HTTP response. This should tell you which end is having trouble.
    • Larry.Z
      Larry.Z over 10 years
      What's the defalut response content-type? Can you post that?
  • Eric
    Eric over 10 years
    Thanks for your reply. And I keep my configuration the same but I change from String to ObjectNode when server response. And now it works.
  • Larry.Z
    Larry.Z over 10 years
    If you want to get json format for spring-mvc controller, return an Object is a good idea, spring convert json format automaticly with the correct charset.