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. 低差异序列 (low-discrepancy sequences)之Halton序列均匀产生多维随机数的介绍与实现

    Halton序列 在统计学中,Halton序列是用于生成空间中的点的序列,如Monte Carlo模拟的数值方法,虽然这些序列是确定性的,但它们的差异性很低,也就是说,在许多方面看起来是随机的.它们在 ...

  2. javascript 标签轮播

    html <div id="banner-switch"> <!-- 切换内容 --> <div class="notice-content ...

  3. lumen-phpunit 单元测试

    lumen-框架5.8为例 1,把vendor下的bin目录放到环境变量里面: 2,设置路由 $router->get('syn', ['uses' => 'syn\syn@diction ...

  4. git 报错 gitThere is no tracking information for the current branch. Please specify which branch you w

    新建本地分支后将本地分支推送到远程库, 使用git pull 或者 git push 的时候报错gitThere is no tracking information for the current ...

  5. 关于Redis的十个高频面试问题

    文件来自大神的分析,小弟引用.希望更多的资源能被更多的人分享到!!! 一.Redis有哪些数据结构? 字符串String.字典Hash.列表List.集合Set.有序集合SortedSet. 如果你是 ...

  6. mysql从零开始之MySQL PHP 语法

    MySQL PHP 语法 MySQL 可应用于多种语言,包括 PERL, C, C++, JAVA 和 PHP,在这些语言中,MySQL 在 PHP 的 web 开发中是应用最广泛. 在本教程中我们大 ...

  7. 极简SpringBoot指南-Chapter01-如何用Spring框架声明Bean

    仓库地址 w4ngzhen/springboot-simple-guide: This is a project that guides SpringBoot users to get started ...

  8. java 从零开始手写 RPC (07)-timeout 超时处理

    <过时不候> 最漫长的莫过于等待 我们不可能永远等一个人 就像请求 永远等待响应 超时处理 java 从零开始手写 RPC (01) 基于 socket 实现 java 从零开始手写 RP ...

  9. Java入门基础,必读!Java单行、多行和文档注释!

    在编写Java的过程中,我们需要对一些程序进行注释.除了方便自己阅读之外,我们还需要为他人更好地理解我们的程序.因此,我们需要对一些程序进行注释,这些注释可以是编程思想,也可以是程序的作用,可以说是J ...

  10. SPOJ16636 Journey IE2

    SPOJ16636 Journey IE2 更好的阅读体验 在Byteland有n个城市,编号从1到n.这些城市由m条双向道路网络连接.众所周知,每一对城市最多只能由一条道路连接. Byteman最近 ...