Java POST数据到mySQL UTF-8编码问题

时间:2011-12-13 15:43:37

标签: java mysql post encoding utf-8

我的POST数据包含日语字符串AKB48 ネ申テレビ シーズン3,在jQuery中定义为data

$("#some_div").load("someurl", { data : "AKB48 ネ申テレビ シーズン3"}) 

将后期数据发送到Java Servlet:

String data = new String(this.request.getParameter("data").getBytes("ISO-8859-1"), "UTF-8");

我的程序将其保存到MySQL,但在将数据保存到数据库后,它变为:

  

AKB48 u30CDu7533u30C6u30ECu30D3 u30B7u30FCu30BAu30F33

如果我想将其保存为UTF-8,我该怎么办?我的所有文件都是UTF-8。

MySQL编码是utf8,这是代码

String sql = "INSERT INTO Inventory (uid, item_id, item_data, ctime) VALUES ("
                + inventory.getUid() + ",'"
                + inventory.getItemId() + "','"
                + StringEscapeUtils.escapeJava(inventory.getItemData()) + "',CURRENT_TIMESTAMP)";
    Statement stmt = con.createStatement();
    int cnt = stmt.executeUpdate(sql);

4 个答案:

答案 0 :(得分:3)

从上面的示例中,我可以验证日语字符串是否正确保存到MySQL数据库,但是escaped Unicode

我会按顺序检查这些项目:

  1. 您的表和列是否都设置为utf8的字符集和排序规则?即, CHARACTER SET utf8 COLLATE utf8_general_ci
  2. 是否在POST之前明确设置字符集编码? request.setCharacterEncoding("UTF-8");
  3. 您是否为数据库连接设置了字符编码?即,jdbc:mysql://localhost:3306/YOURDB?useUnicode=true&characterEncoding=UTF8
  4. 正如其他人所指出的,你不应该使用getBytes技巧。它肯定会弄乱POSTed值。

    修改

    不要使用StringEscapeUtils.escapeJava,因为这会将您的字符串转换为转义的Unicode。这就是将AKB48 ネ申テレビ シーズン3转换为AKB48 u30CDu7533u30C6u30ECu30D3 u30B7u30FCu30BAu30F33的原因。

答案 1 :(得分:0)

为什么不提取像this.request.getParameter("data")这样的参数值?

使用URL编码正确发送您的数据,其中每个unicode字符都被其代码替换。然后你必须得到参数的值。当您使用ISO-8859-1请求字节时,实际上是在破坏数据,因为如果代码是文本形式,则字符串表示为序列。

答案 2 :(得分:0)

该行的重点是什么

String data = new String(this.request.getParameter("data").getBytes("ISO-8859-1"), "UTF-8");

您正在使用ISO-8859-1编码将中文(或至少非西方)字符转换为字节。当然这不起作用,因为ISO-8859-1编码不支持中文字符。然后,您将使用UTF-8编码从字节构造一个新的String,该字符串应该代表ISO-8859-1编码的字符。再一次,这没有任何意义。 UTF-8和ISO-8859-1不是一回事,只有一小部分字符在两种格式中具有相同的编码。

只需使用

String data = this.request.getParameter("data");

并且一切都应该没问题,前提是MySQL表中的列使用支持这些字符的编码。

编辑:

既然你已经向我们展示了用于在数据库中插入数据的代码,我知道所有这些来自哪里(前面的点仍然有效)。你在做什么

StringEscapeUtils.escapeJava(inventory.getItemData())

重点是什么? escapeJava用于获取String并转义特殊字符,以使其成为有效的Java String字符。它与SQL无关。使用准备好的声明:

String sql = "INSERT INTO Inventory (uid, item_id, item_data, ctime) VALUES (?, ?, ?, CURRENT_TIMESTAMP);
PreparedStatement stmt = con.prepareStatement();
stmt.setInteger(1, inventory.getUid()); // or setLong, depending on the type
stmt.setString(2, inventory.getItemId());
stmt.setString(inventory.getItemData());
int cnt = stmt.executeUpdate();

PreparedStatement将正确处理特殊SQL字符。它们是SQL注入攻击的最佳工具,并且在查询具有参数时应始终使用,特别是如果参数来自最终用户。请参阅http://docs.oracle.com/javase/tutorial/jdbc/basics/prepared.html

答案 3 :(得分:0)

Java字符串以UTF-16存储。所以,这段代码:

String data = new String(this.request.getParameter("data").getBytes("ISO-8859-1"), "UTF-8");

使用ISO-8859-1字符集将UTF-16字符串(已在HTTP协议中从UTF-8重新编码)解码为二进制数组,并使用UTF-8重新编码二进制数组字符集。这几乎肯定不是你想要的。

使用它时会发生什么?

String data = this.request.getParameter("data");
System.out.println(data);

如果第二行生成错误数据,那么您的问题可能出在jQuery中。确定您确实在jQuery请求中获得了unicode:

System.out.println(this.request.getHeader("Content-Encoding"));

如果它不会生成错误数据,但数据无法在mySQL中正确存储,则问题出在数据库级别。确保您的列类型支持unicode字符串。