JSP项目前后端编码全解(乱码问题,tomcat问题)
本文将介绍jsp项目的各个模块之间的编码转换原理和乱码情形。
约定:
1、提前了解**字符编码自洽现象、乱码**解释
马丁向往未来:巨人:乱码(解码混乱)zhuanlan.zhihu.com[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JULWpwaP-1618084300773)
(https://zhstatic.zhihu.com/assets/zhihu/editor/zhihu-card-default.svg)]马丁向往未来:造作:字符编码自洽zhuanlan.zhihu.com
2、了解jsp技术基本常识
JSP项目相关编码转换过程总结:
【编写**JSP(Java Server Pages)文件->tomcat部署过程(加载JSP文件->转换为java文件->编译为class文件->放入Catalina(一种Servlet容器的实现)目录)】
----等待【接收用户JSP网页HTTP请求->(tomcat部署**过程)->构建网页数据返回用户->浏览器渲染网页数据】
----等待【接收用户网页提交数据->将结果返回用户】
以上过程便是JSP网页技术较为完整的用例图景,我们以下便一一介绍其中的编码转换过程。
编写JSP文件
根据约定,我们称JSP文件为字符编码自洽文件,为什么呢?因为我们可以看到JSP文件中有明显的编码体现,文件本身标明了自己的编码方式。
如下图所示:
我们可以明显的看到‘charset=UTF-8’
同时,我们也可以看看文件的二进制形式:
‘charset=UTF-8’是通用编码字符
所以,倘若我们的login.jsp文件确实是使用utf-8格式编码,那这个.jsp文件便是自洽的。如果文件是自洽的,那Tomcat便理应可以正确的读取到文件中的其他非通用字符编码(例如中文字符),从而完全解码.jsp文件数据。
Tomcat部署过程
Tomcat本身是由java实现的,同时也是在JVM中运行的。JAVA从出生就支持了UTF-8编码,甚至其字符串类型(String)的编码形式就是UFT-8。
所以,倘若jsp文件本身是字符编码自洽的,那么我们可以说Tomcat有责任和义务在将jsp文件翻译为java文件进而编译成class文件的过程中,保持对jsp文件中非通用编码字符的解码能力。用情报学来讲,就是你的下级给你传递了你能理解和解码的情报,你和你的上级们必然有责任和义务继续传递正确的情报(即保持解码能力)。
HTTP请求发送和处理过程
用户的在浏览器上键入一个网址,例如http://256:256:256:256:65532/girl-bbs/login.jsp,请求经过因特网传递到了Tomcat的服务中,其中某个容器通过加载调用login_jsp.class来处理这个请求,并返回HTTP响应(本质上是HTML文件)给了用户。
那这个过程有什么编码转换呢?login_jsp.class处理请求之后生成HTML文件。
这个HTML的文件编码格式是什么呢?我们可以看下图:
我用Fiddler抓包工具截取了返回数据
上图可知,返回的HTML文件数据编码仍然是UTF-8,这就说明,当你将charset设置为UTF-8的时候,用户接收到的数据THML文件编码也是UTF-8。
charset影响着HTTP协议数据的编码
HTTP表单请求
倘若用户再http请求中加入了一些表单数据呢?这些表单数据的编码又是什么?我们的编码又会出现什么问题?
我模拟了简单的表单提交,见下图:
我在网页上输入‘马丁’,然后点击Login
我再次查看一下抓包数据:
表单数据是:userName=%E9%A9%AC%E4%B8%81&password=123&submit=Login
我查了UTF-8的编码:
我改一下网页的编码试试:
我将网页的编码改为了GBK编码
再次提交,查看抓包:
表单数据是:userName=%C2%ED%B6%A1&password=go&submit=Login
我查了GBK的编码:
综上所述:网页提交数据,使用的编码是浏览器页面当前编码[1],那服务器收到的数据便应该是非自洽文本数据[2],那服务器如何解码你提交的数据呢?
答案是:当你私自修改了页面当前编码,服务器无法解码你的提交。惊讶吧,但确实是这样。不过这种情况地的出现需要你**私自修改。**如果你老老实实提交数据,服务器便会以之前约定[3]好的编码去解码。
HTTP表单处理过程
倘若你就是私自把页面编码改为了GBK,那服务器有什么补救措施呢?
对!使用setCharacterEncoding。
request.setCharacterEncoding("gbk");
这样就主动设置服务器用GBK去解码提交数据。
这便是JSP技术中所有的编码解码过程,其实并不复杂。更多的编码转换过程就交由你自己思考吧。
除上文提到的编码设置以外,还有:
- pageEncoding="gbk"
- response.setCharacterEncoding(“gbk”);
- <form name=“form1” action=“login.jsp” method=“post” charset=“gbk”>