部分一(POST),另外这些测试都是在Tomcat 7上进行测试的:
这是一个前端jsp页面,有一个超链接和post方式提交数据的表单:
<form action="<c:url value='/AServlet'/>" method="post"> <!-- form.jsp -->
用户名:<input type="text" name="username" value="胶布虫"/>
<input type="submit" value="提交"/>
</form>
在页面中点击表单或链接,如果页面的编码是utf-8, 那么从浏览器传递到服务器的数据的编码也是utf-8的。
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
/*
* response.setContentType("text/html;charset=utf-8");
* 这个方法不仅会调用 response.setCharaceterEncoding("utf-8"),
* 还会设置content-type响应头,客户端浏览器会使用content-type头来解码响应数据。
*/
response.setContentType("text/html;charset=utf-8");
/*
* request.setCharacterEncoding("utf-8");
* 设置请求编码,只对请求体有效!但对于GET而言,没有请求体!!!
* 所以此方法只能对POST请求体中的参数有效!
*
* 如果一个前端页面的编码是utf-8, 那么从客户端传过来的数据就是utf-8编码的
* 这句话的意思就是告诉服务器以utf-8去解码传过来的数据
*
* 如果form.jsp文件的编码是gbk的话,这里的处理就不合适了,应设置为gbk
* 这样从客户端传过来的数据就是gbk编码的,需要让服务器知道以哪种编码去解码
* 所以应设置为 request.setCharacterEncoding("gbk");
*/
request.setCharacterEncoding("utf-8");
String username = request.getParameter("username"); //用指定的编码去获取数据
response.getWriter().println(username);
}
上面代码注释中提到了request.setCharacterEncoding("utf-8");只会对POST请求的请求体中的参数数据有效,下面是一段HTTP协议POST请求时的请求头:
POST /http/post.php HTTP/1.1
Host:localhost
Content-type:application/x-www-form-urlencoded
Content-length:27
username=Jack Chou&sex=male //这就是请求体
In total: 对于post传递的数据,只要使用:
response.setContentType("text/html;charset=utf-8"); //utf-8,这个编码与你的客户端表单页面的文件编码一致
request.setCharacterEncoding("utf-8");
就可以解决乱码问题。
部分二(GET):
<a href="<c:url value='/AServlet?username=胶布虫'/>">点击</a>
</pre><p><pre name="code" class="java">public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
String username = request.getParameter("username"); //此处username是ISO-8859-1解码的数据
/*
* GET请求的数据到达服务器后,服务器使用默认的ISO-8859-1去解码
* username.getBytes("ISO-8859-1") 使用ISO-8859-1去编码username
* 这样一个转换,就得到了原先从客户端通过GET方式传过来的以utf-8编码的数据
* 再用utf-8解码,username中的数据就是正常的了
* new String(username.getBytes("ISO-8859-1"), "utf-8")
*/
username = new String(username.getBytes("ISO-8859-1"), "utf-8");
response.getWriter().println(username);
}
下面这个同理:
<form action="<c:url value='/AServlet'/>" method="get">
用户名:<input type="text" name="username" value="胶布虫"/>
<input type="submit" value="提交"/>
</form>
In total:对于GET方式传递的数据只需在服务器端进行编码转换,就可以得到正常的数据,如:
username = new String(username.getBytes("ISO-8859-1"), "utf-8");
再来一段代码模拟这种get请求的情况(我是这样理解的,欢迎拍砖):
/**
* username = new String(username.getBytes("ISO-8859-1"), "utf-8");
* 模拟一下这种情况
*/
@Test
public void testUtfTransfer() throws Exception {
String utfEncode = "我是胶布虫"; /** utf8编码 */
byte[] ureEncodeByte = utfEncode.getBytes("UTF-8"); /** 模拟从网络中传过来的utf-8编码的二进制数据 */
/**
* utf-8 字节 <----ISO8859-1----> 具体字符
*/
/**在Get Post方法中收到的字符串 其实是通过了下种方式解码的*/
String iso = new String(ureEncodeByte, "ISO8859-1"); /** ISO8859-1解码获取数据 */
/** 又以ISO8859-1 编码回去 */
byte[] isoByte = iso.getBytes("ISO8859-1");
System.out.println(new String(isoByte, "utf-8")); // 输出正常
}