标签:
字符编码
字符编码就是以二进制的数字来对应字符集的字符,常见字符编码方式有:ISO-8859-1(不支持中文),GB2312,GBK,UTF-8等.在JavaWeb中, 经常遇到的需要编码/解码的场景有响应编码/请求编码/URL编码:
响应编码
服务器发送数据给客户端由Response对象完成,如果响应数据是二进制流,就无需考虑编码问题.如果响应数据为字符流,那么就一定要考虑编码问题:
response.getWriter()默认使用ISO-889-1发送数据,而该字符集不支持中文,因此遇到中文就一定会乱码.
在需要发送中文时, 需要使用:
response.setCharacterEncoding("UTF-8");
// getWriter() ...
设置编码方式,由于在getWriter()输出前已经设置了UTF-8编码,因此输出字符均为UTF-8编码,但我们并未告诉客户端使用什么编码来读取响应数据,因此我们需要在响应头中设置编码信息(使用Content-Type):
response.setContentType("text/html;charset=UTF-8");
// getWriter() ...
注意: 这句代码不只在响应头中添加了编码信息,还相当于调用了一次response.setCharacterEncoding("UTF-8");
请求编码
1. 浏览器地址栏编码
在浏览器地址栏书写字符数据,由浏览器编码后发送给服务器,因此如果在地址栏输入中文,则其编码方式由浏览器决定:
浏览器 | 编码 |
---|---|
IE/FireFox | GB2312 |
Chrome | UTF-8 |
2. 页面请求
如果通过页面的超链接/表单向服务器发送数据,那么其编码方式由当前页面的编码方式确定:
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
3. GET
当客户端发送GET请求时,无论客户端发送的数据编码方式为何,服务端均以ISO-8859-1解码(Tomcat8.x之后改用UTF-8),这就需要我们在request.getParameter()获取数据后再转换成正确的编码:
private Map<String, String> convertToParameterMap(HttpServletRequest request) throws UnsupportedEncodingException {
Enumeration<String> names = request.getParameterNames();
Map<String, String> parameters = new HashMap<String, String>();
if (names != null) {
while (names.hasMoreElements()) {
String name = names.nextElement();
String value = request.getParameter(name);
parameters.put(name, new String(value.getBytes("ISO-8859-1"), "UTF-8"));
}
}
return parameters;
}
4. POST
当客户端发送POST请求时,服务端也是默认使用iOS-8859-1解码,但POST的数据是通过请求体传送过来,因此POST请求可以通过request.setCharacterEncoding()来指定请求体编码方式:
private Map<String, String> convertToParameterMap(HttpServletRequest request) throws IOException {
Map<String, String> parameters = new HashMap<String, String>();
if (request.getMethod().equals("POST")) {
request.setCharacterEncoding("UTF-8");
Enumeration<String> names = request.getParameterNames();
while (names.hasMoreElements()) {
String key = names.nextElement();
parameters.put(key, request.getParameter(key));
}
} else {
Enumeration<String> names = request.getParameterNames();
while (names.hasMoreElements()) {
String key = names.nextElement();
String value = request.getParameter(key);
parameters.put(key, new String(value.getBytes("ISO-8859-1"), "UTF-8"));
}
}
return parameters;
}
URL编码
网络标准RFC 1738规定:
“…Only alphanumerics [0-9a-zA-Z], the special characters "$-_.+!*‘()," [not including the quotes - ed], and reserved characters used for their reserved purposes may be used unencoded within a URL.”
“只有字母和数字[0-9a-zA-Z]、一些特殊符号"$-_.+!*‘(),"[不包括双引号]、以及某些保留字,才可以不经过编码直接用于URL。”
如果URL中有汉字,就必须编码后使用, 而URL编码过程其实很简单:
首先需要指定一种字符编码,把字符串解码后得到byte[],然后把小于0的字节+256,再将其转换成16进制,最后前面再添加一个%.
这个编码过程在Java中已经封装成了现成的库, 可直接使用:
URLEncoder | 描述 |
---|---|
static String encode(String s, String enc) |
Translates a string into application/x-www-form-urlencoded format using a specific encoding scheme. |
URLDecoder | 描述 |
---|---|
static String decode(String s, String enc) |
Decodes a application/x-www-form-urlencoded string using a specific encoding scheme. |
注: 在Web中Tomcat容器会自动识别URL是否已经编码并自动解码.
标签:
原文地址:http://www.cnblogs.com/gossip/p/5725193.html