中文字符的值在web中提交的问题

URL中出现汉字的情况有两种,一种是汉字出现在URL的路径部分,一种是汉字出现在URL的参数部分。
第一种情况依赖于WEB服务器和操作系统是否支持,但是在做WEB应用的时候应该避免这种做法。
第二种情况的时候必须采用编码后传参,接受时解码的方式完成参数值的获取。
参数可以通过表单提交,浏览器地址栏输入,URL链接点击。
下面的这些测试是在tomcat中进行的
先来看通过表单post提交的方式。

html文件如下:

test encoding
GB2312页面

meta的设置为
通过Fiddler抓取的提交内容如下图:param=%D6%D0%CE%C4,
System.out.println(java.net.URLEncoder.encode("中文", "gb2312"));得到的结果为 %D6%D0%CE%C4
可以判断浏览器将参数编码为GB2312
在后端的代码中通过下面的代码能够得到正确的数据
request.setCharacterEncoding("GB2312");
String param = request.getParameter("param");
注意setCharacterEncoding必须在从request取数据之前执行。
如果不通过setCharacterEncoding指定编码,数据流默认以ISO-8859-1的编码,需要按照下面的方式转换。
String gbparam = new String(request.getParameter("param").getBytes("ISO-8859-1"),"GB2312");

中文字符的值在web中提交的问题

meta的设置为
通过Fiddler抓取的提交内容如下:param=%E4%B8%AD%E6%96%87,
System.out.println(java.net.URLEncoder.encode("中文", "utf-8"));得到的结果为 %E4%B8%AD%E6%96%87
可以判断浏览器将参数编码为GB2312
在后端的代码中通过下面的代码能够得到正确的数据
request.setCharacterEncoding("utf-8");
String param = request.getParameter("param");

中文字符的值在web中提交的问题

在地址栏中直接输入http://localhost:8080/prjWebSec/encode/enctest1.jsp?param=中文
通过Fiddler抓取的提交内容如下,在firefox和chrome都是用的utf-8编码
http://localhost:8080/prjWebSec/encode/enctest1.jsp?param=%E4%B8%AD%E6%96%87

在我的测试中,如果是jsp文件post提交,不管meta的content设置的是gb2312还是utf-8,
提交的参数都是以utf-8编码的。

如果在link中对参数进行encode如下
">中文encoded

浏览器中源码如下:中文被utf-8编码
中文encoded

点击链接后浏览器地址栏变成如下,浏览器显示URL在地址栏中的时候做了一次自动解码。 http://localhost:8080/prjWebSec/encode/enctest2.jsp?param=中文,
提交和传输到服务器端的是%E4%B8%AD%E6%96%87。
后端取到参数后和post的处理原则一致。

如果在link中对参数进行两次encode如下
(URLEncoder.encode(">">
浏览器中源码如下:第一次中文被utf-8编码成%E4%B8%AD%E6%96%87,第二次将%再编码成%25,最后的结果如下
中文double encoded
点击链接后浏览器地址栏和源码中的形式一致,浏览器只会对%xx自动解码,对%xxxx不会自动解码。
http://localhost:8080/prjWebSec/http://blog.csdn.net/kkdelta/article/details/encode/enctest2.jsp?param=%25E4%25B8%25AD%25E6%2596%2587
后端取到参数后需要做一次utf-8的decode,request的编码则无所谓,通过request.getParameter("param")
得到的值总是%E4%B8%AD%E6%96%87,下面的代码能得到"中文"这个值.
String decodedparam = URLDecoder.decode(request.getParameter("param"),"UTF-8");

对于编码的处理,如果处理多字节的字符,一般来讲最好将提交和接收端都设置成utf-8.
接收端编码设置要在从request拿数据之前。在链接中一般也没有必要对参数做两次encoding。

参数提交和读取的过程应该是浏览器对参数进行编码,
编码后的参数传给web服务器,到达服务器后,服务器会将得到的内容以一种编码来表示。
以tomcat为例,这时候发生了(UTF-8 -->ISO-8859-1),这时候参数值是ISO-8859-1表示的。
在request.setCharacterEncoding("utf-8");
然后request.getParameter("param")的时候又转回了utf-8。

如果直接通过stream的方式取到字节流,内容如下
112 97 114 97 109 61 37 69 52 37 66 56 37 65 68 37 69 54 37 57 54 37 56 55
正好对应 param=%E4%B8%AD%E6%96%87,所以发生解码的时候是在 request.getParameter的时候。
如果在这之前setCharacterEncoding设置了编码,则用设置的编码来解码。否则用servlet服务器的
默认编码来解码。取字节流的代码如下

ServletInputStream input = request.getInputStream(); System.out.println(input); byte[] readBytes = new byte[10]; while (true) { if (input.available() >= 10) { input.read(readBytes); for (byte b : readBytes) { System.out.print(b + " "); } } else { int readByte = 0; while((readByte = input.read()) !=-1){ System.out.print(readByte + " "); } break; } }

通常一个做法是配置一个fittler,在filtter中对request设置编码,如下:

encodingFilter org.springframework.web.filter.CharacterEncodingFilter encoding UTF8 forceEncoding true encodingFilter *.html encodingFilter *.jsp

分类:默认分类 时间:2015-03-12 人气:1
本文关键词:
分享到:

相关文章

Copyright (C) quwantang.com, All Rights Reserved.

趣玩堂 版权所有 京ICP备15002868号

processed in 0.027 (s). 10 q(s)