先看一个字符串
String str = "Hello 简体 繁體 한국어 ";
字符串本无编码,就是一个字符串,但是计算机不能保存字符串,只能以二进制的形式保存,所以就会有字符串到二进制的转换动作,这个转换的规则叫编码规则,不同的规则就是不同的编码,比如gbk,gb2312,utf-8
下面看一个例子
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
public class CharSetTest {
/**
* @param args
* @throws UnsupportedEncodingException
*/
public static void main(String[] args) throws UnsupportedEncodingException {
String str = "Hello 简体 繁體 한국어 ";
toByte(str, Charset.defaultCharset().displayName());
toByte(str, "utf-8");
toByte(str, "utf-16");
toByte(str, "utf-32");
toByte(str, "gbk");
toByte(str, "GB2312");
toByte(str, "iso-8859-1");
}
public static void toByte(String str, String charSet) throws UnsupportedEncodingException {
System.out.println(str + " " + charSet + ":");
for (byte b : str.getBytes(charSet)) {
System.out.print(b + " ");
}
System.out.println();
System.out.println(new String(str.getBytes(charSet),charSet));
System.out.println();
}
}
结果输出
Hello 简体 繁體 한국어 UTF-8:
72 101 108 108 111 32 -25 -82 -128 -28 -67 -109 32 32 -25 -71 -127 -23 -85 -108 32 32 32 -19 -107 -100 -22 -75 -83 -20 -106 -76 32
Hello 简体 繁體 한국어
Hello 简体 繁體 한국어 utf-8:
72 101 108 108 111 32 -25 -82 -128 -28 -67 -109 32 32 -25 -71 -127 -23 -85 -108 32 32 32 -19 -107 -100 -22 -75 -83 -20 -106 -76 32
Hello 简体 繁體 한국어
Hello 简体 繁體 한국어 utf-16:
-2 -1 0 72 0 101 0 108 0 108 0 111 0 32 123 -128 79 83 0 32 0 32 126 65 -102 -44 0 32 0 32 0 32 -43 92 -83 109 -59 -76 0 32
Hello 简体 繁體 한국어
Hello 简体 繁體 한국어 utf-32:
0 0 0 72 0 0 0 101 0 0 0 108 0 0 0 108 0 0 0 111 0 0 0 32 0 0 123 -128 0 0 79 83 0 0 0 32 0 0 0 32 0 0 126 65 0 0 -102 -44 0 0 0 32 0 0 0 32 0 0 0 32 0 0 -43 92 0 0 -83 109 0 0 -59 -76 0 0 0 32
Hello 简体 繁體 한국어
Hello 简体 繁體 한국어 gbk:
72 101 108 108 111 32 -68 -14 -52 -27 32 32 -73 -79 -13 119 32 32 32 63 63 63 32
Hello 简体 繁體 ???
Hello 简体 繁體 한국어 GB2312:
72 101 108 108 111 32 -68 -14 -52 -27 32 32 -73 -79 63 32 32 32 63 63 63 32
Hello 简体 繁? ???
Hello 简体 繁體 한국어 iso-8859-1:
72 101 108 108 111 32 63 63 32 32 63 63 32 32 32 63 63 63 32
Hello ?? ?? ???
从例子看到,每种编码产生的字符大部分不一样,而且gbk和gb2312对韩文是不支持的,iso-8859-1只是assic的简单扩展,不支持中文。gb2312不支持繁体,gbk支持繁体
具体每种编码的编码范围可以查阅文档,我们常用的大概就utf-8,gbk,gb2312,assic,iso-8859-1
关于乱码:
为什么会出现乱码呢?
比如“中文”的utf-8编码为:-28 -72 -83 -26 -106 -121 32 gb2312编码为0 0 78 45 0 0 101 -121 0 0 0 32 ,可以看出两种编码是不一致的,假如以utf-8编码后,以gb2312来解码,那就出现了乱码,所以要防止乱码,必须知道文字以什么格式保存,然后以什么格式取出;
当然也有例外那就是编码之间有包含关系,比如utf-8,gbk,gb2312都支持assic码,对英文生成的编码格式也是一致,在这种情况下互转是没有问题的。
关于tomcat与iso8859-1
jsp和servlet有几种设置编码的方法:
在jsp中contentType="text/html; charset=gbk" 这个代表页面以gbk编码显示内容
pageEncoding="gbk" 代笔jsp以gbk编码编译成class
request.setCharacterEncoding("UTF-8");
如同new String(request.getParameter("name").getBytes("iso8859-1"),"utf-8");
response.setCharacterEncoding("utf-8"); 设置页面显示格式
tomcat默认把所有文字都进行ios8859编码,
比如页面编码的格式为utf-8,字符中文编码为-28 -72 -83 -26 -106 -121 32,那么tomcat在传送的过程中如同
new String("中文".getBytes("utf-8"),"iso8859-1"); 在页面中你不可以使用 request.getParameter("name");因为这样jvm默认使用了当前环境的编码比如utf-8或gbk等,正确的方式是
new String(request.getParameter("name").getBytes("iso8859-1"),"页面编码");