编码基础知识
ISO-8859-1
ISO-8859-1 的较低部分(从 1 到 127 之间的代码)。
ISO-8859-1 的较高部分(从 160 到 255 之间的代码)。
因此只能表示一些数字,英文字母和西欧语言、希腊语、泰语、阿拉伯语、希伯来语对应的文字符号
单字节,即一个字节对应一个编码,不能编码汉字
GBK
1) 能编码汉字,一个汉字用2个字节编码
2) 编码的汉字比GB2312更多
GB2312
能编码汉字,一个汉字用2个字节编码
UTF-8
英文字母用一个字节表示,一个汉字用3个字节表示
字符集范围包括:汉字、字母、符号
编码和解码
原理
我们平时看到的“美女”是字符,是一种逻辑展示,计算机不会直接存储一个这样的字符串,
考虑重用,计算机存储的基本单位是字节,然后由字节来表示字符,比如a用[97]表示
这种映射关系就叫做编码,因此一个字符串要被编码成字节之后才能被计算机存储,网络传输
也是如此,都是以字节的形式传输。
将字节还原成字符的过程叫做解码。
那么就要规定编码和解码的规则要相同,否则就会造成乱码
servlet容器中遇到的编码问题
接收浏览器POST请求
客户端是浏览器
服务端是servlet容器
那么首先,客户端要指定编码的方式,以html为例:
html4:<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
html5:<meta charset="utf-8"/>
此标签的作用不是浏览器展示时用的,而是浏览发起post请求时,按此编码将
发送的内容编码为字节。
servlet服务端解码方式:
request.setCharacterEncoding("utf-8");
String name = request.getParameter("name");
接收浏览器GET请求
如:
http://localhost:8888/webtest/EncodeServlet?name=你好
浏览器将会对url进行urlEncode,编码方式为UTF-8
服务端解码方式:
String name = new String(request.getParameter("name").getBytes("ISO-8859-1"),"UTF-8");
此处用request.setCharacterEncoding("UTF-8");来设置解码,不能奏效,原因是get请求将参数拼在url后面进行url encode,而web容器对url的解码是在调用servlet之前,且默认解码方式是iso-8859-1
当然这个uri encode的可以修改的,其实中国人开发的程序,就应该讲uri的编码也设置成utf-8而不是iso-8859-1
如果是tomcat,则修改位置如下:
<Connector connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443" URIEncoding="UTF-8"/>
响应给浏览器
Response设置编码:
Response是指响应给客户端时,字节的编码方式,默认为ISO-8859-1
可用如下方法查看:
response.getCharacterEncoding();
设置响应流的编码方式:
response.setCharacterEncoding("UTF-8");
设置浏览器的解码方式:
response.setContentType("text/html;charset=UTF-8");
此设置是告知客户端按此编码来解码
Struts2 和Spring 设置编码问题
Struts2
Struts.xml中做如下配置:
<constant name="struts.i18n.encoding" value="utf-8"></constant>
Spring
Web.xml中配置如下:
<filter>
<filter-name>encodingFilter</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter
</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
其中encoding设置服务端编码和解码的方式
forceEncoding表示强制编码的方式
字符串转字节转码
String s = "s汉";
byte[] bytes1 = s.getBytes("ISO-8859-1");//丢失字符
byte[] bytes2 = s.getBytes("GBK");
byte[] bytes3 = s.getBytes("UTF-8");
字节转字符串
String s1 = new String(bytes1,"utf-8");//丢失
String s2 = new String(bytes2,"GBK");
String s3 = new String(bytes3,"utf-8");