Spring表单和UTF-8坏编码

时间:2015-03-09 11:22:37

标签: spring spring-mvc encoding utf-8

在我们的网络应用中,我们遇到了一个糟糕的编码问题。为了重现此问题,用户在浏览器中选择非unicode编码(例如在chrome - > More tools-> encoding-> Koi8中)并尝试设置西里尔文本。 Chars在进入控制器时被破坏(只是在调试时检查),甚至它存储错误并且错误地呈现。
我们已遵循所有建议:http://balusc.blogspot.com/2009/05/unicode-how-to-get-characters-right.html,这似乎是提交application/x-www-form-urlencoded编码内容类型的问题。因为在这些表单提交期间不可能设置charset。
例如,如果使用json提交相同的数据并设置必需内容类型,则所有内容都将正确存储。 我们也试过这篇文章的例子: http://www.codejava.net/frameworks/spring/spring-mvc-form-handling-tutorial-and-example并使用以下方法添加了UTF8文件管理器:

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException,
        ServletException {

            request.setCharacterEncoding("UTF-8");
            response.setCharacterEncoding("UTF-8");
    chain.doFilter(request, response);
}

但同样的问题是可以重现的。 有人可以建议如何解决上述问题吗?
是否有可能正确处理Spring MVC中提到的用例,因为我们尝试了简单的示例,它似乎不起作用。这种用例改变浏览器编码是否有效?

3 个答案:

答案 0 :(得分:4)

尝试:在web.xml中



<filter>
     <filter-name>encoding-filter</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>

 <filter-mapping>
     <filter-name>encoding-filter</filter-name>
     <url-pattern>/*</url-pattern>
 </filter-mapping>
&#13;
&#13;
&#13;

参考:http://wiki.apache.org/tomcat/FAQ/CharacterEncoding

此外,如果您使用jstl,请尝试设置默认编码

答案 1 :(得分:0)

在您的请求管道中的某处,您将覆盖编码(即String.getBytes()new String(bytes),而不使用正确的编码。 有很多地方可能会发生这种情况,这也是Spring Boot和其他各种框架强制输入和输出UTF-8的原因之一,特别是因为UTF-8是推荐的编码。

您的用户不应更改编码。事实上,当页面加载servlet响应和HTML本身时,应该指定UTF-8,这是有充分理由的。服务器说&#34;我说UTF-8&#34;。如果你想要一个不同的编码,你必须在HTML(即jsp)和servlet请求/响应中指定不同的编码,以便浏览器自动选择编码。即使这样,你的里程也会因application/x-www-form-urlencoded而异,特别是如果你使用Javascript(可能是因为其他角色的编码规范有些含糊不清)。为了给你一些更多的例子,说明为什么HTML必须具有与你的发送完全相同的编码,因为名称值对将具有不同的编码。那就是你的表单有UTF-8请求参数名称(因为那是HTML中的内容)但是当你覆盖它时你为参数值提供了不同的编码(即?UTF-8Name=KoiValue&UTF-8Name=KoiValue)。希望你能看出为什么这很糟糕,我不确定chrome是否足够智能(或者甚至应该这样做)将请求参数名称更改回Koi8。

因此,如果您绝对必须支持其他字符编码,则可能应使用multipart/form(在表单元素的enctype属性中指定此项)并且不使用将UTF-8设置为的编码过滤器那些可能会导致腐败。

答案 2 :(得分:0)

可以通过在表单中​​使用accept-charset="UTF-8"属性来实现此行为。

可以在弹簧形式标签中添加。还有旧版struts中的错误(1.1受影响)

https://issues.apache.org/jira/browse/STR-1636

这使得无法将此属性直接添加到表单中。作为一种解决方法,可以使用jQuery

jQuery( document ).ready(function() {
   jQuery("#formSelector").attr("accept-charset", "UTF-8");
});

因此,简而言之,此属性将强制浏览器使用指定的编码从此表单发送数据。如果用户将一些控制字符设置到输入中,它们也将被发送到后端,因此需要验证以防止此类情况。还会处理浏览器编码和键盘语言不能很好地协同工作的情况(例如KOI8-U和中文键盘语言)。

accept-charset official documentation