Servlet出现中文乱码的问题
中文乱码问题
当页面中提交一个包含中文的请求时,在服务端有可能出现中文乱码问题。
一、乱码的产生原因
Http 协议中规定,数据的传输采用字节编码(unicode)方式,即无论浏览器提交的数据所包含的中文是什么字符编码格式,一旦由浏览器经过 Http 协议传输,则这些数据均将以字节的形式上传给服务器。因为 HTTP 协议的底层使用的是 TCP 传输协议。TCP(Transmission Control Protocol:传输控制协议)是一种面向连接的、可靠的、基于字节流的、端对端的通信协议。在请求中,这些字节均以 % 开头,并以十六进制形式出现。如%5A%3D等。
那么,乱码是如何产生的呢?
当用户通过浏览器提交一个包含 UTF-8 编码格式的两个字的中文请求时,浏览器会将这两个中文字符变为六个字节(一般一个UTF-8汉字占用三个字节),即形成六个类似%8E的字节表示形式,并将这六个字节。上传至 Tomcat 服务器。
Tomcat 服务器在接收到这六个字节后,并不知道它们原始采用的是什么字符编码。而 Tomcat 默认的编码格式为 IS0-8859-1。所以会将这六个字节按照【IS0-8859-1】的格式进行编码,编码后在控制台显示,所以在控制台会显示乱码。
- 如果浏览器以【GET方式】发送请求,【请求参数】在【请求头】存放,在请求协议包到达服务端之后,【请求头】内容是由 Tomcat 负责解析,Tomcat8、9 在解析数据时,默认采用的字符集【UTF-8】,所以如果浏览器以【GET】方式发送中文参数,此时在服务端不会出现中文乱码问题
- 如果浏览器以【POST方式】发送请求,【请求参数】在【请求体】存放,在请求协议包到达服务端之后,【请求体】内容是由对应【请求对象request】负责解码的。request 对象默认使用【IS0-8859-1】字符集。所以如果浏览器以【POST方式】方式发送中文参数,此时在服务端必会出现中文乱码问题
二、乱码的产生演示
login.jsp:
<form action="/myWeb/three.do" method="get">
用户名:<input type="text" name="username" /><br>
<input type="submit" value="登录">
</form>
ThreeServlet:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String username = request.getParameter("username");
response.getWriter.println("username = " + username);
}
提交后访问Servlet出现乱码:
三、乱码的解决方案
1、解决POST提交时的中文乱码问题
setCharacterEncoding( )方法设置了请求正文中的字符编码
request.setCharacterEncoding("UTF-8");
2、解决GET提交时的中文乱码问题
注意:Tomcat 8、9版本的问题已解决,这里针对的是Tomcat7及以下版本
使用GET提交时,若请求中携带有中文,为什么会产生乱码?
当用户提交了一个包含中文参数的请求时,浏览器首先会将这些中文转化为一个字节序列,发送到服务器。服务器接收到这个字节序列后,会按照其默认的字符编码【IS0-8859-1】对其进行解码,此时就产生了乱码。但紧接着,服务器会将解码过的参数存放到 parameterMap 中,那么这个Map中的参数已经是乱码了。
(1)在 Tomcat 配置文件中设置(当一个 Tomcat 中只有少数项目时可以使用,不常用)
加入以下一段话:URIEncoding=“UTF-8”
(2)对于请求中的中文乱码的万能解决方案
//这里接收到的name,其字符编码为IS0-8859-1
String name = request.getParameter("name");
//打散:将name字符串按照原编码进行打散
byte[] bytes = name.getBytes("IS08859-1");
//组装:将bytes字节数组按照指定字符编码进行组装,组装为String
name = new String(bytes,"UTF-8");
//但一般情况下都组合起来写
name = new String(name.getBytes("IS08859-1"),"UTF-8");
注意:这里每次接收请求参数,都需进行一次这样的代码,重复性高。
3、解决response响应时的中文乱码问题
(1)设置响应的 MIME 类型( video/mp4,image/jpg ),其中可以指定 MIME 的字符编码,即响应体的字符编码(常用)
response.setContentType("text/html;charset=UTF-8");
(2)setCharacterEncoding() 方法的使用前提是:之前必须要先使用 setContentType() 方法,setCharacterEncoding( )方法用于修改ContentType的MIME类型字符编码
response.setContentType("text/html");
response.setCharacterEncoding("UTF-8");
推荐阅读
-
Servlet出现中文乱码的问题
-
python写入csv文件的中文乱码问题
-
servlet2.3规范中文版 博客分类: 我的文档中心 ServletWeb应用服务器网络应用JSP
-
android自更新时下载出现的问题 博客分类: Java 下载downloadHttpStatusandroid 下载
-
解决springmvc下载poi生成excel的乱码问题
-
jsp中文问题的解决 JSPTomcatXMLApache
-
JSP中用jsp:param传递中文参数出现乱码?
-
HTTP消息头Content-Disposition 的运用(国际化语言环境下下载文件时文件名乱码问题处理)
-
web设置下载文件的头信息(可解决中文文件命令乱码问题)
-
Servlet--下载文件时文件名为中文乱码解决