Spring MVC + Hibernate 编码问题

3

我正在开发一个基于Spring MVC + Hibernate的应用程序,使用带有InnoDB引擎的MySQL(版本为5.0.51a)。

问题出现在当我提交一个包含西里尔文字符的表单时。结果是,数据库中包含了无法识别编码的无意义字符。

所有的JSP页面、数据库(包括表和字段)都使用UTF-8创建。 Hibernate的配置也包含将编码设置为UTF-8的属性。

我通过创建过滤器对请求内容进行UTF-8编码来解决了这个问题。 示例代码:

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

但这明显会拖慢应用程序。

有趣的是,直接从应用程序执行插入查询(即从Eclipse作为Java应用程序运行)效果完美。

更新。

据我所知,在我的情况下使用过滤器是唯一可行的解决方案。

我不知道有关标准CharacterEncodingFilter的信息。现在使用它,效果非常好!

<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>

<filter-mapping>
    <filter-name>CharacterEncodingFilter</filter-name>
    <url-pattern>*</url-pattern>
</filter-mapping>

在请求对象中更改字符编码不应该对应用程序的速度产生可见影响。一定是其他问题导致的。 - matt b
你是否有将 doFilter() 方法声明为 synchronized - Bozho
2个回答

3

您的JSP文件必须以两种方式为UTF-8:

  • 标题处使用<%@page pageEncoding="UTF-8" %>
  • 在Eclipse中通过右键单击 > 属性,将它们的编码设置为UTF-8(可能会拒绝转换,因此请先剪切当前内容,然后更改编码,再将其粘贴回去)

然后对于这种情况,Spring有一个CharacterEncodingFilter,这不应该会有任何显著的性能影响:

<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>

实际上,除非doFilter()方法声明为synchronized,否则没有任何过滤器应该有显著的性能损失。


@Bozko。我的标题和页面都使用了UTF-8编码。doFilter()方法中没有包含关键字“synchronized”。看起来减速只是我的主观感受。CharacterEncodingFilter运行良好!谢谢。 - MiKo
如果这不起作用,请返回-1。如果您的页面不是ISO-8859-1(在浏览器端),您必须使用CharacterEncodingFilter来正确处理非美国ASCII输入(除非您的servlet容器在此处违反了servlet规范,例如Jetty)。 - axtavt
@axtavt,我修复了那个微小的细节。 - Bozho
所以,该过滤器将转换已发布的表单值或者? - Blankman

2
这是正确编码转换的代价:UTF-8(请求)-> UTF-16(Java)-> UTF-8(数据库)。但我认为如果这种转换占总请求时间的百分比超过了几个点,那么就有些不对劲了。
所有JSP页面都使用UTF-8创建。你的容器是否将UTF-8设置为页面编码?(请参阅生成的页面属性)。如果是,则无需设置过滤器,浏览器会以UTF-8格式提交表单。

浏览器通常在提交表单时不会发送编码信息,而Servlet容器默认假设是ISO-8859-1编码。因此,在这种情况下,过滤器是唯一正确的解决方案。 - axtavt
生成的页面包含以下行:<meta http-equiv="Content-Type" content="text/html;charset=utf-8">但是,正如我所提到的,没有过滤器就没有成功。如果您认为转换过程有点繁琐,在这种情况下有更好的解决方案吗? - MiKo
浏览器确实会发送编码——与页面的原始编码相同,或者是UTF-8。否则我们这些非Latin1人士怎么能提交我们可怜的多字节表单呢?:D - Vladimir Dyuzhev
@Bar,跟踪HTTP请求(例如使用Firefox的FireBug或TamperData),查看来自服务器和发送到服务器的内容。检查Content-Transfer-Encoding标头。 - Vladimir Dyuzhev

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接