0

我正在帮助我的一位朋友。他正在使用 JSF 2.0 和 mysql 创建 Web 应用程序。

在创建数据库时,他使用了以下查询。

CREATE DATABASE dbName DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_general_ci;

到目前为止,网站运行良好。今天客户尝试输入阿拉伯语文本,他们说输出很奇怪。我的朋友所做的是将数据输入数据库后,他还在另一页上打印相同的数据说Congratulations, XYZ ABC is added successfully。但是他认为输出为Congratulations, Ù?ظاÙ? تÙ?Ù?Ù?Ø© Ù?تÙ?Ù?Ù? صدÙ?Ù? Ù?Ù?بÙ?ئة is added successfully. 我不明白为什么当数据库字符设置正确时他会这样。

web.xml内容如下。

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
    <context-param>
        <param-name>javax.faces.PROJECT_STAGE</param-name>
        <param-value>Development</param-value>
    </context-param>
    <servlet>
        <servlet-name>Faces Servlet</servlet-name>
        <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>Faces Servlet</servlet-name>
        <url-pattern>/faces/*</url-pattern>
    </servlet-mapping>
    <session-config>
        <session-timeout>
            600
        </session-timeout>
    </session-config>
    <welcome-file-list>
        <welcome-file>faces/index.xhtml</welcome-file>
    </welcome-file-list>
    <filter>
        <filter-name>restrict</filter-name>
        <filter-class>com.sac.filter.MyFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>restrict</filter-name>
        <url-pattern>*.xhtml</url-pattern>
    </filter-mapping>
    <filter>
        <filter-name>MyFacesExtensionsFilter</filter-name>
        <filter-class>org.apache.myfaces.webapp.filter.ExtensionsFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>MyFacesExtensionsFilter</filter-name>
        <servlet-name>Faces Servlet</servlet-name>
    </filter-mapping>

    <servlet>
        <servlet-name>DisplayImage</servlet-name>
        <servlet-class>com.sac.databean.DisplayImage</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>DisplayImage</servlet-name>
        <url-pattern>/DisplayImage</url-pattern>
    </servlet-mapping>
    <servlet>
        <servlet-name>SaveMyImage</servlet-name>
        <servlet-class>com.sac.databean.SaveMyImage</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>SaveMyImage</servlet-name>
        <url-pattern>/SaveMyImage</url-pattern>
    </servlet-mapping>

<!-- for not using css and js of default richfaces   -->
    <context-param>
        <param-name>org.richfaces.SKIN</param-name>
        <param-value>plain</param-value>
    </context-param>
    <context-param>
        <param-name>org.richfaces.LoadStyleStrategy</param-name>
        <param-value>None</param-value>
    </context-param>
    <context-param>
        <param-name>org.richfaces.enableControlSkinning</param-name>
        <param-value>false</param-value>
    </context-param>
<!-- for not using css and js of default richfaces   -->    

</web-app>

在每个.xhtml页面上,他都有<?xml version='1.0' encoding='UTF-8' ?>

如果您需要其他任何东西,请告诉我。


编辑 1

在我的 JSF 过滤器中,我还添加req.setCharacterEncoding("UTF-8");doFilter(). 我还在数据库中看到???????????


编辑 2

在 JSF 页面中,当我将Java bean 中<h:inputText value="#{PersonalInformationDataBean.fullName}">的值打印为m 时,我得到的输出为.fullNameSystem.out.println("my name while entering is " + fullName);my name while entering is ???????????? ????

这意味着输入数据时出现问题

有人可以帮助发生什么奇怪的事情吗?

4

1 回答 1

3

然而,他将输出视为祝贺,Ù?ظاÙ?تÙ?Ù?Ù?Ø© Ù?تÙ?Ù?Ù? صدÙ?Ù? Ù?Ù?بÙ?ئة添加成功。我不明白为什么当数据库字符设置正确时他会这样。

这被称为Mojibake。这不是 DB 编码问题,而是 HTTP 编码问题。像您一样设置 POST 请求字符编码确实是正确的解决方案。


编辑 1:在我的 JSF 过滤器中,我还添加req.setCharacterEncoding("UTF-8");doFilter(). 还在数据库中我看到?????????????

当连接的双方知道自己的编码时,就会出现问号。一侧编码未涵盖的发送/检索字符将替换为问号。阿拉伯字符不会出现在 ISO-8859-1 中,因此它们被问号取代。这就是 Mojibake 的不同之处,即发送字符而不检查对方使用的编码是否真的支持该字符。您最终会得到错误编码的字符,这些字符将自身呈现为难以理解的字符序列。

在这种特殊情况下,JDBC 驱动程序本身知道它默认使用 ISO-8859-1 将字符传输到 DB,而检索到的字符是 UTF-8(MySQL JDBC 驱动程序不查看 DB表编码,即使在您的情况下它已正确设置为 UTF-8)。在将数据传输到 DB 之前,您需要明确告诉 JDBC 驱动程序使用 UTF-8 解码字符。这将作为 JDBC 连接属性来完成,这些属性在 JDBC URL 中定义为查询字符串参数,如下所示:

jdbc:mysql://localhost:3306/db_name?useUnicode=yes&characterEncoding=UTF-8

如果您使用的是容器管理的数据源,则只需分别指定这些属性,就像您为用户名和密码所做的那样

useUnicode=yes
characterEncoding=UTF-8

也可以看看:

于 2012-11-19T11:14:32.633 回答