我的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);
答案 0 :(得分:3)
从上面的示例中,我可以验证日语字符串是否正确保存到MySQL数据库,但是escaped Unicode。
我会按顺序检查这些项目:
CHARACTER SET utf8 COLLATE utf8_general_ci
request.setCharacterEncoding("UTF-8");
jdbc:mysql://localhost:3306/YOURDB?useUnicode=true&characterEncoding=UTF8
正如其他人所指出的,你不应该使用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字符串。