JDBC Resource Pool with Tomcat6 on Centos5.5 和 utf8 问题

Posted

技术标签:

【中文标题】JDBC Resource Pool with Tomcat6 on Centos5.5 和 utf8 问题【英文标题】:JDBC Resource Pool with Tomcat6 on Centos5.5 and utf8 problems 【发布时间】:2011-01-29 13:34:13 【问题描述】:

首先:请原谅我的英语。 然后……

我在 Centos5.5 上有一个 Tomcat6 服务器,配置了 JDBC 资源池。

<Resource name="jdbc/BD"
            auth="Container"
            type="javax.sql.DataSource"
            username="user"
            password="pass"
            driverClassName="com.mysql.jdbc.Driver"
            url="jdbc:mysql://127.0.0.1:3306/BD?autoReconnect=true&amp;useEncoding=true&amp;characterEncoding=UTF-8"
            maxActive="30"
            maxIdle="50"
            maxWait="-1"
            testWhileIdle="true"
            timeBetweenEvictionRunsMillis="300000"
/>

我编写了一个类来建立与该数据源的连接(名为 DAO);

        Context initCtx = new InitialContext();
        Context envCtx = (Context) initCtx.lookup("java:comp/env");
        DataSource ds = (DataSource) envCtx.lookup("jdbc/BD");
        connexio = ds.getConnection();
        sentencia = connexio.createStatement();

这里有我用来抛出查询的代码:

            DAO conn = new DAO();
            ResultSet SQLresults = conn.executeSQL(SQLQuery);

            while (SQLresults.next()) 
                String string1 = SQLresults.getString(2);
                String string2 = SQLresults.getString(3);
                String string2 = SQLresults.getString(4).replaceAll("[\n\r]", " ");
                String string3 = SQLresults.getString(5).replaceAll("[\n\r]", " ");
                String string4 = SQLresults.getString(6).replaceAll("[\n\r]", " ");
            

我的 DDBB (MySQL) 默认使用 UTF8,我使用“default charset=utf8”创建了所有表以确保这一点。

还有……

我几乎可以使用格式正确的 UTF8 字符编码,但有时我会遇到一些字符错误。我确定问题出在 mysql 和 tomcat 之间(所以在我的 servlet 或 JDBC 连接中),因为在 servlet 写入它们之后我看到一些格式错误的字符,但它们在 MySQL UTF8 提示符下格式正确我的终端。

例如,在 MySQL UTF8 终端(Putty、iMac 终端、Ubuntu 和 Debian 终端)中,我看到:

德国亚马逊售价 499 欧元的 LG Optimus 2X 和 Optimus Black 尚未开售

但我的 servlet 写道:

德国亚马逊标价 499 欧元的 LG Optimus 2X 和 Optimus Black,尚未开售

当我解码时,“â?¬”应该是一个“€”......但它不是。格式不好。

其他示例字符,在我的 UTF8 终端中:

David Trueba:“Leer novelas me llevó al guión”:推文 RUBÉN DARÍO ÁLVARE...

小服务程序:

David Trueba: â??Leer novelas me llevó al guiónâ?: Tweet RUBÃ?N DARÃO ÃLVARE...

但是“â??”、“â?”、“Ã?”应该是“”É(解码后),但它们是损坏的 UTF8 字符,我不知道为什么,因为 85% 的 UTF8 字符被完美解码。您可以通过以下方式看到这一点:ó Í Á 因为它们的格式完全正确。

你怎么看?如果有帮助,我会将该 UTF8 文本发送到 android 设备,当有格式错误的 UTF8 字符时,我会看到 .

顺便说一句,我使用此页面来确定良好的 UTF8 文本:

http://www.cafewebmaster.com/online_tools/utf_decode

而且....它确认了格式正确和格式错误的字符。

啊!,servlet 在浏览器中写入文本(没有 html 语句,只有文本),但我一直在做一些测试,如果我将其转换为 html 页面并将格式错误的数据放在正文中并强制它们为 utf8:

<meta http-equiv="Content-Type" content="text/html;charset=utf-8" >

结果是一样的。

非常感谢!

【问题讨论】:

【参考方案1】:

我发现至少有两个(潜在的)问题。首先,在您的 JDBC URL 中,您使用了 useEncoding 参数,而 MySQL JDBC 驱动程序并未正式识别该参数。它应该被称为useUnicode

然后是servlet响应部分。它默认使用平台默认字符编码,它本身不是 UTF-8。您还需要将 servlet 响应的字符编码显式设置为 UTF-8,向其写入任何字符之前。由于您没有使用 JSP,因此您还需要手动设置内容类型。

resposne.setContentType("text/plain; charset=UTF-8");
resposne.setCharacterEncoding("UTF-8");

在第一次调用getWriter()getOutputStream() 之前执行此操作。

另见:

Unicode - How to get the characters right?

请注意,当通过 HTTP 传输内容时,您的问题中给出的元标记会被忽略。相反,HTTP 响应 Content-Type 标头将用于确定内容类型和字符编码。您可以在 Net 面板中使用例如 Firebug 来确定 HTTP 标头。

【讨论】:

我刚才试过了,还是不行。现在它打印: David Trueba: “Leer novelas me llevó al guiónâ€Â: Tweet RUBÉN DARÃÂO ÃÂLVARE... ALL 是格式错误的 UTF8 字符 :S. 那么数据根本没有以 UTF-8 传输。我再次检查了您的 JDBC URL,发现您使用了useEncoding(根本不存在)而不是useUnicode。修复它并重试。 我的 JDBC URL 现在就像你说的那样,但什么也没有. 都做了吗?两者都需要完成。好吧,这仅意味着数据库本身的数据实际上已损坏。你是怎么插入数据的?无论如何,我建议自己阅读链接的文章,看看数据库表是否确实正确创建。 关于 DB 表....我所有的终端都是 UTF8 模式(只有 utf8),并且没有任何格式错误的字符。

以上是关于JDBC Resource Pool with Tomcat6 on Centos5.5 和 utf8 问题的主要内容,如果未能解决你的问题,请参考以下文章

关于c3p0 ResourcePoolException: Attempted to use a closed or broken resource pool

java.lang.ClassNotFoundException: org.apache.tomcat.jdbc.pool DataSourceFactory

Try-with-resource'必须是变量声明'[重复]

Error creating bean with name ‘redisConnectionFactory‘ defined in class path resource...

Error creating bean with name ‘redisConnectionFactory‘ defined in class path resource...

Java Connection Pool 和 try-with 语句:连接实际上是关闭还是返回到池中?