Spring Controller @ResponseBody text/xml 响应 UTF-8 编码问题

Posted

技术标签:

【中文标题】Spring Controller @ResponseBody text/xml 响应 UTF-8 编码问题【英文标题】:Spring Controller @ResponseBody text/xml response UTF-8 encoding issue 【发布时间】:2015-02-20 08:54:30 【问题描述】:

我在码头网络服务器(也是 tomcat)上运行基于注释的 Spring Rest 服务。控制器代码是:

@RequestMapping(method = RequestMethod.POST, value =  "/s-s-rfeed/exec/",
                "/query/exec" , consumes =  "application/xml", "text/xml",
                "application/x-www-form-urlencoded" , produces = 
                "application/xml;charset=UTF-8", "text/xml;charset=UTF-8",
                "application/x-www-form-urlencoded;charset=UTF-8" )
        @ResponseBody
        protected String getXmlFeed(HttpServletRequest request,
                @PathVariable String serviceName, @RequestBody String xmlReq) 

                //code....
                return appXMLResponse;
    

问题是控制器返回的响应 xml 包含一些字符,如 ä ö ü(元音变音符号)。在浏览器上呈现的响应给出了解析错误:

XML Parsing Error: not well-formed
Location: //localhost:8083/MySerice/s-s-rfeed/exec/
Line Number 18111, Column 17:
<FIRST_NAME>Tzee rfista</FIRST_NAME>
----------------^

(一个小三角形出现在ü的位置)

The expected is : <FIRST_NAME>Tzeeürfista</FIRST_NAME>

我尝试了以下解决方案,但问题仍然存在。

    参考technowobble上给出的解决方案尝试使用过滤器

    将字符集传递给 StringHttpMessageConverter 属性

    <bean id="restTemplate" class="org.springframework.web.client.RestTemplate">
        <property name="messageConverters">
            <list>
                <bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
                    <property name="supportedMediaTypes" value="application/json" />
                </bean>
                <bean class="org.springframework.http.converter.StringHttpMessageConverter">
                    <property name="supportedMediaTypes" value="text/xml;charset=UTF-8" />
                </bean>
            </list>
        </property>
    </bean>
    
    ref link

    在tomcat -web.xml中启用SetCharacterEncodingFilter

    将代码更改为返回 ResponseEntity 而不是 String 并删除 @ResponseBody

      protected ResponseEntity<String> getXmlFeed(HttpServletRequest
    request, @PathVariable String serviceName, @RequestBody String xmlReq)         
    //line of code
      HttpHeaders responseHeaders = new HttpHeaders();
      responseHeaders.add("Content-Type", "application/xml; charset=utf-8");
      return new ResponseEntity<String>(appXMLResponse, responseHeaders, HttpStatus.CREATED);
    
    
    

第 4 个解决方案有效但这是现有代码,我无法更改方法签名,因为它可能会影响该服务的现有客户端。任何想法/指针来解决这个问题?

【问题讨论】:

【参考方案1】:

在您的调度程序 servlet 上下文 xml 中,您必须添加一个属性。例如

<bean class = "org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<property name="messageConverters">
    <array>
        <bean class = "org.springframework.http.converter.StringHttpMessageConverter">
            <property name="supportedMediaTypes" value = "text/plain;charset=UTF-8" />
        </bean>
    </array>
</property>
</bean>

【讨论】:

我也试过了(选项#2),但没有解决问题。 我更新了代码部分你可以试试这个,StringHttpMessageConverter bean的简单声明是不够的,尝试将它注入AnnotationMethodHandlerAdapter,Spring MVC 3.1你可以使用MVC命名空间 我尝试了上面的sn-p,但问题仍然存在。【参考方案2】:

问题终于解决了。这就是我所做的。 1.使用StringHttpMessageConverter的构造函数设置charset为:

<bean id="stringHttpMessageConverter"
            class="org.springframework.http.converter.StringHttpMessageConverter">
            <constructor-arg index="0" name="defaultCharset" value="UTF-8"/>
            <property name="supportedMediaTypes">
                <list>
                    <value>application/xml</value>
                    <value>text/xml</value>
                    <value>application/x-www-form-urlencoded</value>
                </list>
            </property>
        </bean>

我还从我的项目中删除了不必要的 spring3.0 和 3.1 jar。这些不是必需的,而是躺在那里。 (应该早点做)。

这解决了我的问题。

【讨论】:

【参考方案3】:

我解决了我的编码问题没有这样的答案,所以我会发布它。

我在 Jetty 上运行了 Spring RestService。在响应正文部分,从数据库接收到的数据具有正确的 UTF-8 编码,但来自 .property 文件(带有错误和成功消息)的数据具有不正确的编码,就像 äöü...

起初我用 File->Settings->Editor->Code Style-> File Encodings 检查了 .property 文件本身的编码(这样你不仅可以检查而且可以设置你需要的编码) - 它是 UTF-8 .

然后我在我的 RestController 中设置响应编码@RequestMapping:

@RequestMapping(value = "/category/categoryId", method = RequestMethod.DELETE, produces =  "application/json;**charset=UTF-8**" )

并为 Jackson2 设置 defaultCharset 属性:

<bean id="jsonConverter" class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
    <property name="supportedMediaTypes" value="application/json;" />
    <property name="prettyPrint" value="true" />
    <property name="defaultCharset" value="UTF-8"/>
</bean>

没有结果。 但是后来我发现问题可以通过添加UTF-8编码来解决 从我的 .property 文件中获取数据的 PropertyPlaceholderConfigurer:

    <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="locations">
        <list>
            <value>classpath:app.properties</value>
            <value>classpath:database.properties</value>
            <value>classpath:ru.error.messages.properties</value>
            <value>classpath:ru.success.messages.properties</value>
        </list>
    </property>
    <property name="fileEncoding" value="UTF-8"/>
</bean>

...问题已经解决了)))

【讨论】:

以上是关于Spring Controller @ResponseBody text/xml 响应 UTF-8 编码问题的主要内容,如果未能解决你的问题,请参考以下文章

spring 处理异常

web注解

respon对象

Spring mvc Controller接口

Spring Boot Controller(篇二)

Spring Aop对Controller层拦截失效问题