9、乱码问题解决

乱码问题解决

  • 前提知识
  • Request乱码问题
  • Response乱码问题

一、前提知识

1.1、相关概念

  • 字符集:可以将字符集当作一本容纳了世界上大多数字符的字典,每一个字符在字典中都有一个唯一id,计算机则通过这个唯一id区别字符。字符集有很多种,同一个字符在不同的字符集中唯一id可能不一样。
  • 编码:将字符用字符集中的id来表示,就是编码。A——>>64——>>00100000
  • 解码:将id对照字符集用字符的形式来表示就是解码。00100000——>>64——>>A

1.2、乱码的根本原因

​ 所有的乱码问题,其根本原因只有一个:解码和编码使用的字符集不同。

1.3、四种常见编码

  1. ISO-8859-1:单字节编码,兼容ASCII码,相当于ASCII码的扩展,无法表示中文字符,系统默认编码。
  2. GBK:双字节编码,国标码,可以表示繁体字和简体字,兼容GB2312编码(而GB2312编码只能表示简体字)
  3. UNICODE:定长双字节编码,可以表示所有语言的字符,但是不兼容任何编码。
  4. UTF:不定长编码,可以表示所有语言的字符,常用的UTF-8兼容ISO-8859-1编码,UTF编码会比UNICODE编码节省空间

二、Request乱码问题

2.1、get请求乱码

​ 一般来说在Tomcat8.0以后的版本,只要没有手动修改过server.xml配置文件都不会出现乱码。超链接也是GET请求方式。

  1. get请求的所有参数都在请求行中,即请求URL后面。

  2. 对于GET请求方式,所有的浏览器都是使用UTF-8字符集对请求参数进行编码。

  3. Tomcat8.0之前,会默认使用ISO-8859-1字符集对请求参数解码,这也是GET请求参数乱码的根本原因。

    • 解决方案一:在conf/server.xml配置文件中修改Tomcat对于请求参数的默认解码方式为:UTF-8
    <Connector connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443" URIEncoding="UTF-8"/>
    //URIEncoding:修改对于GET请求方式的默认解码方式
    
    • 解决方案二:逆向编码。先用ISO-8859-1将参数解码,在用UTF-8编码
    String name = request.getParameter("name");//得到乱码    
    name = new String(name.getBytes("iso-8859-1"),"utf-8");//得到正常的name值(post和get都适用)
    
  4. Tomcat8.0以后,会默认使用UTF-8字符集对请求参数解码。只要没有乱改Tomcat配置文件就不会乱码。

不要用UTF-8去解码GBK,这样搞会破坏数据结构,就算你逆向操作,之前的数据也回不来了。

2.2、post请求乱码

  试了很多次,结果发现火狐、谷歌、IE、Edeg等浏览器对请求体中的参数都是使用的UTF-8编码的,根文档中的<meta>标签一毛钱关系都没有,根浏览器显示编码有点关系。但是IE的显示编码是GBK,但是请求体中的参数仍然使用的是UTF-8编码,就很让人费解。反正最后的结论——>>所有浏览器对于请求体中的参数都是使用的UTF-8编码的。

  1. post请求的所有参数都在请求体中,以键值对的形式存在着。

  2. 对于POST请求方式,所有的浏览器都会根据当前文档的显示编码(控制台输入document.charset可以查看)对请求参数进行编码,几乎所有的浏览器都是采用的UTF的显示编码。

  3. 而Tomcat对于POST请求方式,默认都是使用ISO-8859-1去解码的。这也就是POST请求容易乱码的原因。

    • 解决方案一:在conf/server.xml配置文件中修改Tomcat对于GET请求的默认解码方式为:UTF-8
    <Connector connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443" URIEncoding="UTF-8" useBodyEncodingForURI="true"/>//作者失败了......
    //URIEncoding:修改对于请求参数的默认解码方式
    //请求体和uri使用相同的编码格式
    
    • 解决方案二:逆向编码。先用ISO-8859-1将参数解码,在用UTF-8编码。
    String value = request.getParameter("name");//得到乱码
    value = new String(value.getBytes("iso-8859-1"),"utf-8");//得到正常的name值(post和get都适用)
    
    • 解决方案三:手动设置Tomcat对请求参数使用的解码方式。(最常用的一种)
    request.setCharacterEncoding("UTF-8");
    

三、Response乱码问题

3.1、乱码原因

  1. Tomcat发送给浏览器的数据,默认是使用ISO-8859-1编码的。
  2. 浏览器在收到服务器的响应消息后,第一时间会去响应头Header里面找Content-Type属性,通过这个属性的值获取解码方式
  3. 如果没找到Content-Type属性,那么就会默认使用GBK解码,当我们没有进行任何处理的时候,自然也就产生响应乱码了

3.2、解决乱码

  1. 方法一:手动设置Tomcat的编码方式为GBK

    response.setCharacterEncoding("GBK");//不保证所有浏览器的默认解码方式都是GBK
    
  2. 方法二:手动设置Tomcat的编码方式为UTF-8,同时告知浏览器服务器使用的编码方式为UTF-8

    response.setCharacterEncoding("UTF-8");
    response.setHeader("content-type","text/html;charset=utf-8");//告诉浏览器我使用的编码方式
    //----------------------------简化代码--------------------------------
    response.setContentType("text/html;charset=utf-8");
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值