假设现在有个form表单,当页面中提交一个包含中文的请求时,在服务端有可能出现中文乱码问题。

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<form action="registerServlet" method="POST">
姓名:<input type="text" name="name"><br>
年龄:<input type="text" name="age"><br>
<input type="submit" value="注册">
</form>
</body>
</html>

乱码的产生原因

  Http协议中规定,数据的传输采用字节编码方式,即无论浏览器提交的数据所包含的中文是什么字符编码格式,一旦由浏览器经过Http 协议传输,则这些数据均将以 字节的形式上传给服务器。 因为 HTTP 协议的底层使用的是 TCP 传输协议。 TCP (Transmission Control Protocol) 传输控制协议 ,是一种面向连接的、可靠的、基于字节流的、端对端的通信协议。在请求中,这些字节均以 开头,并以十六进制形式出现。如 %5A%3D 等。

  当用户通过浏览器提交一个包含 UTF 8 编码格式的两个字的中文请求时,浏览器会将这两个中文字符变为六个字节(一般一个 UTF 8 汉字占用三个字节),即形成六个类似 %8E 的字节表 示形式,并将这六个字节上传至 Tomcat 服务器。Tomcat 服务器在接收到这六个字节后,并不知道它们原始采用的是什么字符编码。而Tomcat 默认的编码格式为 ISO 8859-1 。所以会将这六个字节按照 ISO 8859-1 的格式进行编码,这种编码方式不支持中文,这样就出现了乱码。

关于请求的乱码的解决方案

一、针对POST提交方式的解决方案

<!--
设置了请求正文的字符编码,服务器解码的时候会按照UTF-8解码
但是这种方式对于GET方式的请求不适用,因为只对请求正文有作用,
GET方式的请求正文为空行,请求的参数出现在请求行 -->
request.setCharacterEncoding("UTF-8");

二、针对GET提交方式的解决方案

  对于GET方式提交的情况,上述中设置request.setCharacterEncoding("UTF-8");是不会起作用的,因为GET方式的请求参数是在请求行

  目前了解的两种解决方案:

  ①Tomcat的版本影响,我自己试了一下Tomcat的7.*版本的,什么都不设置的话,会有乱码,但是用7.*以上的Tomcat服务器8.*,9.*的版本就不会出现乱码

  ②当我们以GET方式向服务器提交数据的话,在地址栏中,URL中URI部分的参数提交的中文会以字节的方式显示,对于请求路径中所携带参数的解析,由 Tomcat 服务器完成。而 Tomcat 服务器的字符编码默认为 ISO8859-1 ,所以会将请求路径中所携带的数据,按照 ISO8859 1 进行编码。

  这种情况下我们可以通过修改 Tomcat 默认字符编码的方式来解决 GET 提交方式中携带中文的乱码问题。在 Tomcat 安装目录的 conf/server.xml 中,找到端口号为 8080 的 <Connector>标签,在其中添加 URIEncoding=UTF-8 的设置,即可将 Tomcat 默认字符编码修改为 UTF-8 。

(不建议,如果服务器有多个虚拟服务器,修改后会重启多个应用程序)

三、万能的解决方案(比较通用但是还是有弊端)

String name = request.getParameter("name");
byte[] bytes = name.getBytes("ISO8859-1");
name = new String(bytes, "UTF-8");

  该方式无需设置Tomcat 中的 server.xml 中的 Tomcat 默认字符编码,无需设置 request的请求体的字符编码。从数据在请求中的存放形式,到数据被Tomcat 中的 Servlet 接收到后的存放形式,均是由单个字 节的形式存在,而在众多字符编码格式中, ISO8859-1 为单字节编码,所以,首先以 ISO8859 -1 的形式先对单字节的数据进行编码,并将编码后的数据存放在字节数组中。然后,再将字节数组中的数据,按照指定的 UTF -8 格式进行解码,即变为了需要的 UTF- 8 字符编码的数据,解决了中文乱码问题。

  编码,即重新编排,即打散,将字符串 打散后按照指定编码进行重新编排。 这里的编码使用的是 String 的 getBytes() 方法,完成的工作是:按照当前字符编码将数据打散。

  解码,即解释执行,即组装,对打散的字符按照指定编码组装后进行解释执行。 这里的解码使用的是StringString的带参构造器,完成的工作是:按照原有字符编码将数据组装。的带参构造器,完成的工作是:按照原有字符编码将数据组装。

该方式针对POST与与GET提交方式,均起作用。

响应的乱码问题

产生原因:之所以响应时会产生乱码,是因为 HTTP 协议中规定,默认响应体的字符编码为ISO-8859-1 。所以,若要解决乱码问题,就需要修改响应体的默认编码。

解决方案:

response.setContentType("text/html“);//设置MIME类型
response.setCharacterEncoding("UTF-8");

  修改 MIME 的字符编码,即修改响应体的字符编码。但使用 setCharacterEncoding() 方法的前提是,之前必须要通过使用方法 setContentType() 方法设置响应内容的 MIME 类型。否则 setCharacterEncoding() 方法不起作用。

response.setContentType("text/html;charset=UTF-8");

 用于 设置响应 内容 的 MIME 类型 ,其中可以指定 MIME 的字符编码。而 MIME 的字符编码,即响应体的字符编码 。

 ①②是一样的,没啥区别!!!

  浏览器会根据响应体字符编码,自动调整其对响应体内容的解码方式,即会使用响应体的字符编码显示响应体内容。不过,需要注意一点,这些设置,必须在PrintWriter 对象产生之前先设置,否则将不起作用。

重定向的乱码解决方式

//底层按字节流传输,打散
name = URLEncoder.encode(name, "UTF-8"); //另一边接收
//组装
name = URLDecoder.decode(name, "UTF-8");
byte[] bytes = name.getBytes("ISO8859-1");
name = new String(bytes, "UTF-8");

Servlet中的乱码问题及解决办法的更多相关文章

  1. Linux下Oracle中SqlPlus时上下左右键乱码问题的解决办法

    window下的sqlplus可以通过箭头键,来回看历史命令,用起来非常的方便. 但是在Linux下,会出现各种乱码,非常不方便,如下图所示,每次打错一个字符就需要重新打一遍. 解决办法:rlwrap ...

  2. eclipse中js中文乱码问题的解决办法

    在Eclipse中编辑JS文件简直是一种折磨,但是却总是很无奈得要去适应. 这里说一下Eclipse中,编辑JS文件时候,出现中文乱码问题的解决办法. 这个问题很容易想到是文件编码的问题,因此通常是修 ...

  3. (tamcat控制台乱码)在idea中运行toncat后控制台出现乱码的情况解决办法(教程附图)。

    详细教程: (tamcat控制台乱码)在idea中运行toncat后控制台出现乱码的情况解决办法(教程附图)._IT打工酱的博客-CSDN博客

  4. iOS 学习笔记二【cocopods安装使用和安装过程中遇到的问题及解决办法】【20160725更新】

    在osx 10.11之前cocopods问题不多,但是升级到11之后的版本,之前的cocopods大多用不了,需要重新安装,对于我这种使用测试版系统的技术狂来说,每次都需要重新安装很多东西, 当然,c ...

  5. MyEclipse代码编辑器中汉字太小的解决办法(中文看不清)

    问题描述:新安装的myeclipse 2014,代码编辑器中汉字很小看不清 解决办法:调整字体即可.通过菜单Windows——Preferences,输入font过滤选择Colors and Font ...

  6. 虚拟机中不能连接usb设备解决办法

    虚拟机中不能连接usb设备解决办法 1.点击开始->运行,在对话框中输入"services.msc",确定,打开windows服务管理器.2.在服务列表中选中"VM ...

  7. Aasible中cryptography兼容性报错解决办法

    Aasible中cryptography兼容性报错解决办法 1 Ansible中使用ansible --version查看版本,报错信息如下: ERROR! Unexpected Exception, ...

  8. windows10中git-bash闪退的解决办法

    windows10中git-bash闪退的解决办法 出现错误详情 Windows10 64位专业版安装git .18之后出现 Git闪退,报错信息:bash: /dev/null: No such d ...

  9. SVN版本冲突中 Files 的值“ < < < < < < < .mine”无效路径中具有非法字符的解决办法

    .NET 中 SVN版本冲突中 Files 的值“ < < < < < < < .mine”无效路径中具有非法字符的解决办法: 一. 1.将项目逐个进行编译, ...

随机推荐

  1. 数据排序 sort

    排序命令: 常和管道进行协作的命令  -sort  (默认使用字符的第一个字符进行排序) -n  按数字排序 -r  反序排序 -o  结果 输出到文件 -t  分隔符 (sort -n -t &qu ...

  2. HDU1285(拓扑排序裸题

    ..被多组测试坑了一波 #include<iostream> #include<vector> #include<queue> using namespace st ...

  3. 链表分割——牛客剑指offer

    题目描述: 编写代码,以给定值x为基准将链表分割成两部分,所有小于x的结点排在大于或等于x的结点之前 给定一个链表的头指针 ListNode pHead,请返回重新排列后的链表的头指针.注意:分割以后 ...

  4. 推荐系统遇上深度学习(十)--GBDT+LR融合方案实战

    推荐系统遇上深度学习(十)--GBDT+LR融合方案实战 0.8012018.05.19 16:17:18字数 2068阅读 22568 推荐系统遇上深度学习系列:推荐系统遇上深度学习(一)--FM模 ...

  5. spring jpa 学习笔记(一) 之集成

    一.pom 配置 <?xml version="1.0"?> <project xsi:schemaLocation="http://maven.apa ...

  6. 搭建自己的框架WedeNet(二)

    WedeNet2018.Infrastructure-基础设施层:结构如下: Tools结构如下: 考虑到系统可能会有多个数据上下文(暂时以两个为例),所以根据需要定义两个T4模板用来生成对应的ent ...

  7. 服务端相关知识学习(五)之Zookeeper leader选举

    在上一篇文章中我们大致浏览了zookeeper的启动过程,并且提到在Zookeeper的启动过程中leader选举是非常重要而且最复杂的一个环节.那么什么是leader选举呢?zookeeper为什么 ...

  8. element ui input框不能输入的问题(实时学习)

    解决: 在input的上面添加数据v-model 既可以 1.菜单中api (2018年8月14号) :default-active  默认根据当前路由选中菜单,值需要和  el-submenu 的属 ...

  9. Jetson TX1 安装ROS操作系统

    直接按照官网上的步骤安装即可,其中会出现很多bug,主要是依赖库安装的问题,添加清华源和中科大源,(注意:中科大源会有些问题)需要apt-get update 和 apt-get upgrade更新库 ...

  10. selenium:能够模拟人类打开浏览器的爬虫利器

    介绍 selenium相当于是一个机器人,可以模拟人类登陆浏览器的行为,比如点击.填充数据.删除cookie等等.Chromedriver是一个驱动Chrome的程序,使用它才可以驱动浏览器,其实Ch ...