提交表单后输入框中出现乱码字符的问题

9

我通常可以将捷克语字符串写入表单:

enter image description here

但是在验证后(以及当我将收集到的字符串发送到数据库时),该字符串使用了其他字符集:

enter image description here

h:outputTexts (名称,姓氏)仍然正常显示,而h:inputTexts则不是。

我应该在哪里寻找问题?

更新: HTTP响应头:

enter image description here

解决方案:

  • 创建带有request.setCharacterEncoding("UTF-8")的过滤器,在Filter#doFilter()中使用
  • 检查所有xml是否已配置为UTF-8
  • 在主xhtml中添加<f:view contentType="text/html" encoding="UTF-8"/>
  • 在hibernate.cfg.xml中添加以下行:

    <property name="hibernate.connection.characterEncoding">utf8</property>

    <property name="hibernate.connection.useUnicode">true</property>


那不是响应头,那是请求头 :) 你需要发布从服务器检索到的任何内容,而不是你发送到服务器的内容。但你使用Safari有些耳熟... - BalusC
啊哈,这对我来说很新鲜,我需要稍微探索一下 :) “Safari rings some bells”是什么意思? - gaffcz
只需检查Firebug的Net选项卡或Chrome工具的Network选项卡(按F12键)。至于Safari,我模糊地记得有一些相关问题,但我似乎找不到任何东西,也无法更详细地回忆起来。我至少会在不同的浏览器(IE、FF、GC等)中尝试,以排除Safari本身的嫌疑。 - BalusC
好的,content-type响应头看起来很好(这也通过适当的标签得到了确认)。这意味着问题在于解析请求参数。理论上,在Filter#doFilter()中使用request.setCharacterEncoding("UTF-8")应该可以解决问题,但对于Facelets上的JSF 2.0来说,这不是必需的。首先,您使用的JSF实现/版本是什么,您在web.xml中有哪些与JSF相关的上下文参数? - BalusC
Mojarra v2.1.3(javax.faces.jar)现在可用,之前是mojarra-2.1.2-FCS。JSF相关的XML部分将在我提问的一分钟内给出。 - gaffcz
显示剩余3条评论
3个回答

4
鉴于症状,使用ISO-8859-x编码重新显示UTF-8数据。在UTF-8中,č (LATIN SMALL LETTER C WITH CARON (U+010D)) 存在于字节 0xC40x8D 中。根据ISO-8859-1代码页布局,这些字节分别表示字符 Ä 和 [nothing],这正是您所看到的。

这个特定的问题可能有很多原因。由于Facelets本身已经默认使用UTF-8来处理HTTP POST请求参数并写入HTTP响应,因此在Java/JSF方面应该/可以没有什么需要修复/更改的地方。

但是,当您在JSF创建/恢复视图之前手动获取请求参数时(例如在自定义过滤器中),那么Facelets可能为设置正确的请求字符编码为时已晚。您需要在继续链或在引起问题的过滤器之前映射的新过滤器中添加以下行:

request.setCharacterEncoding("UTF-8");

此外,如果您已经显式/隐式地通过例如<?xml version="1.0" charset="ISO-8859-1"?><f:view encoding="ISO-8859-1">更改了Facelets的默认字符编码,则Facelets将使用ISO-8859-1。您需要将其替换为UTF-8或完全删除它们。
如果不是这个问题,那么只有数据库端是主要嫌疑人。在这方面,我可以看到两种可能的原因:
1. 数据库表未使用UTF-8。 2. JDBC驱动程序未使用UTF-8。
如何解决取决于所使用的DB服务器。通常,在创建DB表时需要指定字符集,但通常也可以使用ALTER进行更改。至于JDBC驱动程序,这通常可通过显式指定charset作为连接URL参数来解决。例如,在MySQL的情况下:
jdbc:mysql://localhost:3306/db_name?useUnicode=yes&characterEncoding=UTF-8

参见:


谢谢Balusc,<?xml>和<f:view>确实改变了字符集,但是当我将字符串写入inputTexts并进行表单验证后,它们各自不同。而且验证阶段在发送数据到数据库之前,所以这应该与数据库无关..或者不是吗? - gaffcz
“<?xml?>”已被删除,“<f:view encoding =” UTF-8 “>”仅在主页面中存在,且仍然相同 :) 有趣的是,在我基于相同基础构建的其他应用程序中,一切正常,我无法找到任何原则性的区别... - gaffcz
回答什么?哪个答案?你只有一个问题。 - BalusC
Balusc,request.setCharacterEncoding("UTF-8")Filter#doFilter() 中解决了验证表单问题!最终你是对的,即使在 MySql 字符编码 (ěščřžýáíé ?š??žýáíé) 的情况下也是如此。我通过将 hibernate.connection.useUnicodecharacterEncoding 属性添加到我的 hibernate xml 文件中来解决它。请更新您的答案,我会接受它 :) - gaffcz
我已经这样做了,但我仍然想知道为什么request.setCharacterEncoding("UTF-8")是必须的。我有一种感觉这是一个解决方法。你也说过,在你的另一个类似构建的应用程序中,一切都正常工作。我仍然很好奇问题的真正原因。 - BalusC
显示剩余2条评论

3
尝试使用这个解决方案:http://ibnaziz.wordpress.com/2008/06/10/spring-utf-8-conversion-using-characterencodingfilter/。在我的情况下,它有助于(对于俄语)。
在web.xml中添加Spring的字符编码过滤器:
<filter>
    <filter-name>encodingFilter</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>encodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
 </filter-mapping>

1
谢谢Sergey,但是它没有帮助 :) - gaffcz
3
需要在类路径中放置整个Spring库,这相当笨拙。该过滤器的基本功能只是调用 request.setCharacterEncoding("UTF-8")。为此,您也可以创建自定义过滤器。 - BalusC

0

我在验证表单时遇到了完全相同的问题,而我通过Sergey的答案解决了它。

但是你的过滤器需要在web.xml文件中处于第一位置。将我的过滤器从第三个位置移动到第一个位置解决了我的问题。

希望能帮助到你。

(Primefaces 3.2, JSF 2.1.2 with Jboss 7.1)


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