作为非西欧语系的国家,总是要处理编码问题.
请求参数的编码处理,基本上必须分POST与GET的情况来说明.

1.POSt请求参数编码处理,如果客户端没有在Content-Type标头中设置字符编码信息,出现乱码的原因:容器使用的编码处理方式和客户端发送非ASCII字符的请求参数的编码方式不一样,比如网页编码是UTF-8,使用窗体post发送某个中文字符,浏览器会把这个中文方式变为在"UTF-8"编码下的三个字节的对应十六进制数值表示.( GET是HTTP服务器处理,而POST是WEB容器处理(本例使用的是tomcat9).)
在Servlet中取得请求参数时,容器若默认使用ISO-8859-1来处理编码( Tomcat 8以后URIEncoding的默认值为UTF-8,8以前为ISO-8859-1,web容器默认的URIEncoding编码方式只影响GET 请求方式,Post默认的还是ISO-8859-1,仍需设置才能解决)
web容器就会把这个中文字符UTF-8编码的十六进制数值表示按照ISO-8859-1编码方式处理,最终得到的就是乱码了.
案例(POST情况):
form.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
	<form action="request.jsp" method="post">
		姓名: <input type="text" name="name"> <br> 
		密码: <input type="password" name="pass"> 
		      <input type="submit" value="提交">
	</form>
</body>
</html>

可以看出这个网页的编码是UTF-8的.
使用地址栏提供参数的方法输入两个参数 name和pass的值.
表面上地址栏的林看上去还是中文的,但是浏览器是聪明的,它会帮你自动转换成网页的编码方式,也就是"UTF-8".
如下图:
我们可把地址栏复制下来放到一个.txt文件中,就能看到浏览器帮忙转换后的地址栏,如下图:


如上图所示 字被浏览器以"UTF-8"的编码方式处理成十六进制,也就是 %E%9E%97 .

接下来提交请求,跳转到如下页面:
request.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
	<%
		String name = request.getParameter("name");
		String pass = request.getParameter("pass");
	%>
	姓名:<%=name%>
	密码:<%=pass%>
</body>
</html>

显示如下图:

但web容器默认的编码处理方式是ISO-8859-1,如果不加处理就会产生乱码,所以需要更改web容器的编码处理方式:如果浏览器以UTF-8来发送请求,则接收时web容器也要使用UTF-8编码字符串,则可以在取得任何请求值之"前",执行以下语句:
request.setCharacterEncoding("UTF-8");
显示如下图:
这样Post乱码的情况就解决了

GET请求参数编码处理:
request.setCharacterEncoding("UTF-8");这个方法对于请求Body中的字符编码才有作用,也就是基本只对POST产生作用,终究的原因是( GET是HTTP服务器处理,而POST是WEB容器处理(本例使用的是tomcat).)
在tomcat8后,如果网页的编码方式是UTF-8,使用GET方法提交请求是不用处理乱码问题的,因为tomcat8后默认编码处理方式是UTF-8,编码形式不冲突,就不会有乱码问题.
如果网页的编码方式不是"utf-8",则可以采取以下两种方式解决乱码问题.
第一种情况案例:
form.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
	<form action="request.jsp" method="get" >
		姓名: <input type="text" name="name"> <br> 
		密码: <input type="password" name="pass"> 
		      <input type="submit" value="提交">
	</form>
</body>
</html>

request.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
	<%
	    
		String name = request.getParameter("name");
		String pass = request.getParameter("pass");
	%>
	姓名:<%=name%>
	密码:<%=pass%>
</body>
</html>

web容器默认的编码方式是"UTF-8"(我用的tomcat9)
不更改web容器编码方式时运行如下图:


可以看到,是没有中文乱码的
更改web容器的编码方式:
找到server.xml中的这段代码:
改为下面的形式:
更改过后,网页的编码方式是UTF-8,而web容器(tomcat9)编码处理方式由默认的UTF-8变为了ISO-8859-1,这时候就可以看出区别了.
显示如下图:

提交请求后:
这时候就会看到乱码了,通过上述例子,我们可以知道get出现乱码的时候可以通过修改配置文件来解决.
第二种解决方式案例:
配置文件中web容器的编码方式仍然ISO-8859-1是:

form.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
	<form action="request.jsp" method="get" >
		姓名: <input type="text" name="name"> <br> 
		密码: <input type="password" name="pass"> 
		      <input type="submit" value="提交">
	</form>
</body>

request.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
	<%
  //web容器处理时把网页的UTF-8编码方式的十六进制表示直接按照容器默认的ISO-8859-1处理,得到的是中文乱码
		String nameN = request.getParameter("name");//nameN是一个中文乱码
 //在这一步,还原上一步用ISO-8859-1转换的形式,便得到utf-8形式的十六进制表示,然后以UTF-8编码方式再进行一次转换,便得到正确中文字符
		String name = new String(nameN.getBytes("ISO-8859-1"), "UTF-8");

		String pass = request.getParameter("pass");
	%>
	姓名:<%=name%>
	密码:<%=pass%>
</body>
</html>


通过上述处理,Get方法中文乱码的情况就得到解决了.这种通过重新构造为正确编码的字符串在Post中也适用.


Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐