假设现在有个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. Android控制UI界面

    ⒈使用XML布局文件控制UI界面[推荐] Android推荐使用XML布局文件来控制视图,这样不仅简单.明了,而且可以将应用的视图控制逻辑从Java或Kotlin代码中分离出来,放入XML文件中控制, ...

  2. Photon Server初识(一) ---C#链接MySql

    环境: 1.MAC电脑,JetBrains Rider编辑器 2.本地MySql5.7 (开始安装8.1发现使用 NHibernate 映射链接不上) 一.新建工程 二.引入dll包(MySQL.Da ...

  3. python的异常处理机制

    异常机制己经成为衡量一门编程语言是否成熟的标准之一,使用异常处理机制的 Python 程序有更好的容错性,更加健壮. 对于计算机程序而言,情况就更复杂了一一没有人能保证自己写的程序永远不会出辛苦!就算 ...

  4. 流程控制之 while 循环

    目录 流程控制之while while 条件循环语句 while contine while else while 循环的嵌套 流程控制之while while 条件循环语句 循环就是一个重复的过程 ...

  5. 杭电2019多校第一场,Problem I,String 2019

    题目描述 Tom has a string containing only lowercase letters. He wants to choose a subsequence of the str ...

  6. 合并两个排序链表——牛客offer

    题目描述: 输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则. 解题思路: 1.一般看到合并这类的题目就会很自然的想到创建一个新的链表,然后将两个链表根据一定 ...

  7. cookie转换成字典类型方便scraoy 使用

    #bakooie装换成紫电模式方便scrapy使用 cookid = "_ga=GA1.2.1937936278.1538889470; __gads=ID=1ba11c2610acf504 ...

  8. Navicat for Mysql报错1251连接不成功Mysql

    第一步:打开Command Line Client   看清楚不是cmd,是在mysql的目录下,你会发现有2个一模一样其实哪个都行 第二步:输入mysql密码回车    就是安装mysql时设置的密 ...

  9. python之uWSGI和WSGI

    WSGI协议 首先弄清下面几个概念:WSGI:全称是Web Server Gateway Interface,WSGI不是服务器,python模块,框架,API或者任何软件,只是一种规范,描述web ...

  10. UE中正则表达式

    UltraEdit(后简称UE),是我经常使用的文本编辑软件,其功能的强大,令我由衷地爱上了它.每天不用就全身不爽.从最开始的9.0到现在的 12.10a(本人只用到这个版本),UE都是系统重装后必安 ...