Request中文乱码问题以及解决方案

补充三个知识点:

  1. Get是URL解码方式。默认解码格式是Tomcat编码格式。所以URL解码是UTF-8,覆盖掉了request容器解码格式
  2. Post是实体内容解码方式。默认解码格式是request编码格式也是UTF-8。与Tomcat编码格式无关
  3. 解决request乱码问题是在代码中用System.out.println(request.getCharacterEncoding());看看接收过来的request是用什么方式编码的。我的编码方式是UTF-8,所有就没有出现乱码问题
  4. 下面提供通用的解决乱码问题,如果还没有解决可以结合上面三条自己尝试解决。

对于Post请求的中文乱码问题:

// 在 HttpServletRequest 接口中提供了一个 setCharacterEncoding() 方法,该方法用于设置 request 对象的解码方式。
request.setCharacterEncoding("utf-8"); //设置request对象的解码方式,这个要在所有获取对象之前

GET 提交时出现的中文乱码

// 可以先使用错误码表 ISO-8859-1 将用户名重新编码变成字节,然后使用码表 UTF-8 进行解码。再次对 RequestParamsServlet 进行修改
// 因为get请求是在url后面进行传值,传进来的值已经是iso8859-1的编码形式了,所有要按照iso8859-1重新编码成二进制字节,然后按照utf-8的形式在进行解码
name = new String(name.getBytes("iso8859-1"),"utf-8");

Response中文乱码问题以及解决方案

下面通过案例演示乱码问题的产生原因以及解决方式。

@WebServlet("/jsp/test")
public class TestServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException { String data = "麻瓜";
PrintWriter out = response.getWriter();
out.println(data);
}
}

当这样不做任何处理的时候,页面显示出来的中文一般都是乱码

由于计算机中的数据都是以二进制形式存储的,因此,当传输文本数据时,会发生字符和字节之间的转换。字符与字节之间的转换是通过查码表完成的,将字符转换成字节的过程称为编码,将字节转换成字符的过程称为解码,如果编码和解码使用的码表不一致,则会导致乱码问题。

知道了原理就很好解决中文乱码问题了,首先在浏览器控制台document.charset查看自己浏览器的默认解码表是啥,我这里使用Edge浏览器默认是GBK,然后在代码中使用response.getCharacterEncoding(),查看自己响应到浏览器的编码是什么,我这里为UTF-8,当然一般都是使用UTF-8进行开发所以响应回去的就是自己编写代码时使用的编码表,上面出现的乱码问题本质就是用UTF-8编码的中文,然后到浏览器中使用GBK进行解码,最后肯定出现乱码问题。

补充几个知识点:

  1. response.setCharacterEncoding(“UTF-8”)的作用是指定服务器响应给浏览器的编码。但是浏览器会以默认的方式进行解码。

  2. response.setContentType(“text/html;charset=utf-8”)的作用是指定服务器响应给浏览器的编码。同时,浏览器也是根据这个参数来对其接收到的数据进行重新编码(或者称为解码)。

  3. 对于发送数据,服务器按照response.setCharacterEncoding<—contentType<—pageEncoding的优先顺序,对要发送的数据进行编码,也就是说setCharacterEncoding的优先级高于contentType

    JSP要经过两次的“编码”,第一阶段会用pageEncoding,第二阶段会用utf-8至utf-8,第三阶段就是由Tomcat出来的网页, 用的是contentType。
    第一阶段是jsp转译(翻译)成.Java,它会根据pageEncoding的设定读取jsp,结果是由指定的编码方案翻译成统一的UTF-8 JAVA源码(即.java),如果pageEncoding设定错了,或没有设定,出来的就是中文乱码。
    第二阶段是从源码(.java)编译到字节码文件(.class),不论JSP编写时候用的是什么编码方案,经过这个阶段的结果全部是UTF-8的encoding的java源码。
    JAVAC用UTF-8的encoding读取java源码,编译成UTF-8 encoding的二进制码(即.class),这是JVM对常数字串在二进制码(java encoding)内表达的规范。
    第三阶段是Tomcat(或其的application Container)载入和执行阶段二的来的JAVA二进制码,输出的结果,也就是在客户端见到的,这时隐藏在阶段一和阶段二的参数contentType就发挥了功效

解决办法有三种:

第一种方式以浏览器为标准,将代码中的编码方式改为浏览器的编码方式(不推荐,因为不同的用户浏览器编码方法很可能不一样

@WebServlet("/jsp/test")
public class TestServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
// 我这里将响应回到浏览器的编码和浏览器保持一致,就可以解决浏览器乱码问题
response.setCharacterEncoding("gbk"); //设置响应回的中文使用gbk编码,浏览器再使用默认的gbk解码就不会出现问题
String data = "麻瓜";
PrintWriter out = response.getWriter();
out.println(data);
}
}

第二种方式是以代码为标准,通知浏览器中的解码方式改为代码中的编码方式,一般编码方式都是utf-8,这种比第一种好,但是也有人可能使用系统默认的gbk进行编码(不过这种情况下可能就没有乱码问题了( ̄▽ ̄)"),所以也有可能出问题

@WebServlet("/jsp/test")
public class TestServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8"); //通知浏览器使用utf-8解码
// 这两种方式效果一样,都是设置浏览器的内容类型,当然不同的浏览器可以效果有些差距,我这里使用的是edge
// response.setHeader("Content-Type", "text/html;charset=utf-8");
String data = "麻瓜";
PrintWriter out = response.getWriter();
out.println(data);
}
}

中间插入一个测试

@WebServlet("/jsp/test")
public class TestServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
System.out.println(response.getCharacterEncoding()); // UTF-8,这里是编码默认的大写UTF-8
response.setContentType("text/html;charset=gbk"); System.out.println(response.getCharacterEncoding());// gbk
response.setCharacterEncoding("utf-8"); System.out.println(response.getCharacterEncoding());// 我修改后为小写utf-8 String data = "麻瓜";
PrintWriter out = response.getWriter();
out.println(data);
// 最后浏览器控制台document.charset:'UTF-8'
// 如果将setContentType和setCharacterEncoding调换位置,那么最后浏览器控制台document.charset:'GBK'
// 出现这种情况和网上一些说setCharacterEncoding优先级高的有些区别,我这里就以实测为标准,是因为代码顺序决定的优先级,有大佬知道原因的求指导
// 但是如果没有设置setContentType,那么setCharacterEncoding只会修改代码中的编码方式,不会修改浏览器的默认解码方式
}
}

由上面测试可以看出,如果不设置setContentType,那么setCharacterEncoding也不会有效果,那么

理论上统一编码方式为utf-8,这种方式基本可以解决所有问题了

@WebServlet("/jsp/test")
public class TestServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException { response.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8"); String data = "麻瓜";
PrintWriter out = response.getWriter();
out.println(data);
}
}

不过这种方式和第二种方式效果一样,最后还是推荐第二种方式,程序员都是懒人嘛,写的少就是yyds。

request/response解决中文乱码!!!的更多相关文章

  1. java web 中有效解决中文乱码问题-pageEncoding与charset区别, response和request的setCharacterEncoding 区别

    这里先写几个大家容易搞混的编码设置代码: 在jsp代码中的头部往往有这两行代码 pageEncoding是jsp文件本身的编码contentType的charset是指服务器发送给客户端时的内容编码J ...

  2. Response ServletContext 中文乱码 Request 编码 请求行 共享数据 转发重定向

    Day35  Response 1.1.1 ServletContext概念 u 项目的管理者(上下文对象),服务器启动时,会为每一个项目创建一个对应的ServletContext对象. 1.1.2  ...

  3. servlet request、response的中文乱码问题

    一.request 1.get请求 get请求的参数是在请求行中的,浏览器使用utf-8进行编码,数据的编码一般为UTF-8,而url请求行的默认编码为ISO-8859-1,一般来说有以下方式可以解决 ...

  4. GET请求和POST请求的request和response的中文乱码问题

    GET请求(request)中文乱码解决方案: 在Services的server.xml的配置文件的第一个Connector标签中添加属性URIEncoding="UTF-8" P ...

  5. 解决Request中参数中文乱码问题

    1.使用配置过滤器的方式解决 在web.xml中增加过滤器: <!--配置解决中文乱码的过滤器--> <filter> <filter-name>character ...

  6. 04_过滤器Filter_02_Filter解决中文乱码问题

    [过滤器解决中文乱码问题实例] [工程截图] [web.xml] <?xml version="1.0" encoding="UTF-8"?> &l ...

  7. 解决中文乱码( jsp表单提交中文时出现乱码)

    有三种方法: 1.建立一个filter中文解决乱码 2.Struts2在struts.xml中修改默认的编码设定 3.用Spring解决中文乱码 4.直接在jsp中修改解决 1.建立一个filter解 ...

  8. 微信二维码支付-模式一(PC端,解决中文乱码问题)

    近期公司调完银联,调支付宝,调完支付宝调微信.说实话微信的帮助文档确实是烂,而且有没有技术支持,害的我头发都掉了一桌.不说废话了,看代码. 首先登陆微信的公众平台(微信的服务号不是订阅号),然后选择微 ...

  9. 关于web.xml中配置Spring字符编码过滤器以解决中文乱码的问题

    当出现中文乱码问题,Spring中可以利用CharacterEncodingFilter过滤器解决,如下代码所示: <!-- Spring字符编码过滤器:解决中文乱码问题 --> < ...

随机推荐

  1. synchronized Lock(本地同步)锁的8种情况

    Lock(本地同步)锁的8种情况 总结与说明: * 题目: * 1.标准访问,请问是先打印邮件还是短信 Email * 2.email方法新增暂停4秒钟,请问是先打印邮件还是短信 Email * 3. ...

  2. Shell系列(25)- 条件判断之文件权限

    按照文件权限进行判断 读.写.执行等选项权限,只要有,就返回真 不会按照所属者,所属用户组,其他用户进行区分 先判断文件是否存在,再去判断选项权限 测试选项 作用(标红熟记) -r 文件 判断该文件是 ...

  3. SQL-关联查询【转】

    T_A A表 T_B B标,id为表与表相关联的字段`创建相关表结构 CREATE TABLE Table_B( id INT(2), serNum VARCHAR(10) ); CREATE TAB ...

  4. Hive——安装以及概述

    一.hive的安装 注意:安装hive的前提要安装好MySQL和Hadoop Hadoop安装:https://www.cnblogs.com/lmandcc/p/15306163.html MySQ ...

  5. Node.js躬行记(11)——E2E测试

    Cypress是为现代网络构建的前端测试工具,解决了开发人员和 QA 工程师在测试应用程序时面临的关键痛点. 在这个测试框架中包含了E2E测试.集成测试和单元测试(内嵌了Mocha),我们需要的是它的 ...

  6. 鸿蒙内核源码分析(任务切换篇) | 看汇编如何切换任务 | 百篇博客分析OpenHarmony源码 | v41.03

    百篇博客系列篇.本篇为: v41.xx 鸿蒙内核源码分析(任务切换篇) | 看汇编如何切换任务 | 51.c.h .o 任务管理相关篇为: v03.xx 鸿蒙内核源码分析(时钟任务篇) | 触发调度谁 ...

  7. P7717-「EZEC-10」序列【Trie】

    正题 题目链接:https://www.luogu.com.cn/problem/P7717 题目大意 求有多少个长度为\(n\)的序列\(a\)满足,都在\([0,k]\)的范围内且满足\(m\)个 ...

  8. Markdown 编写技巧汇总(一)

    编写文档,有很多格式选择,也有不同平台选择.下面就自己接触到的MarkDown编写文档的各种技巧做简单梳理,供自己参阅,也希望帮到网友. [1]添加空格 ①   这种写法比较老土,但是,很实用!注意都 ...

  9. 通俗易懂,Layui前端框架!

    前言   layui 是一款采用自身模块规范编写的前端 UI 框架,遵循原生 HTML/CSS/JS 的书写与组织形式,门槛极低,拿来即用.其外在极简,却又不失饱满的内在,体积轻盈,组件丰盈,从核心代 ...

  10. RAC使用auto rolling的方式打补丁

    11.2.0.4 RAC 某系统主库使用auto rolling的方式打补丁在一节点执行1-5,结束后然后在二节点执行1-5,结束后最后再在某个节点执行6. 1.backup GI_HOME& ...