使用 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. 会话存储sessionStorage

    会话存储的工作方式和本地存储的工作方式很接近,不同之处在于数据是各个浏览器上下文私有的,会在文档被关闭时移除(注意是被关闭时才移除,刷新是不会移除的).我们通过全局sessionStorage访问会话 ...

  2. C/C++书籍分享(百度网盘版)

    作为第一篇博客,该写一些什么好呢,毕竟作为技术博客开创的,不能随便闲谈不是. 那就分享一些书籍作为见面礼吧.链接里面包含有大量的C++学习用书籍,包含了从入门到进阶的大部分高质量书籍,注意仅用作个人学 ...

  3. 基于Python3 + appium的Ui自动化测试框架

    UiAutoTest 一.概要 数据驱动的Ui自动化框架 二.环境要求 框架基于Python3 + unittest + appium 运行电脑需配置adb.aapt的环境变量,build_tools ...

  4. Java并发编程之CAS第一篇-什么是CAS

    Java并发编程之CAS第一篇-什么是CAS 通过前面几篇的学习,我们对并发编程两个高频知识点了解了其中的一个—volatitl.从这一篇文章开始,我们将要学习另一个知识点—CAS.本篇是<凯哥 ...

  5. 050.集群管理-Prometheus+Grafana监控方案

    一 Prometheus概述 1.1 Prometheus简介 Prometheus是由SoundCloud公司开发的开源监控系统,是继Kubernetes之后CNCF第2个毕业的项目,在容器和微服务 ...

  6. win7 win10 更换电脑盘符的图标

    效果如下 第一步 -> 1.把文件全放到盘符住目录 2.如果需要更换图标 (文件最好是ICO后缀的) 打开 Autorun 文件并编辑 第二步 -> 重启电脑就完了 下载连接  已经放到码 ...

  7. [ctfhub]SQL注入

    今天在ctfhub整理了几个sql注入的解题过程,还算是比较详细的. 知识点都是比较常见的:每个题大致涉及的知识点用一张表格解释 !注:下方的 information_schema.xxxxxxxxx ...

  8. python爬虫之beautifulsoup的使用

    一.Beautiful Soup的简介 简单来说,Beautiful Soup是python的一个库,最主要的功能是从网页抓取数据.官方解释:Beautiful Soup提供一些简单的.python式 ...

  9. udp和tcp特点 实现文件上传

    本周课程安排: 网络编程结束 并发网络开头 进程 线程 IO模型 上周内容回顾: 1.osi七层:应用层,表示层,会话层,传输层,网络层,数据链路层,物理连接层 也有人把他们归纳为五层: 应用层, 传 ...

  10. 【Code Force】Round #589 (Div. 2) D、Complete Tripartite

    题目链接 大致题意 把一个图分成三块,要求任意两块之间是完全图,块内部没有连线 分析 首先根据块内没有连线可以直接分成两块 假定点1是属于块1的,那么所有与点1连接的点,都不属于块1:反之则是块1的 ...