- 客户端编码与服务器解码全过程_gaoge19861207的专栏-CSDN博客
- 深入分析 web 请求响应中的编码问题_weweeeeeeee的博客-CSDN博客
- Tomcat web 编解码过程_zhangbinalan的专栏-CSDN博客
- 关于 tomcat7 和 tomcat8 服务器编码的解释_LawssssCat的博客-CSDN博客
- java web 一次请求编码设置的过程 - 人生已是如此的艰难 - 博客园
原始代码:使用Tomcat7.x服务器 客户端(使用了谷歌验证码):
<%@ page contentType="text/html;charset=UTF-8" language="java" %> ......servlet程序:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取Session中的验证码
String token = (String) request.getSession().getAttribute(KAPTCHA_SESSION_KEY);
//删除Session中的验证码
request.getSession().removeAttribute(KAPTCHA_SESSION_KEY);
String code = request.getParameter("code");
String username = request.getParameter("username");
if(token != null && token.equalsIgnoreCase(code)){
System.out.println("保存到数据库:" + username);
response.sendRedirect(request.getContextPath() + "/ok.jsp");
}else{
System.out.println("请不要重复提交表单");
}
}
终端输出:
知识回顾:
-
tomcat7中关于connector的编码默认为"
iso8859-1
";
tomcat8中connector的编码默认为"
utf-8
"
- 所以 tomcat7默认的解码方式是:输入ISO8859-1的编码方式进行解码
-
浏览器呈现的两种web页面:html页面和jsp页面
-
通过表单提交发起的请求:对于表单中的参数,
无论是
通过
get
方法(通过
URL
查询参数)还是
post
方法(通过请求体)提交,浏览器(谷歌、火狐、IE)都会根据页面的
ContentType("text/html; charset=enc")
中指定的编码对表单中的数据进行编码,然后发给服务器。
- 通过3和4可知:网页(html文件或者jsp文件)在浏览器上的解码方式 就是 当前网页的表单数据提交给服务器前进行编码的方式
-
jsp文件本身的编码:pageEncoding;服务器发送给客户端浏览器时的内容编码(服务器通过响应头来通知客户端以那种编码形式来进行解码呈现web页面(jsp文件/html页面)的内容):
contentType
的
charset
- contentType 里的 charset="utf-8" ,指的是此web文件输出到浏览器的输出方式为 utf-8 。在这个过程中,一个 JSP 的源文件需要经过三个阶段,两次编码,才能完成一次完整的输出。(服务器响应到客户端的过程)
-
第三阶段:从服务器到浏览器,这在一过程中用到的指令是contentType。服务器载入和执行由第二阶段生成出来JAVA二进制码,输出的结果,也就是在客户端可见到的结果,在这次输出过程中,由contentType属性中的charset来指定,将UTF8形式的二进制码以charset的编码形式来输出。
如果没有人为设定,则默认的是ISO-8859-1的形式
。----
java web 一次请求编码设置的过程 - 人生已是如此的艰难 - 博客园
- 由4.可知 如果没有人为设定 contentType属性中的charset,客户端将以ISO-8859-1的编码方式对表单数据进行编码
- 【 客户端发送的数据在请求行中】
- 【 客户端发送的数据在请求体中】
- 对英文字符来说UTF-8编码和ISO-8859-1编码的效果相同
- UTF-8编码的格式:一个汉字来三个字节构成,每一个字节会转换成 16进制的编码 ,同时添加上%号
- 客户端浏览器地址栏中向服务器发送请求: http: 服务器地址: port/ 工程名 /regist.jsp
-
其中 Regist.jsp中:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
- 浏览器中呈现以utf-8编码方式解码的regist.jsp文件
- GET方式提交表单,提交表单时表单数据会按照utf-8 来编码数据。因为是GET 方式,这些数据(已经编码好成为字节了)位于http请求行中。
- 将http请求发送到服务器
-
服务端收到客户端的 HTTP 请求,
中间件/应用服务器
会针对每一次请求分别创建一个 request 对象和 response 对象。
- request 对象是 服务器端 操作 客户端发送过来的数据 的容器。
- response 对象是 服务器端 操作 服务端发出的数据 的容器。
- Tomcat7.x中默认的编码方式是ISO8859-1,所以也默认使用ISO8859-1对GET请求行中的数据进行解码
- 得到 ISO8859-1解码后的乱码
- 因为原数据的编码方式是utf-8,并且被使用ISO8859-1编码方式进行了解码,所以先使用ISO8859-1对乱码进行编码,得到字节数组,然后再使用UTF-8对字节数据进行解码即可。
String username = request.getParameter("username");//乱码
username = new String(username.getBytes("ISO8859-1"),"UTF-8");//没有乱码
POST乱码原因分析:
因为:
通过表单提交发起的请求:对于表单中的参数,
无论是
通过
get
方法(通过
URL
查询参数)
还是
post
方法(通过请求体)提交,浏览器(谷歌、火狐、IE)都会根据页面的
ContentType("text/html;
charset=enc")
中指定的编码
对表单中的数据进行编码,然后发给服务器。
所以:post请求体中的数据也是通过UTF-8进行编码后将http请求发送给服务器,然后Tomcat7.x服务器使用默认的ISO8859-1编码方式进行解码,从而导致中文乱码问题。
POST乱码解决方案:
- 仍可以通过GET中的解决方式解决POST乱码,即:
String username = request.getParameter("username");//乱码
username = new String(username.getBytes("ISO8859-1"),"UTF-8");//没有乱码
2. 因为:request 对象是
服务器端 操作 客户端发送过来的数据 的容器。所以可以通过改变request对象的请求体中的编码方式(从而改变了服务器对request对象的请求体中的解码方式),使得Tomcat7.x服务器对request对象的请求体中的默认解码方式变为指定编码的解码方式。
request.setCharacterEncoding("UTF-8");//在获取请求参数前使用
- 注:因为改变的是request对象的请求体中的编码方式,所以对GET的乱码无效。



