jsp和servlet开发过程中参数传递乱码问题总结
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