Javaweb中的中文编码问题
1. Java中需要编码的场景
1. I/O操作中存在编码
涉及编码的地方,一般都在从字符到字节、从字节到字符的转换上。
1) I/O中读操作,将字节转为字符
InputStream类是读字节的父类
InputStreamReader类是关联字节到字符的桥梁,负责I/O过程中处理字节到字符的转换
StreamDecoder类是字节到字符解码具体的实现类,被InputStreamReader委托类,转码过程中必须由用户指定编码格式。不指定则将使用本地环境的默认字符集。
2) I/O中写操作,将字符转为字节
StreamEncoder类负责将字符转换为字节。
2. 内存操作中存在编码
1) Java中用String表示字符串,String类中提供了转换为字节的方法。
**try** {
Strings = "我是中国人,what??";
**byte**[] b = s.getBytes("utf-8");
Stringres = **new** String(b,"utf-8");
System.**out**.println(res);
} **catch** (UnsupportedEncodingException e) {
e.printStackTrace();
}
2) Java中ByteBuffer类??????????????
提供一种char和byte之间的软转换,它们之间转换不需要编码和解码,只是把一个16bit的char拆分成为2个8bit的byte表示。。。。。
2. Java中如何进行编解码
1) ISO-8859-1编码
2) GB2312编码
3) GBK编码
4) UTF-16编码
5) UTF-8编码
6) 代码验证:
String name = "I am 君山";
**byte**[] iso8859 = name.getBytes("ISO-8859-1");
**byte**[] gb2312 = name.getBytes("GB2312");
**byte**[] gbk = name.getBytes("GBK");
**byte**[] utf16 = name.getBytes("UTF-16");
**byte**[] utf8 = name.getBytes("UTF-8");
**byte**[] b = {-27, -79, -79};
String sb = **new** String(b,"UTF-8");
System.**out**.println(sb);
[73,32, 97, 109, 32, 63, 63] iso
[73,32, 97, 109, 32, -66, -3, -55, -67] gb2312
[73,32, 97, 109, 32, -66, -3, -55, -67] gbk
[73,32, 97, 109, 32, -27, -112, -101, -27, -79, -79] utf8
[-2,-1, 0, 73, 0, 32, 0, 97, 0, 109, 0, 32, 84, 27, 92, 113] utf16
1.utf8表示用三个字节表示中文字符。如
byte[] b = {-27, -79, -79};
String sb = new String(b,”UTF-8”);
Sb**结果为*“*山*”***
2.gb2312额gbk编码结果一样,GBK编码是兼容GB2312的。
GBK包含的汉字字符更多。
只要经过GB2312编码的汉字都可以用GBK进行解码,反之不然。。
3. Javaweb中涉及的编解码
用户从浏览器端发起一个HTTP请求,需要存在编码的地方时URL、Cookie、Paramiter。
服务端接收到HTTP请求后要解析HTTP,其中URI、Cookie和POST表单参数需要解码。
服务端读取数据库中的数据–本地或网络中的文本文件,都存在编码问题。
1) URL的编解码
Ø 视图解析URL(和URI)
Ø 以Tomcat作为ServletEngine为例
① Port:对应Tomcat中的
2) HTTP Header的编解码
① Header中项默认使用ISO-8859-1进行解码,从byte至char
② 不能设置Header的其他解码格式,否则会乱码
③ 不要在Header中传递飞ASCII字符,如果一定要传递,先将这些字符用org.apache.catalina.util.URLEncoder编码,再添加至Header中
3) POST表单的编解码
① 当我们在页面点击提交按钮的时候,浏览器首先会根据ContentType的charset编码格式对表单中填入的参数进行编码,然后提交到服务端,在服务端同意也是用ContentType中的字符集进行解码。
② 注意:一定要在第一次调用request.getParameter方法之前就设置request.setCharacterEncoding(charset),否则POST表单提交过来的数据也有可能乱码。。。。
4) HTTP BODY的编解码
Response返回给客户端时:
① 编码字符集可以通过response.setCharacterEncoding来设置,
② 通过Header的Content-Type返回给客户端
③ 浏览器接收到返回的Socket流时,将通过Content-Type的charset来解码。
④ 如果返回的HTTP Header 中Content-Type没有设置charset,那么浏览器将根据HTML中的中的charset来解码
⑤ 如果还没有定义,浏览器将使用默认的编码来解码。
4. Js中的编码问题
1) 外部引入js文件
HTML页面 指定的编码格式必须与js文件编码格式一致,不会乱码。
2) Js的url编码
在js中处理URL编码有三个函数:
① escape()函数 已经在ECMAScript v3中删除了,使用后面两个函数替代
var s = "I am 君山";
console.log(escape(s)); //result:I%20am%20%u541B%u5C71
var res =unescape('I%20am%20%u541B%u5C71');
console.log(res); //result: I am 君山
② encodeURI()
将整个URL中的字符进行UTF-8编码
vard = 'http://localhost:8080/kwmp/servlets/servlet/你是?id=好';
varres = encodeURI(d); //编码
console.log(res);
//result:http://localhost:8080/kwmp/servlets/servlet/%E4%BD%A0%E6%98%AF?id=%E5%A5%BD
//解码
var a = decodeURI('http://localhost:8080/kwmp/servlets/servlet/%E4%BD%A0%E6%98%AF?id=%E5%A5%BD');
console.log(a);
//result: <http://localhost:8080/kwmp/servlets/servlet/你是?id=好>
③ encodeURIComponent()
比encodeURI()编码还要彻底。。。
整个函数通常用于将一个URL当做参数放在另一个URL中