目录

1、乱码原因和解决思路

2、准备知识(新手必读,老司机跳过)

2.1 字符集

2.2 URL编码

2.3 javaweb servlet

3 浏览器编码/解码使用字符集的逻辑优先顺序

3.1 浏览器解码使用的字符集优先级

3.2 浏览器编码使用的字符集

3.2.1 URL直接访问

3.2.2 html form 表单发送http get/post请求

4、http get请求参数乱码:浏览器发送给后端servlet

4.1 设置发送端(浏览器)url编码的字符集

4.1.1 get 第一类场景:URL直接访问

4.1.2 get 第二类场景: html form表单发送http get请求

4.2 设置接收端(servlet)url解码的字符集

4.2.1 方案1【不推荐】:通过new String()方式转码

4.2.2 方案2【推荐】:使用过滤器方法给所有servlet参数转码

4.2.3 方案3【强烈推荐】:设置tomcat解码的字符集为UTF-8

4.2.4 方案4【推荐】:用post

5 http post请求参数乱码:浏览器发送给后端servlet

5.1 设置发送端(浏览器)编码的字符集

5.2 设置接收端(servlet)解码的字符集

5.2.1 方案1【不推荐】:通过new String()方式转码

5.2.2 方案2【不推荐】:通过req.setCharacterEncoding("UTF-8")方式转码

5.2.3 方案3【推荐】:使用过滤器方法给所有servlet参数转码

6、http响应数据乱码:servlet发送给浏览器等客户端

6.1 设置发送端(servlet)对数据编码的字符集

6.2 告诉接收端(浏览器等)数据解码的字符集

7、http响应html页面乱码:tomcat发给浏览器

7.1 设置发送端(servlet)对html页面编码的字符集

7.2 设置接收端(浏览器)对html页面解码的字符集

8、http响应jsp页面乱码:tomcat发给浏览器

8.1 设置发送端(servlet)对jsp页面编码的字符集

8.1.1 方式一【不推荐】:以idea为例,右下角可以修改jsp等文件编码

8.1.2 方式二【推荐】:在文件头设置 pageEncoding,idea的jsp文件编码以此为准(右下角编码变灰色,不可改)

8.1.3 方式三【推荐】:在文件头设置 contentType="text/html;charset=UTF-8",该设置会覆盖“方式二”的设置(看下面的源码)

8.2 设置接收端端(浏览器等)对jsp页面解码的字符集

8.2.1 方式一【不推荐】:在响应体head中添加meta charset="UTF-8"

8.2.2 方式二【推荐】:在文件头设置 pageEncoding

8.2.3 方式三【推荐】:在文件头设置 contentType="text/html;charset=UTF-8",该设置会覆盖“方式二”的设置(看下面的源码)

9、tomcat日志在idea种乱码

9.1 设置输出日志的编码字符集

9.2 设置idea控制台解码的字符集

【JavaWeb开发】Servlet彻底解决开发中请求(get/post)、应答以及控制台中文乱码问题


1、乱码原因和解决思路

导致乱码原因都是因为字符编码和解码用的字符集不一致导致,解决乱码问题需统一编码和解码的字符集,建议都用UTF-8

2、准备知识(新手必读,老司机跳过)

2.1 字符集

HTML 编码(字符集)https://www.w3school.com.cn/html/html_charset.asp

HTML 字符集 | 菜鸟教程https://www.runoob.com/tags/ref-charactersets.html

2.2 URL编码

HTML URL 编码参考手册 | 菜鸟教程HTML URL 编码 参考手册 URL 编码会将字符转换为可通过因特网传输的格式。 URL - 统一资源定位器 Web 浏览器通过 URL 从 web 服务器请求页面。 URL 是网页的地址,比如: https://www.runoob.com。 URL 编码 URL 只能使用 ASCII 字符集来通过因特网进行发送。 由于 URL 常常会包含 ASCII 集合之外的字符,URL 必须转换为有效的 ASCII 格式。 ..https://www.runoob.com/tags/html-urlencode.html

2.3 javaweb servlet

Servlet 教程 | 菜鸟教程Servlet 教程 Servlet 为创建基于 web 的应用程序提供了基于组件、独立于平台的方法,可以不受 CGI 程序的性能限制。Servlet 有权限访问所有的 Java API,包括访问企业级数据库的 JDBC API。 本教程将讲解如何使用 Java Servlet 来开发基于 web 的应用程序。 现在开始学习 Servlet! 谁适合阅读本教程? 本教程是专为 Java 程序员设计的。在阅读本教程之前,需要先了解..https://www.runoob.com/servlet/servlet-tutorial.html

3 浏览器编码/解码使用字符集的逻辑优先顺序

3.1 浏览器解码使用的字符集优先级

浏览器输入url网址,服务器tomcat会对应的响应(html、jsp、json等),浏览器是用什么字符集解码的呢?结论如下:

1.http响应头中的字符集    >   2. html/jsp页面中的字符集    >    3.使用默认字符集(不同浏览器不同)

1、首先,浏览器先从响应头读取  Content-Type 的 charset 的字符集

2、其次,从响应体中(包括html文件) 的<html><head><meta charset="UTF-8">中读取字符集

3、如果上面两个都没有,则使用默认的字符集(不同浏览器不同)

4、补充,IE和360浏览器可以右键修改页面使用的字符集,修改后解码 和 编码(get url编码、post请求体编码等)都以修改后的为准,但是只对本窗口有效。

3.2 浏览器编码使用的字符集

3.2.1 URL直接访问

直接访问指的是:在地址栏输入带参数url访问,浏览器会使用默认字符集UTF-8对URL的非ASCⅡ字符进行编码。详细说明:

  • 浏览器输入URL直接访问一般是首次打开一个网站(对浏览器 [ 非postman ] 而言,是必然是http get 请求,不会是post,因为浏览器发post请求需要 html 的 form 表单发送),由于还未收到服务器任何响应,无从获取服务器的字符集,所以会使用默认字符集UTF-8对URL的非ASCⅡ字符进行编码(亲测当前主流新版浏览器都是用UTF-8字符集)。
  • IE可以修改默认设置,不用UTF-8,没啥意义

IE默认url编码(get请求)

3.2.2 html form 表单发送http get/post请求

html <form>表单发送时,对数据编码使用的字符集与当前页面的解码的字符集一致。详细说明:

在url直接访问后,服务器一般会响应一个html 或 jsp页面,这时在响应的响应头context-type中 或 响应体(包括html文件) 的<html><head><meta charset="UTF-8">中得到解码的字符集,然后再通过html页面<form>表单发送get/post请求时,将使用与该页面解码字符集一样的字符集进行编码。

补充:IE和360浏览器可以右键修改页面使用的字符集,修改后解码 和 编码(get url编码、post请求体编码等)都以修改后字符集的为准,但是只对本窗口有效。

4、http get请求参数乱码:浏览器发送给后端servlet

get提交不经过请求体而是通过URL传参

 servlet 测试 代码:

@WebServlet(name = "A01Servlet", value = "/A01Servlet")
public class A01Servlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) {String name = req.getParameter("name");System.out.println("name=" + name);}
}

4.1 设置发送端(浏览器)url编码的字符集

4.1.1 get 第一类场景:URL直接访问

此类场景,浏览器会使用默认字符集UTF-8对URL的非ASCⅡ字符进行编码。详细说明见章节 3.2.1

测试url:

url编码前            http://localhost:8080/lishuoboy_javaweb_war_exploded/A01Servlet?name=硕

url编码后UTF-8  http://localhost:8080/lishuoboy_javaweb_war_exploded/A01Servlet?name=%E7%A1%95

url编码后 GBK    http://localhost:8080/lishuoboy_javaweb_war_exploded/A01Servlet?name=%CB%B6

如果 URL编码后“硕”变成了“%E7%A1%95”,有三个%,说明是用UTF8字符集编码的,因为UTF8字符集一个汉字占用3个字节。否则GBK一个汉字占用2个字节,有2个%

4.1.2 get 第二类场景: html form表单发送http get请求

html <form>表单发送时,对数据编码使用的字符集与当前页面的解码的字符集一致。详细说明见章节 3.2.2

测试的html页面表单:

<html>
<head><title>Title</title><!-- 1、设置页面解码 和 编码(包括请求体,post请求参数通过请求体传送) 的字符集2、不同浏览器默认解码的字符集不固定(以系统编码为准居多),可以右键设置当前页面解码和编码的编码字符集3、该设置不一定生效,最上面的第一行会在响应头设置context-type,浏览器优先使用响应头的编码。--><!-- H5 --><meta charset="UTF-8"><!-- H5之前 --><!-- <meta http-equiv="Content-Type" content="text/html;charset=utf-8"> -->
</head>
<body>
<form action="/lishuoboy_javaweb_war_exploded/A01Servlet" method="get"><input type="text" name="name" placeholder="输入名字"><input type="submit" value="提交">
</form>
</body>
</html>

4.2 设置接收端(servlet)url解码的字符集

4.2.1 方案1【不推荐】:通过new String()方式转码

假如tomcat URI(不知是什么,可以先看方案3)解码的字符集是“ISO-8859-1“,即配置为URIEncoding="UTF-8",用getBytes(“ISO-8859-1“)拿到原编码的byte数组,再通过new一个String转成UTF-8编码

优缺点:每个servlet、每个参数都需要转码(可以给所有参数写个for循环转码)

4.2.2 方案2【推荐】:使用过滤器方法给所有servlet参数转码

原理跟方案2一样,只不过不用每一个参数都写一次转码

具体写法:过滤器(解决中文乱码get/post)_mtm001的专栏-CSDN博客_乱码过滤器

优缺点:每个参数都需要转码(可以给多个参数写个for循环),但不用每个servlet都转

4.2.3 方案3【强烈推荐】:设置tomcat解码的字符集为UTF-8

tomcat8.0之后默认的解码的字符集就是UTF-8,无需设置

tomcat8.0之前默认的解码的字符集是ISO-8859-1,需要设置,设置方法:修改tomcat目录下/conf/server.xml文件,设置 URIEncoding="UTF-8"。

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

4.2.4 方案4【推荐】:用post

提供一个思路,get提交几乎每一点都比不上post提交,那么就使用post提交方式就好了。

5 http post请求参数乱码:浏览器发送给后端servlet

post提交经过请求体而不是通过URL传参

测试html页面表单:

<html>
<head><title>Title</title><!-- 1、设置页面解码 和 编码(包括请求体,post请求参数通过请求体传送) 的字符集2、不同浏览器默认解码的字符集不固定(以系统编码为准居多),可以右键设置当前页面解码和编码的编码字符集3、该设置不一定生效,最上面的第一行会在响应头设置context-type,浏览器优先使用响应头的编码。--><!-- H5 --><meta charset="UTF-8"><!-- H5之前 --><!-- <meta http-equiv="Content-Type" content="text/html;charset=utf-8"> -->
</head>
<body>
<form action="/lishuoboy_javaweb_war_exploded/A01Servlet" method="post"><input type="text" name="name" placeholder="输入名字"><input type="submit" value="提交">
</form>
</body>
</html>

servlet 测试代码:

@WebServlet(name = "A01Servlet", value = "/A01Servlet")
public class A01Servlet extends HttpServlet {@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws UnsupportedEncodingException {String name = req.getParameter("name");System.out.println("name=" + name);}
}

5.1 设置发送端(浏览器)编码的字符集

浏览器不能直接发送http post请求,必须通过html <form>表单发送,对数据编码使用的字符集与当前页面的解码的字符集一致。详细说明见章节 3.2.2

5.2 设置接收端(servlet)解码的字符集

5.2.1 方案1【不推荐】:通过new String()方式转码

假如浏览器发送的编码的字符集是“ISO-8859-1“,用getBytes(“ISO-8859-1“)拿到原编码的byte数组,再通过new一个String转成UTF-8编码

优缺点:每个servlet、每个参数都需要转码(可以给所有参数写个for循环转码)

5.2.2 方案2【不推荐】:通过req.setCharacterEncoding("UTF-8")方式转码

注意点:req设置编码前不能get过参数,否则就不好使了

优缺点:每个servlet都需要转码

5.2.3 方案3【推荐】:使用过滤器方法给所有servlet参数转码

原理跟方案2一样,只不过不用每一个servlet都做一次转码

注意点:req设置编码前不能get过参数,否则就不好使了

优缺点:不用每个servlet都转码

6、http响应数据乱码:servlet发送给浏览器等客户端

 测试url:http://localhost:8080/lishuoboy_javaweb_war_exploded/A01Servlet

servlet 测试 代码:

@WebServlet(name = "A01Servlet", value = "/A01Servlet")
public class A01Servlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {resp.getWriter().println("name=硕");}
}

6.1 设置发送端(servlet)对数据编码的字符集

// 以下3个都可以,只是设置响应体编码用方式一即可,方式二和方式三,既设置了响应字符编码的字符集还在响应头设置了content-type(就是告诉浏览器解码字符集)。前面的 text/json;可根据具体情况选择,一般json居多
// 可以在当前servlet中设置,或者直接在过滤器设置
// 如果都设置了,那么后面的覆盖前面的,其中resp.setCharacterEncoding("UTF-8");只能覆盖content-type的charset的值。// 方式一:【不推荐】
resp.setCharacterEncoding("UTF-8");
// 方式二【推荐】
resp.setContentType("text/json;charset=utf-8");
// 方式三【推荐】
resp.setHeader("content-type", "text/json;charset=UTF-8"); 

6.2 告诉接收端(浏览器等)数据解码的字符集

以下2个都可以,如果都设置了,那么后面的覆盖前面的。下面两个设置会在响应头设置了content-type,就是告诉浏览器解码字符集。前面的 text/json;可根据具体情况选择,一般json居多resp.setContentType("text/json;charset=utf-8");         resp.setHeader("content-type", "text/json;charset=UTF-8"); 

设置后,setContentType之后,http响应头会有对应参数content-type,浏览器就知道响应数据的字符集了

7、http响应html页面乱码:tomcat发给浏览器

测试代码

<!DOCTYPE html>
<html lang="en">
<head><!-- 1、浏览器解码时优先读取响应头的Content-Type中的字符集,没有则读取<head>标签<meta charset="UTF-8">中的字符集。不同浏览器默认(自动)解码的字符集不固定(以系统编码为准居多),可以右键设置当前页面解码和编码的编码字符集2、浏览器编码(包括请求体,post请求参数通过请求体传送)与上一步解码的字符集一致  --><!-- H5 --><meta charset="UTF-8"><!-- H5之前 --><!-- <meta http-equiv="Content-Type" content="text/html;charset=utf-8"> --><title>Title</title>
</head>
<body>
<form action="/lishuoboy_javaweb_war_exploded/A01Servlet" method="post"><input type="text" name="name"><input type="submit" value="提交">
</form>
</body>
</html>

7.1 设置发送端(servlet)对html页面编码的字符集

以idea为例,右下角可以修改html等文件编码

7.2 设置接收端(浏览器)对html页面解码的字符集

请阅读章节: 3.1 浏览器解码使用的字符集优先级

8、http响应jsp页面乱码:tomcat发给浏览器

8.1 设置发送端(servlet)对jsp页面编码的字符集

8.1.1 方式一【不推荐】:以idea为例,右下角可以修改jsp等文件编码

8.1.2 方式二【推荐】:在文件头设置 pageEncoding,idea的jsp文件编码以此为准(右下角编码变灰色,不可改)

看一下jsp翻译的java原文件,该设置不仅设置了文件编码,还设置响应头的contentType

8.1.3 方式三【推荐】:在文件头设置 contentType="text/html;charset=UTF-8",该设置会覆盖“方式二”的设置(看下面的源码)

看一下jsp翻译的java原文件,该设置不仅设置了文件编码,还设置响应头的contentType,告诉浏览器编码字符集

8.2 设置接收端端(浏览器等)对jsp页面解码的字符集

方式一优先级最低,因为方式二和方式三会在响应头设置content-type,方式一则不会

8.2.1 方式一【不推荐】:在响应体head中添加meta charset="UTF-8"

8.2.2 方式二【推荐】:在文件头设置 pageEncoding

见章节8.1.2

8.2.3 方式三【推荐】:在文件头设置 contentType="text/html;charset=UTF-8",该设置会覆盖“方式二”的设置(看下面的源码)

见章节8.1.3

9、tomcat日志在idea种乱码

9.1 设置输出日志的编码字符集

tomcat7、8、9最新小版本 和 tomcat10 默认是UTF-8,之前需要在启动命令设置(具体百度)。

修改tomcat目录下conf/logging.properties文件,ConsoleHandler.encoding = GBK。

9.2 设置idea控制台解码的字符集

参考:

【JavaWeb开发】Servlet彻底解决开发中请求(get/post)、应答以及控制台中文乱码问题

【JavaWeb】Http get请求乱码、post请求乱码,html页面乱码、jsp页面乱码,控制台tomcat日志乱码原因分析和解决方案相关推荐

  1. 解决IntelliJ IDEA控制台乱码问题[包含程序运行时的log4j日志以及tomcat日志乱码]

    解决IntelliJ IDEA控制台乱码问题[包含程序运行时的log4j日志以及tomcat日志乱码] 参考文章: (1)解决IntelliJ IDEA控制台乱码问题[包含程序运行时的log4j日志以 ...

  2. 关于html页面转为 jsp页面中文乱码问题

    在Java项目中有时我们需要把html页面转成jsp 转换步骤 两步 1. 修改html页面头部声明 修改方法 在头部加上这段代码 <%@ page language="java&qu ...

  3. Tomcat日志乱码解决

    Tomcat日志乱码全解决方案 1.出现乱码 2.解决方案 方案一. 直接修改Tomcat日志输出字符集 方案二. 修改IDEA启动VM参数字符集 1.出现乱码 最近一直在用Springboot,很少 ...

  4. 淇℃伅 Tomcat日志乱码的办法

    淇℃伅 Tomcat日志乱码的办法 本人使用的工具: Tomcat是9.0.37 Idea2020.2 使用过程中有两个地方乱码如下图: 然后第1个地方乱码解决的办法是通过修改你安装的Tomcat目录 ...

  5. linux tomcat 日志乱码,Linux下TOMCAT中日志出现中文乱码

    红帽子AS4,其中TOMCAT为6.0. 结果TOMCAT中日志出现中文乱码 解决方法修改i18n: 最后的配置为: [root@linux etc]# more /etc/sysconfig/i18 ...

  6. 【SpringBoot的坑】Restful请求报错Request method 'POST' not supported,HiddenHttpMethodFilter无法将POST转换为PUT原因分析

    直接上结论: 因为 SpringBoot 版本原因,在我目前使用的 2.2.4 版本中,需要在springapplication.xml文件中 添加配置: spring.mvc.hiddenmetho ...

  7. Java中文jsp页面_java中文乱码解决之道(七)—–JSP页面编码过程

    我们知道JSP页面是需要转换为servlet的,在转换过程中肯定是要进行编码的.在JSP转换为servlet过程中下面一段代码起到至关重要的作用. 在上面代码中有两个地方存在编码:pageEncodi ...

  8. java 页面编码_java中文乱码解决之道(七)-----JSP页面编码过程

    我们知道JSP页面是需要转换为servlet的,在转换过程中肯定是要进行编码的.在JSP转换为servlet过程中下面一段代码起到至关重要的作用. 在上面代码中有两个地方存在编码:pageEncodi ...

  9. IDEA中Tomcat日志乱码问题解决

    以前一直使用Eclipse,现在试用IDEA,遇到一些坑,通过网上的答案基本都解决了,但有些答案不好,比如这个问题. 1.原因分析 Tomcat运行Java Web的程序,在IDEA控制台中输出显示, ...

  10. idea console中文乱码_idea控制台tomcat中文乱码的处理方法

    第一步: 在idea的目录中找: 第二步: 在idea64.exe.vmoptions中添加一句话: 保存关闭 第三步: 关闭idea再重新启动 第四步: 在往tomcat中部署项目时在VM opti ...

最新文章

  1. 可删除任意位置数据的堆
  2. android logcat里面AndroidRuntime FATAL EXCEPTION: main这个是什么问题啊。
  3. Python-dataframe合并(merge函数)
  4. java远程插件动态注册机制_Spring运行时动态注册bean的方法
  5. android系统加载主题的流程,详解Android布局加载流程源码
  6. mysql linux 用户_Linux mysql添加用户,删除用户,以及用户权限
  7. mysql事件执行记录表_MySQL事件异常记录
  8. python编程是啥-Python编程
  9. SQLServer的本月统计和本周统计
  10. HDFS的架构和设计要点
  11. loadruner知识点小结
  12. Java实现批量发送邮件
  13. 使用hydra破解密码
  14. Ultra96安装指导和无线配置
  15. Java综合项目----开发团队分配管理软件
  16. guzzlehttp resulted in a `409 Conflict` response 访问网址 laravel thinkphp
  17. MATLAB代码实现三次样条插值
  18. HDU 4685. Prince and Princess
  19. Chalk-控制台输出着色Nodejs库
  20. Three.js - 着色器材质(二十七)

热门文章

  1. springboot项目去除druid监控的广告超链接等
  2. UE4是什么?虚幻4引擎是什么?
  3. 企业级AD域管理部署实战 微软升级版MCSE MCSA必修课程 Windows Server 2016AD管理实战
  4. 无线通讯基站服务器,无线通信的软基站技术详解
  5. 故障诊断仪采集发动机EMS故障的报文与故障码记录
  6. 电影购票c语言程序,C语言电影购票系统小样
  7. 拼音工具类(多音字处理)
  8. 我本人常去的一些技术性网站!!(不定期更新)
  9. 想要导航提示页最新安卓区_2020年网站页头设计:最佳实践及案例
  10. 如何在网上买到下铺票2020_网上订票怎么选下铺