文章目录
- java编码
- ACSII编码对应表
- 常用编码
- 1、ISO-8859-1
- 2、GB2312/GBK
- 3、Unicode
- 4、UTF-8
- 几种编码关系
- java字符串处理
- getBytes(charset) 将字符串所表示的字符按照设置charset编码以字节形式表示
- new String(byte[],charset) 将字节数组按照设置charset编码识别,最后转换为Unicode存储
- GBK、UTF-8、ISO-8859-1转换
- 字符串内存Unicode16进制值
- web乱码问题
- get乱码
- post乱码
- 其他相关
java编码
java内部使用Unicode编码处理;iso-8859-1是JAVA网络传输使用的标准字符集
ACSII编码对应表
常用编码
1、ISO-8859-1
属于单字节编码,最多能表示的字符范围0-255;应用于英文系列;无法标识中文
2、GB2312/GBK
汉字的国际码,专门用来表示汉字,是双字节编码;英文字母和ISO-8859-1一致(兼容ISO-8859-1编码);GBK是不定长编码
GBK能同同时表示繁体字和简体字
GB2312只能表示简体字;GBK兼容GB2312编码
3、Unicode
最统一编码,可以表示所有语言的字符;是定长双字节编码(定长编码便于计算机处理);不兼容任何编码;对应英文是在ISO-8859-1之前加一个0字节
4、UTF-8
由于Unicode不兼容ISO-8859-1,而且容易占用更多空间,不便于传输和存储,因此产生了UTF-8编码;UTF-8兼容ISO-8859-1同时可以表示所有语言字符;英文1个字节表示,汉字3个字节表示;UTF-8是不定长编码
注意:UTF-8节省空间是相对Unicode来说的;如果已知是汉字,使用GBK是最节省
几种编码关系
如:a中
Unicode:61 4e2d
GBK:61 d6d0
UTF-8:61 e4b8ad
汉字没有ISO-8859-1编码,可以用iso8859-1编码来表示
java字符串处理
getBytes(charset) 将字符串所表示的字符按照设置charset编码以字节形式表示
private static void codeArray(String str) throws Exception{
System.out.println("IDE设置默认编码:"+Arrays.toString(str.getBytes()));
System.out.println("ISO-8859-1:"+Arrays.toString(str.getBytes("ISO-8859-1")));
System.out.println("GBK:"+Arrays.toString(str.getBytes("GBK")));
System.out.println("GB2312:"+Arrays.toString(str.getBytes("GB2312")));
System.out.println("UTF-8:"+Arrays.toString(str.getBytes("UTF-8")));
}
new String(byte[],charset) 将字节数组按照设置charset编码识别,最后转换为Unicode存储
private static void codeConvert(String str) throws Exception{
System.out.println("IDE默认编码:"+System.getProperties().getProperty("file.encoding"));
System.out.println("Unicode与IDE默认编码转换:"+new String(str.getBytes()));
System.out.println("Unicode与GBK转换:"+new String(str.getBytes("GBK"),"GBK"));
System.out.println("Unicode与GB2312转换:"+new String(str.getBytes("GB2312"),"GB2312"));
System.out.println("Unicode与UTF-8转换:"+new String(str.getBytes("UTF-8"),"UTF-8"));
System.out.println("Unicode与ISO-8859-1转换:"+new String(str.getBytes("ISO-8859-1"),"ISO-8859-1"));
}
GBK、UTF-8、ISO-8859-1转换
private static void codeIsoConvert(String str) throws Exception{
String gbk2iso = new String(str.getBytes("GBK"),"ISO-8859-1");
System.out.println("GBK编码ISO-8859-1解码,再反过来操作:"+new String(gbk2iso.getBytes("ISO-8859-1"),"GBK"));
String utf2iso = new String(str.getBytes("UTF-8"),"ISO-8859-1");
System.out.println("UTF-8编码ISO-8859-1解码,再反过来操作:"+new String(utf2iso.getBytes("ISO-8859-1"),"UTF-8"));
}
private static void codeUtf2GbkConvert(String str) throws Exception{
String utf2gbk = new String(str.getBytes("UTF-8"),"GBK");
System.out.println("UTF-8编码GBK解码,再反过来操作:"+new String(utf2gbk.getBytes("GBK"),"UTF-8"));
}
private static void codeGbk2UtfConvert(String str) throws Exception{
String gbk2utf = new String(str.getBytes("GBK"),"UTF-8");
System.out.println("GBK编码UTF-8解码,再反过来操作:"+new String(gbk2utf.getBytes("UTF-8"),"GBK"));
}
结论:
* utf-8、gbk编码可以用iso8859-1解码后编回去
* gbk与utf-8不可以
字符串内存Unicode16进制值
private static void codeHexValue(String str) throws Exception{
for(int i=0;i<str.length();i++){
System.out.println("字符串:"+str+" 第"+i+"个字符,Unicode值:"+Integer.toHexString(str.charAt(i)));
}
byte[] gbkArray = str.getBytes("GBK");
for(int i=0;i<gbkArray.length;i++){
System.out.println("字符串:"+str+" 转换GBK编码字节数组,第"+i+"个字节,GBK值:"+Integer.toHexString(gbkArray[i]));
}
byte[] utf8Array = str.getBytes("UTF-8");
for(int i=0;i<utf8Array.length;i++){
System.out.println("字符串:"+str+" 转换UTF-8编码字节数组,第"+i+"个字节,UTF-8值:"+Integer.toHexString(utf8Array[i]));
}
byte[] isoArray = str.getBytes("ISO-8859-1");
for(int i=0;i<isoArray.length;i++){
System.out.println("字符串:"+str+" 转换ISO-8859-1编码字节数组,第"+i+"个字节,ISO-8859-1值:"+Integer.toHexString(isoArray[i]));
}
}
web乱码问题
浏览器发送文字编码是和页面编码一直的(一般默认为UTF-8)
tomcat接收请求没有设置的情况下,默认使用ISO-8859-1
get乱码
- 手动转换编码:String key = new String(request.getParameter(“key”).getBytes(“ISO-8859-1”), “UTF-8”);
- 设置tomcat编码server.xml:
- 前端对中文参数encode处理,服务端decode处理;如下
前端:encodeURI(encodeURI(“中文”));
后端:URLDecoder.decode(request.getParameter(“key”), “UTF-8”)
注意:前端需要两次encode;容器会默认解码一次,容器解码采用的是容器默认编码,可能是UTF-8,GBK等,若与应用使用编码不一致直接获取会存在乱码,所以使用两次encode
post乱码
设置setCharacterEncoding() 需要在第一个getParameter之前设置,因为在执行第一个getParameter会按照设置编码分析内容,后续不在分析
其他相关
指定jsp文件存储编码<%@ page contentType="text/html; charset=UTF-8" %>