1.前言

  相信很多初学者在学习javaWeb基础知识时,总会遇到各种各样的乱码问题,我也是从那个时候过来的。当时遇到各种乱码问题,那叫惨不忍睹,只能通过面向百度的方式,解决各种乱码问题,乱码虽然问题能解决,但是总是知其然不知其所以然。如果你也存在一些疑惑,并且仔细阅读这篇文章,我相信我会帮助到你。

2.参数传递乱码问题

解决的办法

  先看参数传递方式

    1.form表单(get提交)、url传参、超链接在这里我统归于get参数传递方式

    2.form表单(post提交)、request请求转发在这里我统归于post参数传递方式

  再看Tomcat版本号

    1.Tomcat 8及以上版本

    2.Tomcat 8以下版本

举例:

  example1:get参数传递方式 + Tomcat 8 以下版本 

  这种情况下,不会出现乱码问题,因为Tomcat 8 版本自动做了参数处理,讲清楚这个东西,需要先了解一个Tomcat的连接器组件(Connector):

  Connector是Tomcat中的一个重要的组件,它负责监听Tomcat收到的请求信息,并将这些请求信息传递给Servlet规范中所定义的Request,然后将转换后的请求交给Engine组件去处理,最后将Engine返回的Response返回给客户端。

  Connector对象的构造方法在Tomcat 7.x的版本是这样的:

 1 protected String URIEncoding = null;
 2 public Connector(String protocol) {
 3         setProtocol(protocol);
 4         try {
 5             Class<?> clazz = Class.forName(protocolHandlerClassName);
 6             this.protocolHandler = (ProtocolHandler) clazz.newInstance();
 7         } catch (Exception e) {
 8             log.error(sm.getString(
 9                     "coyoteConnector.protocolHandlerInstantiationFailed"), e);
10         }
11 }

  在代码中我们并没有看到它去设置URIEncoding,那么在封装GET请求时,如果该字段的值为null,则会在解析的GET请求时,赋予默认值:ISO-8859-1,而ISO-8859-1是不包含中文的,所以自然会出现中文乱码,这个时候,我们可能会尝试使用这种下面方式处理乱码问题:

request.setCharacterEncoding("utf-8");

  但是,在 get参数传递方式 + Tomcat 8 以下版本 这种环境下,上面的方式处理不了乱码问题,遇到这种情况,通常解决方式有两种:

  1.如果方便找到Tomcat 的配置文件,修改Tomcat的配置文件(conf/server.xml)

    Tomcat 的server.xml配置文件有这样一段: 

<Connector port="8080" protocol="HTTP/1.1" 
               connectionTimeout="20000" redirectPort="8443" />

    在Connector这个标签内,是没有URIEncoding这个属性的,那么加上这个属性更改为:

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

    重启Tomcat服务器,就能解决了。

  2.获得参数前进行编码方式转换

    当使用一些内置的Tomcat服务器(例如MyEclipse中内置了Tomcat服务器),修改配置文件显然不是一个好方式,反正我是没找到MyEclipse的Tomcat配置文件。。。又或者不想使用上面的方式,那么这个时候可以使用下面这种方式:

    例如:想要获得表单传递过来的一个username参数,可以进行下面的操作:

String username = new String (request.getParameter("username").getBytes("iso8859-1"),"utf-8");

    这样username的值就不会是乱码了。

 

  example2:get参数传递方式 + Tomcat 8 及以上版本 

  在这种情况下,不会出现乱码问题,还是上面的Tomcat 组件Connector,在Tomcat 8 中该对象的构造方法为:

 1 protected String URIEncoding = null;
 2 public Connector(String protocol) {
 3         setProtocol(protocol);
 4         ProtocolHandler p = null;
 5         try {
 6             Class<?> clazz = Class.forName(protocolHandlerClassName);
 7             p = (ProtocolHandler) clazz.getDeclaredConstructor().newInstance();
 8         } catch (Exception e) {
 9             log.error(sm.getString(
10                     "coyoteConnector.protocolHandlerInstantiationFailed"), e);
11         } finally {
12             this.protocolHandler = p;
13         }
14 
15         if (!Globals.STRICT_SERVLET_COMPLIANCE) {
16             URIEncoding = "UTF-8";
17             URIEncodingLower = URIEncoding.toLowerCase(Locale.ENGLISH);
18         }
19     }

  与上面的Tomcat 7中的Connector构造器对比就可以发现,URIEncoding的默认值为UTF-8,所以get方式请求传递的中文参数我们就不需要处理了。

  

  example3:post参数传递方式 + Tomcat

  使用post参数传递方式,无论是Tomcat 8 版本前后,都需要进行乱码处理,通过网络抓包,我们可以看到post方式传递的参数会放在请求体中,这也是与get方式的一点不同之处(get方式传递的参数从url地址栏中能看到,是放在请求行中的),处理post方式的中文乱码,实际上是处理流的编码,说了这么多,其实只需要在获得参数前,加上这样一行代码即可:

request.setCharacterEncoding("utf-8");

  就会发现 post参数传递方式 + Tomcat 中文传参问题解决了。

    

3.结语

  以上总结了关于一些常见中文参数传递乱码的解决方式,至于程序中其他的中文乱码情况,我还在整理中,例如response获得输出流导致页面的乱码问题等等,有什么问题可以留言,我们一起讨论。上诉总结若有不正确之处,希望能够指出,我定当认真修复,谢谢。

 

转载请注明出处!

 

参考:

https://www.jianshu.com/p/0ff9cbfc1cca

  

    

版权声明:本文为BoildWater原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/BoildWater/p/10896628.html