Results 1 to 10 of 16

Thread: @ResponseBody and UTF-8

Hybrid View

  1. #1
    Join Date
    Dec 2009
    Posts
    4

    Default @ResponseBody and UTF-8

    I have a method annotated with @ResponseBody and returning a string. The String contains Unicode characters, but when my browser renders my the response, all I see are ?? in place of the Unicode characters. I've also tried using a CharacterEncodingFilter and setting the encoding to UTF-8 and force encoding to true. This hasn't worked for the HTTP response either.

    Is there a way to let Spring know the returned content encoding is UTF-8? The only other way I see is not use Spring and write the content directly to the HttpServletResponse.

    Thanks.

  2. #2
    Join Date
    Jul 2006
    Posts
    26

    Default

    Not sure this will solve your problem, but I've solved quite a lot of my character set problems using this in my web.xml:

    Code:
    <filter>
    	<filter-name>characterEncodingFilter</filter-name>
    	<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    	<init-param>
    		<param-name>encoding</param-name>
    		<param-value>UTF-8</param-value>
    	</init-param>
    	<init-param>
    		<param-name>forceEncoding</param-name>
    		<param-value>true</param-value>
    	</init-param>
    </filter>

  3. #3
    Join Date
    Oct 2006
    Posts
    228

    Default

    Make sure you declare the CharacterEncodingFilter as the first filter in web.xml and that you are using at least Servlet version 2.4 (check your web.xml version declaration) as forceEncoding won't work for earlier versions

  4. #4

    Default

    CharacterEncodingFilter can't help here, because String returned by @RequestBody-annotated method is encoded by StringHttpMessageConverter, which deduces the encoding from its specified content-type ("text/plain;charset=ISO-8859-1" by default). If you want to use @RequestBody, probably, you can reconfigure it something this way:
    Code:
    <bean class = "org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
    	<property name = "messageConverters">
    		<list>
    			<bean class = "org.springframework.http.converter.StringHttpMessageConverter">
    				<property name = "supportedMediaTypes">
    					<list>
    						text/plain;charset=UTF-8
    					</list>
    				</property>
    			</bean>
    		</list>
    	</property>
    </bean>

  5. #5
    Join Date
    Dec 2009
    Posts
    1

    Default

    sometimes this codes can work, but sometimes not.
    Code:
    <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
     <property name = "messageConverters">
      <list>
       <bean class = "org.springframework.http.converter.StringHttpMessageConverter">
       <property name = "supportedMediaTypes">
        <list>
         <value>text/plain;charset=UTF-8</value>
        </list>
       </property>
       </bean>
      </list>
     </property>
    </bean>
    your will get error HTTP Error 406, when the request parameter Accept is '*/*', and you can't set the value with '*' ;

    So, I suggest that you configure like this
    Code:
    <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
     <property name = "messageConverters">
      <list>
       <bean class = "org.springframework.http.converter.StringHttpMessageConverter">
       <property name = "supportedMediaTypes">
        <list>
         <bean class="org.springframework.http.MediaType">
          <constructor-arg index="0" value="text"/>
          <constructor-arg index="1" value="plain"/>
          <constructor-arg index="2" value="UTF-8"/>
         </bean>
         <bean class="org.springframework.http.MediaType">
          <constructor-arg index="0" value="*"/>
          <constructor-arg index="1" value="*"/>
          <constructor-arg index="2" value="UTF-8"/>
         </bean>
        </list>
       </property>
       </bean>
      </list>
     </property>
    </bean>

  6. #6
    Join Date
    Jun 2006
    Posts
    7

    Default

    The proposed solution fails when the client doesn't specify the proper ACCEPT header, that would result in a 406. Also, the above solution does not work because */* is not allowed for MediaTypes (no matter how clever you are at constructing them).

    StringHttpMessageConverter should allow the DEFAULT_CHARSET to be set instead. This way you can configure it to return UTF-8 by default. All it would take is a simple setter: setDefaultCharset(String charset).

    That would solve the problem where the client's ACCEPT header is empty, and setting the MediaType is therefore not an option.


    UPDATE: Looking at the code I can see why a setter cannot be used. The value is needed in the constructor (super() call). Maybe an alternative would be to provide a constructor that would look like this:

    private static final Charset DEFAULT_CHARSET = Charset.forName("ISO-8859-1");

    public ConfigurableStringHttpMessageConverter() {
    this(DEFAULT_CHARSET);
    }

    public ConfigurableStringHttpMessageConverter(Charset defaultCharset) {
    super(new MediaType("text", "plain", defaultCharset), MediaType.ALL);
    this.availableCharsets = new ArrayList<Charset>(Charset.availableCharsets().val ues());
    }
    The bean would only need:

    <bean id="stringHttpMessageConverter"
    class="org.springframework.http.converter.StringHt tpMessageConverter">
    <constructor-arg value="UTF-8"/>
    </bean>
    I have implemented my own ConfigurableStringHttpMessageConverter (essentially a copy of StringHttpMessageConverter) and it works fine.
    Last edited by springbee; Feb 23rd, 2010 at 11:16 AM. Reason: added constructor code

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •