随笔 - 312, 文章 - 14, 评论 - 1393, 引用 - 0
数据加载中……

Tomcat在处理GET和POST请求时产生的乱码问题

本文为原创,如需转载,请注明作者和出处,谢谢

    有个朋友写JSP程序时,在Servlet中取请求参数时出现了乱码,当然,这种乱码问题再简单不过了。由于在JSP中使用了GBK作用页面的编码,那么提交的中文信息自然也会被按着GBK进行编码,为%xx格式的GBK编码。
    要解决这个问题可以说是方法多多。最简单的就是使用request.setCharacterEncoding方法设置编码格式,如下面的代码所示:

request.setCharacterEncoding("GBK");

    在设置完编码格式之后,就可以直接通过request.getParameter方法来获得请求参数中的中文信息了。当然,为了方便,还可以在过滤器中加入上面的语句,这样所有的Servlet都可以直接使用
request.getParameter方法来获得请求参数中的中文信息了。 除了这两种方法,还可以不使用request.setCharacterEncoding("GBK"),而使用下面的语言来转换编码:

String name = new String(request.getParameter("name").getBytes("ISO-8859-1"), "GBK");

    但为了更快解决这个问题,我就直接告诉这位朋友使用了setCharacterEncoding方法来设置编码。但是说来奇怪,还是出现乱码,没有任何解决问题的迹象。 最郁闷的事就是使用了自己认为100%能解决问题的方法,而这种方法却一点都没起作用。
    最后又让朋友试了最后一种方法,说来奇怪,竟然好使了。当然,这也没什么可奇怪的,本来就应该好使,但奇就奇在setCharacterEncoding方法并没有去掉,也就是说,同时使用了下面两条语句,竟然得到了正常的中文请求参数值:

request.setCharacterEncoding("GBK");
String name 
= new String(request.getParameter("name").getBytes("ISO-8859-1"), "GBK");
System.out.println(name);  
//  正常输出中文请求参数

    按着常理来说,这是不可能的,既然使用了setCharacterEncoding方法设置成了GBK,再使用
new String(request.getParameter("name").getBytes("ISO-8859-1"), "GBK")来转换,得到的应该是?????,不可能是正常的中文,只有将setCharacterEncoding方法去了,以ISO-8859-1格式保存的字符串才可以用ISO-8859-1格式还原,再用GBK重新保存成Java字符串(这一步实际上就是GBK转Unicode)。

    但经过仔细思考后,决定看下JSP代码是如何写的。不看不知道,一看吓一跳,原来<form>在提交时使用的是GET,而未用POST,这当然没什么了不起的,用什么都可以,但对编码就有问题了。自从Tomcat5.x开始,GET和POST方法提交的信息,Tomcat采用了不同的方式来处理编码,对于POST请求,Tomcat会仍然使用request.setCharacterEncoding方法所设置的编码来处理,如果未设置,则使用默认的iso-8859-1编码。而GET请求则不同,Tomcat对于GET请求并不会考虑使用
request.setCharacterEncoding方法设置的编码,而会永远使用iso-8859-1编码,而这位朋友使用的正好是GET请求,因此,tomcat将会使用iso-8859-1将提交的字节转换成字符串。

解决的方法有两个:
1.  将GET请求改成POST请求,然后就可以使用
request.setCharacterEncoding方法设置编码,并使用request.getParameter方法直接获得中文请求参数了。
2.  不用改GET请求,在Servlet中使用如下的代码来得到中文请求参数。

String name = new String(request.getParameter("name").getBytes("ISO-8859-1"), "GBK");

    综上所述,如果使用了GET请求,则setCharacterEncoding方法不起作用,只能使用上面的代码来解决,而使用POST请求,尽管
setCharacterEncoding方法起作用,但使用上面的代码仍然好使(在这时不能使用setCharacterEncoding方法将编码格式设置成非iso-8859-1格式)。因此,如果想让Servlet可以同时处理GET和POST请求中的中文信息,除了判断这两种方法外,还可以使用上面的代码来同时处理这两种请求的中文信息。

    笔者建议使用如下的代码来获得中文请求参数:

String name = new String(request.getParameter("name").getBytes("ISO-8859-1"), "GBK");

    因为上面的代码是利用了Java的编码能力,对于所有的Web服务器都会有效,而setCharacterEncoding方法是通过Web服务器支持的,并不是所有的Web服务器都会对该方法有很好的支持。





Android开发完全讲义(第2版)(本书版权已输出到台湾)

http://product.dangdang.com/product.aspx?product_id=22741502



Android高薪之路:Android程序员面试宝典 http://book.360buy.com/10970314.html


新浪微博:http://t.sina.com.cn/androidguy   昵称:李宁_Lining

posted on 2008-09-05 15:48 银河使者 阅读(3043) 评论(8)  编辑  收藏 所属分类: javaweb 原创

评论

# re: Tomcat在处理GET和POST请求时产生的乱码问题  回复  更多评论   


我还真以为你发现了什么。
2008-09-05 19:44 | 随便

# re: Tomcat在处理GET和POST请求时产生的乱码问题  回复  更多评论   

只是解释一下为什么最好用String name = new String(request.getParameter("name").getBytes("ISO-8859-1"), "GBK");,哈哈。
2008-09-05 20:03 | 银河使者

# re: Tomcat在处理GET和POST请求时产生的乱码问题  回复  更多评论   

tomcat就是有这样很变态的问题.
新人学习中....
2008-09-12 00:19 | 楼上两位很垃圾

# re: Tomcat在处理GET和POST请求时产生的乱码问题  回复  更多评论   

谢谢。确实很大帮助。其他网页上通常说在server.xml中设置URIEncoding就可以,但事实上不起作用。采用笔者使用的方法成功了。 我使用的是Tomcat 6。
2008-09-25 20:46 | 专吃饭右手

# re: Tomcat在处理GET和POST请求时产生的乱码问题  回复  更多评论   

一直搞不明白为什么request.setCharacterEncoding("GBK")不起作用,看了这篇文章,茅塞顿开。
2008-10-05 10:14 | 文涛

# re: Tomcat在处理GET和POST请求时产生的乱码问题  回复  更多评论   

好!
2008-10-24 16:05 | lyshyhaungli

# re: Tomcat在处理GET和POST请求时产生的乱码问题  回复  更多评论   

j2ee的API里说的很清楚
setCharacterEncoding
public void setCharacterEncoding(java.lang.String env)
throws java.io.UnsupportedEncodingExceptionOverrides the name of the character encoding used in the body of this request. This method must be called prior to reading request parameters or reading input using getReader().
有什么疑问请参考http://rubyeye.javaeye.com/blog/266705

# re: Tomcat在处理GET和POST请求时产生的乱码问题  回复  更多评论   

真是太感谢这篇楼主了,这篇帖子很棒!
2009-05-31 19:12 | 茅塞顿开

只有注册用户登录后才能发表评论。


网站导航: