Java 字符编码相关
Java String类型在内存中以unicode编码形式存储,unicode属于定长编码,便于管理,所以java采用了unicode。
getByte(String charset) 将unicode编码转换编译成指定编码
内部实现调用了encode方法
static byte[] encode(char[] ca, int off, int len) {
String csn = Charset.defaultCharset().name(); //获取系统默认编码
try {
return encode(csn, ca, off, len); //安装指定编码方式对字符进行编码,如果是中文采用ISO8859-1,则无法编码,最后返回 "3f 3f"(两个问号)。
} catch (UnsupportedEncodingException x) {
warnUnsupportedCharset(csn);
}
//如果系统不支持系统默认编码,则用"ISO-8859-1
try {
return encode("ISO-8859-1", ca, off, len);
} catch (UnsupportedEncodingException x) {
// If this code is hit during VM initialization, MessageUtils is
// the only way we will be able to get any kind of error message.
MessageUtils.err("ISO-8859-1 charset not available: "
+ x.toString());
// If we can not find ISO-8859-1 (a required encoding) then things
// are seriously wrong with the installation.
System.exit(1);
return null;
}
}
字符编码转换时候常用到 public String(byte bytes[], String charsetName) 将字节数组按照charsetName编码进行组合识别,最后转换为unicode存储
该函数内部调用的StringCoding.decode(charsetName, bytes, offset, length);
原来认为该方法实现将bytes[]中的数据编码成指定的charsetName,但java实现的确实解码,即用指定的编码来读取bytes[]中的内容,也就是解码的意思,留空则采用系统默认的编码,如中文系统GBK
get方式传输参数乱码问题
原因:
1、chrome浏览器对问号后面的内容按照utf-8( firefox按照系统默认,中文系统一般gbk)进行编码
2、tomcat读取到的字节数组默认采用ISO8859-1编码(内存里是unicode),需要将其编码的数组转换成utf-8或者gbk方能正常显示中文
3、html没有以正确的编码方式显示。 如果html内容以gbk方式编码,但是meta 标签中content="text/html; charset=utf-8" ,即用utf-8解码gbk,必然出现问题。
Tomcat中URIEcoding 默认用ISO8859-1识别字符串,然后转成unicode存储在内存, ISO8859-1 是单字节编码,所以每个字节被按照原样 转换为unicode
String name = request.getParameter("name");
String name2 = new String(name.getBytes("ISO-8859-1"),"utf-8");
out.print(name2);
补充编码的一些知识: