我的数据库编码为UTF-8,数据连接为
con = DriverManager
.getConnection("jdbc:mysql://localhost/utftest?user=root&password=password&useUnicode=true&characterEncoding=GBK");
请问我用rs.getString(1);得到字符编码是什么,是不是与characterEncoding的值有关,谢谢!
con = DriverManager
.getConnection("jdbc:mysql://localhost/utftest?user=root&password=password&useUnicode=true&characterEncoding=GBK");
请问我用rs.getString(1);得到字符编码是什么,是不是与characterEncoding的值有关,谢谢!
解决方案 »
- 找了个链接,没分,那位大侠帮忙下个SSH源码的书籍啊,散分。。
- java 基础问题 关于byte
- if条件问题
- jsp页面跳转啊啊啊
- 刚刚接触正则希望高手指点。没有分数了。不好意思了
- 修改了applet后,再次编译后,用浏览器打开html文件,为什么修改后的不显示呢?
- >>>>> 航母级Java建模软件--MagicDraw UML Enterprise 9.5 下载地址.要的进来看 <<<<<
- 大家看看这段代码是做什么的?老师着急要答案!
- 怎么归档自己的包!
- 紧急求救:光标放在浏览器里表格里,怎得到光标所在的td 是table 的第几行?第几列?
- 今天刚开始学java,请教个小问题!
- interface的疑惑!
如果数据库是UTF-8的,数据库连接是characterEncoding=GBK,为什么我用return new String(rs.getBytes(1), "ISO-8859-1");到客户端显示就是乱码,而数据库编码为GBK的话这样就没问题;同样,数据库是UTF-8,数据库连接是characterEncoding=UTF-8,return new String(rs.getBytes(1), "ISO-8859-1");得到仍是乱码,而把数据库编码改为GBK就又正常了,这不是与characterEncoding设置的值无关么。
当然我要是用return new String(rs.getString(1).getBytes("GBK"),"ISO-8859-1");在上述条件下都可以得到正确值,还望大家告知!
我在linux下试过,mysql存汉字的时候本身就会乱码,在读取的时候最好来一次转换
用byte解决
http://www.regexlab.com/zh/encoding.htm从数据库读取数据,到页面显示,中间的环节很多,问题不一定就出在搂主这里。因此,需要准确理解概念。
-8四种组合来希望得到其返回值到底是与数据库编码有关还是与characterEncoding设置有关, 请大家不必太关心操作细节和结果,这些操作都是正确的,谢谢!
res.setContentType("text/plain");
PrintWriter pw = res.getWriter();
pw.print(balance);
pw.close();
从数据库得到的结果操作为:
........
con = DriverManager
.getConnection("jdbc:mysql://localhost/utftest?user=root&password=password&useUnicode=true&characterEncoding=XXX");
........
return new String(rs.getBytes(1), "ISO-8859-1");
........
这里的数据库编码为GBK时,返回到客户端是正确的结果,而如果是UTF-8的话则是乱码,而不以XXX的值为变化,请问是为什么?
当然用return new String(rs.getString(1).getBytes("GBK"),"ISO-8859-1");的话就与数据库编码是什么无关了
该问题的前两个解释很好,已弄明白,但针对第三个解释,本身我都没有想到以此发问,既然提到了,发现存在出入,你提到"恐怕并不是“与数据库编码是什么无关了”,而是“characterEncoding=XXX 跟数据库编码匹配就可以了”",我之前做过测试,还是这句话:
con = DriverManager
.getConnection("jdbc:mysql://localhost/utftest?user=root&password=password&useUnicode=true&characterEncoding=XXX");
数据库的编码无论是GBK,UTF-8或是默认的Latin1,XXX的值为GBK或是UTF-8,用
return new String(rs.getString(1).getBytes("GBK"),"ISO-8859-1");
在客户端都能返回正确结果,并不似你说的那样,希望解惑!
【hehe,刚发完就发现有问题了,但 CSDN 最多只能连发三贴,所以等了半天】
3. 用return new String(rs.getString(1).getBytes("GBK"),"ISO-8859-1");的话就与数据库编码是什么无关了rs.getString(1) 总能得到一个“正确”的字符串,然后按照 GBK 拆解成字节数组,然后再按照 "ISO-8859-1" 拼装成一个“不知所云”的字符串……后面的事情跟前面 (2) 中所述一样。结论:既然 rs.getString() 总能得到“正确”的字符串,那么,根本就不需要转来转去的,直接 return rs.getString(1) 就好了。如果你用这个办法写到客户端后看到的是乱码,说明你的 PrintWriter 的 encoding 设得不对,想办法设成 GBK 就好了。
res.setContentType("text/plain; charset=GBK");
PrintWriter pw = res.getWriter();
pw.print(balance);
pw.close();
并且用rs.getString()作为返回值,
而第一个没有加charset=GBK的多次试验情况下发现很多令我出乎意料的结果,由于对这块了解不够,才引发诸多疑问,谢谢你详细的解答!
最后再问一句,rs.getString()总能得到“正确”的字符串,依据是什么
public class DBServlet extends HttpServlet { public int type; // 分别对应两种对中文数据的处理方式 private static final long serialVersionUID = 4208954264915608912L; /**
* @函数功能 使用Servlet容器的默认编码(ISO-8859-1),在需要时应对相关数据进行解码处理
*/
protected void doGet(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
String acct = new String(req.getParameter("account").getBytes(
"ISO-8859-1"), "GBK"); // 使用"ISO8859-1"字符集将接收的字符解码并存储到byte数组,再用GBK码将该数组构造为新的String
String pwd = req.getParameter("password");
String keyWord = req.getParameter("keyWord");
type = 0; String balance = accountLookup(acct, pwd, keyWord, type); if (balance == null) {
res.sendError(HttpServletResponse.SC_BAD_REQUEST,
"Unable to locate account.");
return;
} res.setContentType("text/plain");
PrintWriter pw = res.getWriter();
pw.print(balance); // 按照平台的默认字符编码(ISO-8859-1)将字符串的字符转换为字节(编码),并完全以write(int)方法的方式写入这些字节
pw.close();
} /**
* @函数功能 对输入请求和输出响应都预先加上字符编码,避免其中的字符编码转换
*/
protected void doPost(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
req.setCharacterEncoding("GBK"); // 设置输入编码格式,该方法需在读取数据前调用
String acct = req.getParameter("account");
String pwd = req.getParameter("password");
String keyWord = req.getParameter("keyWord");
type = 1; String balance = accountLookup(acct, pwd, keyWord, type); if (balance == null) {
res.sendError(HttpServletResponse.SC_BAD_REQUEST,
"Unable to locate account.");
return;
} res.setContentType("text/plain; charset=GBK"); // 设置输出编码格式,该方法需在使用PrintWriter流前调用
PrintWriter pw = res.getWriter();
pw.print(balance);
pw.close();
} /**
* @param acct
* 用户帐户
* @param pwd
* 用户密码
* @param keyWord
* 查询条件
* @param type
* 操作类型
* @return
* @函数功能 从数据库查询信息并返回结果
*/
private String accountLookup(String acct, String pwd, String keyWord,
int type) {
Connection con = null; try {
Class.forName("com.mysql.jdbc.Driver");
// 这里"characterEncoding=UTF-8"是指将数据从unicode编码转换为指定UTF-8编码进行传输,否则用默认的"ISO-8859-1"的编码进行传输,
// 之后在数据库操作中则是采用数据库指定的内部编码方式存储传来的数据
con = DriverManager
.getConnection("jdbc:mysql://localhost/utftest?user=root&password=password&useUnicode=true&characterEncoding=UTF-8");
Statement stmt = con.createStatement();
String sqlStr = "Select " + keyWord
+ " from userinfo where userName = '" + acct + "'"
+ " and userPwd = '" + pwd + "'";
ResultSet rs = stmt.executeQuery(sqlStr); if (rs.next()) {
if (type == 0) {
// 用rs.getString()得到“正确”的字符串,再按照GBK拆解成字节数组(编码),然后用"ISO-8859-1"解码字节数组并生成字符串(解码)
return new String(rs.getString(1).getBytes("GBK"),
"ISO-8859-1");
// rs.getBytes()得到的东西,只跟数据库的编码有关,得到的是把字符串按照数据库编码拆解出来的字节数组
// return new String(rs.getBytes(1), "ISO-8859-1");
} else {
return rs.getString(1);
}
} else {
return null;
}
} catch (Exception e) {
return e.toString();
}
}}