使用 servlet 向客户端浏览器回送中文时,经常出现中文乱码的问题,这里给大家完完全全地搞明白:

一、基本常识

  1. 中文系统默认是 GBK 编码(GBK是对GB2312的补充,包含它)

  2. 需要处理编码问题的地方:

    1. 浏览器发送请求(Request)时,所用的编码格式;
    2. Web 服务器响应(Response)回送的数据,所用的编码格式;
    3. 浏览器解析响应回送的数据,所用的编码格式;
    • 又分为两种情况:

      • 请求发生乱码往往是 servlet 程序获取请求信息时,获取的信息乱码,问题产生在服务端;
      • 而客户端浏览器出现,往往是2、3两处的编码格式不一造成的;
  3. 查看平台默认字符编码方法:java.nio.charset.Charset.defaultCharset();

  4. HttpServletResponse 类中的 getOutputStream() 获取的字节节流,用于向浏览器输出二进制数据(图片、视频等任何形式数据);而 getWriter() 获取的是字符输出流,用于输出文本数据,二者不能同时使用;

  5. getBytes() 方法通过平台默认字符集进行编码,可传传递参数指定字符集(如 getBytes("UTF-8"))

二、了解编码的过程

​ 以我们要解决的问题角度出发:编码是将文字按照一种规范转变成另一种形式的过程;而解码,是编码的逆过程;这中间的依据也就是那个规范,就是字符集(编码表,如 UTF-8、GBK)。

​ 编码时,程序从字符集中寻找字符在此字符集里的一个"编号"(往往是一种更利于计算机使用字符);这些编号组成的数据,无论传递到什么平台,最后接收数据的平台使用,同一字符集进行解码,就能获取到原本的数据,过程:用接收到的编码数据,从字符集中寻找对应表示的字符进行还原,最终数据的完美传递。

三、解决乱码问题

Request 乱码

从浏览器发起的访问方式有三种:

  1. 在地址栏直接输入URL访问:浏览器默认将请求参数按 UTF-8 进行编码,
  2. 点击超链接访问:浏览器将参数按照当前页面的显示编码进行编码
  3. 提交表单访问:同上

网上常用的设置表单的方法:request.setCharacterEncoding("UTF-8")只对 POST 请求方式有效,所以解决请求乱码要针对两个情况:

GET 方式

get请求乱码解决办法一:修改服务器端对URI参数的默认编码

get请求乱码办法一:修改服务器端对URI参数的默认编码

在tomcat的server.xml中,设置元素的属性URIEncoding=”UTF-8”即可。(默认没有设置此属性)

扩展:

1.设置元素的属性useBodyEncodingForURI=“true”,意思是请求体和uri使用相同的编码格式。

通过设置这两个属性,既可以解决get方式的乱码,又可以解决post方式的乱码。

2.通过修改server.xml指定服务器对get和post统一按照utf-8解码,要求tomcat管理下的所有web应用都要使用utf-8编码,即所有的jsp、html页面都必须使用utf-8编码。

 <Connector connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443"
URIEncoding="UTF-8" useBodyEncodingForURI="true"/>

get请求乱码办法二:逆向操作

参数从浏览器到服务器,经过客户端编码,服务器端解码,最终成为乱码。那我们将乱码进行相反的编解码,即可得到正常的参数值。此时注意上文提到的编码规律总结,只有源头对了,才能成功解决问题。

String name = request.getParameter("name");//得到乱码的数据
name = new String(name.getBytes("GBK"),"utf-8");
//将得到的数据进行GBK方式解码,然后把得到的字节再通过UTF-8编码,得到正常的name值

get请求乱码方法三:手动编码解码

在JSP页面中先把中文编码后再提交,服务器获取后再按照同样的方式解码

//场景:从网页下载,文件名为中文
...
String filePath = "D:\\javacode\\javaweb_Servlet2\\response\\src\\main\\webapp\\哈哈11.xml";
// 通过一些方法,从路径中提取出 文件名:
//通过获取最后一个 / 的脚标 + 1 确定文件名的第一个字符索引,而后从此索引开始截取字符串,就是文件名
String fileName = filePath.substring(filePath.lastIndexOf("\\") + 1);
//URLEncoder.encode() 方法设置以指定字符集对文件名进行编码
resp.setHeader("Content-Disposition","attachment;filename=" + URLEncoder.encode(fileName,"utf-8"));
...

POST 方式

​ post方式提交的参数存在于请求体中,浏览器将参数按照当前页面的显示编码进行编码页面的编码方式一般情况下已经被设置成了UTF-8,只需要修改服务端解码方式(与浏览器页面编码方式一致) ```java

request.setCharacterEncoding(“UTF-8”);

Response 乱码

​ 实际遇到更多的乱码情况是浏览器接收响应数据的乱码,我们需要了解发生乱码的流程:

​ 首先 getBytes() 以 UTF-8 字符集对字符串进行编码,并写入响应对象,响应数据回送至浏览器,浏览器默认使用平台默认编码(中文系统)进行解码,用 GB 码表解码 UTF-8 的编码的数据,结果就是出现乱码。

​ 所以我们要做的使:响应所回送数据所用字符集 和 浏览器用来解析回送数据所用字符集相同

设置浏览器的解码格式:

response.setHeader("content-type","text/html;charset=UTF-8");
//或
response.setContentType("text/html;charset=utf-8");

大白话说就是用 content-type 响应头,告诉浏览器我回送过来的数据时 text/html 类型,要用 UTF-8 字符集解码;

设置好浏览器用于解析响应回送数据的字符集后,现在要设置响应回送的数据字符集,分为两种情况,也就是最开始提到的,处理字节和字符流数据是有差异的:

  1. 使用 response.getWriter() 流写出的的数据乱码解决方式:
//设置将发送到客户端的响应 的字符编码,只能用于设置 getWritet()的字符编码
response.setCharactEncoding("UTF-8");
//同时设置浏览器的解码方式
response.setHeader("content-type","text/html;charset=UTF-8");

需要在调用 getWriter() 方法前 和 响应提交前使用

  1. 使用 response.getOutputStream() 流写出的数据乱码解决方式:
//服务端对字符进行编码的时候,指定编码方式
response.getOutputStream().write("汉字".getBytes("UTF-8"));
//同时设置浏览器的解码方式
response.setHeader("content-type","text/html;charset=UTF-8");

字符响应流只用用来输出字符,而字节响应流可以用来输出任何东西

四、扩展:

  1. 查看当前响应头所设置的字符编码(没有获取到字符集类型说明是默认的):response.getContentType()
  2. 可使用 response.writer().print() 传递 HTML 标签代码间接设置网页的编码格式,如:
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//直接向网页输出 HTML 标签代码
response.getWriter().println("<meta http-equiv='Content-Type' content='text/html; charset=utf-8'>");
}
  1. 为了避免可能的失误,直接将设置编码相关代码放在最前面(无论是后端还是前端)

参考:response与request中文乱码问题及解决方式 Servlet 中文乱码问题及解决方案剖析

Servlet 中文乱码问题解析及详细解决方法的更多相关文章

  1. php -- 解决php连接sqlserver2005中文乱码问题(附详细解决方法)

    @_@~~ --php5.2 --phpstudy --apache --sqlserver2005 @_@~~问题描述 问题一:php连接sqlsever2005,输入中文,然后查询sqlserve ...

  2. Code:Blocks 中文乱码问题原因分析和解决方法

    下面说说修改的地方. 1.修改源文件保存编码在:settings->Editor->gernal settings 看到右边的Encoding group Box了吗?如下图所示: Use ...

  3. JSP中文乱码问题的由来以及解决方法

    首先明确一点,在计算机中,只有二进制的数据! 一.java_web乱码问题的由来 1.字符集 1.1 ASCII字符集 在早期的计算机系统中,使用的字符非常少,这些字符包括26个英文字母.数字符号和一 ...

  4. Python BeautifulSoup中文乱码问题的2种解决方法

    解决方法一: 使用python的BeautifulSoup来抓取网页然后输出网页标题,但是输出的总是乱码,找了好久找到解决办法,下面分享给大家首先是代码 from bs4 import Beautif ...

  5. XFTP连接主机文件名显示中文乱码且不能下载的解决方法

    Xftp连接主机文件名显示中文乱码且不能下载的本地解决方法 原因:Xftp编码格式问题 解决方法:把Xftp的编码格式增加UTF-8 具体步骤:打开Xftp,文件-属性,在打开的属性界面中打开&quo ...

  6. Tomcat中文乱码问题的原理和解决方法

    1) 更改 D:\Tomcat\conf\server.xml,指定浏览器的编码格式为“简体中文”: 方法是找到 server.xml 中的 <Connector port="8080 ...

  7. 对于使用了SSH造成的中文乱码问题,4大解决方法

    修改struts2.xml struts2.xml 中添加 <constant name="struts.i18n.encoding" value="UTF-8&q ...

  8. jsp和servlet中文乱码

    jsp和servlet之间出现中文乱码的集中原因和解决方法详解:http://blog.csdn.net/longyuhome/article/details/7856270

  9. 中文乱码在java中URLEncoder.encode方法要调用两次解决

    中文乱码在java中URLEncoder.encode方法要调用两次解决 一.场景: 1.我在客户端要通过get方式调用服务器端的url,将中文参数做utf-8编码,需要在js中两次的进行编码,服务器 ...

随机推荐

  1. Redis01——Redis究竟支持哪些数据结构

    Redis已经越来越多地应用到互联网技术中,而关于Redis的相关问题,也成为面试中必不可少的一部分,本文开始将会逐渐把我了解到的关于Redis的一些面试问题整理出来,供各位参考,如有不对之处,烦请指 ...

  2. CentOS安装docker ce的三种方式

    参考文章: CentOS安装docker ce的三种方式: 1.环境 CentOS Linux release 7.6.1810 (Core) 2.卸载旧版本 sudo yum remove dock ...

  3. 扩展el-input 加一个控制精度的命令(directives)

    使用el-input时 出现需要精度控制的需求,因为每一个el-input需要精度不用 所以我给这个虚拟dom绑定了一个精度值,根据这个值去控制精度. 下面附上代码: html: <el-inp ...

  4. php7连接mysql8

    最近因为剁手买了mac所以在mac上搭建lnmp环境. 刚好看到mysql从5.7跳到8,性能据说快上一倍,果断尝鲜! lnmp基本都弄好了,但是到用php连接Mysql这一步出了岔子. 出错原因: ...

  5. 面向对象第四单元(UML)及期末总结

    前言 统一建模语言(英语:Unified Modeling Language,缩写 UML),是软件架构设计建模和规约的语言. 在UML系统开发中有三个主要的模型: 功能模型:从用户的角度展示系统的功 ...

  6. NFS作为根文件系统,挂载超时

    NFS服务器配置正确后,使用ramfs,通过mount能够正常挂载NFS,但是作为ROOTFS无法正常挂载,显示超时. 经查看log,RPC报错-120. 分析结果: 在Ubuntu1804上,nfs ...

  7. Spring bean配置 入门

    Spring 的入门案例:(IOC)  IOC 的底层实现原理(结构图2.01) 图:2.01 IOC:Inversion of Control 控制反转,指的是对象的创建权反转(交给)给Spring ...

  8. eclipse 配置tomcat运行环境

    eclipse环境下如何配置tomcat,并且把项目部署到Tomcat服务器上 1.打开Eclipse,单击“Window”菜单,选择下方的“Preferences”. 2.单击“Server”选项, ...

  9. wpf xaml CS0426 错误原因

    wpf  程序集中 类命名空间名称和类名不能相同,否则在 xaml生成 i.g.cs时,会导致 自动生成代码无法推到处是类型还是命名空间的问题.   触发这个错误的条件是类命名空间 与 类名相同 并 ...

  10. 通达OA rce复现

    通达OA下载:链接:https://pan.baidu.com/s/1c0P-M-IyY5VxfH5d0qKHsQ 提取码:l0pc 漏洞原因:未授权文件上传 + 文件包含(利用nginx日志也可以g ...