关于URLEncoder编码的问题

http://www.iteye.com/problems/56952
今天遇到了一个url后追加中文参数乱码的问题,后来用URLEncoder.encode这个方法处理了下解决了。不过感觉还有点迷糊。所以自己写了一个测试的demo.
下面是一个很简单的servlet的部分代码:


protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

String test = request.getParameter("test");
System.out.println("dddddddddddddddddddddddddddd"+test);
System.out.println(new String(test.getBytes("iso8859-1")));
}

输入url :http://localhost:8080/web/TestServlet?test=aa
输出 :ddddddddddddddddddddddddddddaa
       aa

输入:http://localhost:8080/web/TestServlet?test=中文
输出:  dddddddddddddddddddddddddddd????
        中文
输入:http://localhost:8080/web/TestServlet?test=%D6%D0%CE%C4   (注:test是经过encode"中文"的编码)
输出:   dddddddddddddddddddddddddddd????
        中文

输入了三次,似乎在这里中文参数经不经过URLEncoder.encode都可以运行,我就不明白了,encode有什么作用?还有我传递的参数只是经过了encode在接受参数的时候并不需要解码?有点迷糊!

问题补充:
zhanjia 写道
1、
URLEncoder.encode(String s, String enc)
使用指定的编码机制将字符串转换为 application/x-www-form-urlencoded 格式

URLDecoder.decode(String s, String enc)
使用指定的编码机制对 application/x-www-form-urlencoded 字符串解码。

发送的时候使用URLEncoder.encode编码,接收的时候使用URLDecoder.decode解码,都按指定的编码格式进行编码、解码,可以保证不会出现乱码

首先谢谢你的回答,刚提到的编码、解码。我刚传递的是编码后的参数,但在servlet我并没解码也可以得到正常的参数,这是我不明白之一。还有一点是为什么我中文传递的时候,编码和不编码的效果是一样的,这是我不明白之二。希望给予答案,谢谢!

问题补充:
lockwang 写道
还要看你的网站服务器用的什么编码,最好全部统一

服务器我用的是redhat,在/etc/sysconfig/i18n里设置的是GBK这样编码应该和windows是一致的

问题补充:
langshao 写道
URLEncoder.encode 之后浏览器就不会乱编码了,否则会有一些浏览器出现乱码的(如在IE的URL地址中直接输入中文试试)。

一般Tomcat、WebLogic等都会自动解码,不再需要你自己写程序解码。

Tomcat中指定URL用UTF-8编码server.xml:

Xml代码   收藏代码
  1. <Connector port="8080" protocol="HTTP/1.1"   
  2.            connectionTimeout="20000"   
  3.            redirectPort="8443" useBodyEncodingForURI="true" URIEncoding="UTF-8" />  

解码工作是中间件容器自动完成的吗,URIEncoding="UTF-8"这段的意思是
URLDecoder.decode(str,"UTF-8")吗?

问题补充:
zhanjia 写道
网页提交字符串:
     当页面中的表单提交字符串时,首先把字符串按照当前页面的编码,转化成字节串。然后再将每个字节转化成 "%XX" 的格式提交到 Web 服务器。比如,一个编码为 GB2312 的页面,提交 "中" 这个字符串时,提交给服务器的内容为 "%D6%D0"。

    在服务器端,Web 服务器把收到的 "%D6%D0" 转化成 [0xD6, 0xD0] 两个字节,然后再根据 GB2312 编码规则得到 "中" 字。

    在 Tomcat 服务器中,request.getParameter() 得到乱码时,常常是因为前面提到的“误解一”造成的。默认情况下,当提交 "%D6%D0" 给 Tomcat 服务器时,request.getParameter() 将返回 [0x00D6, 0x00D0] 两个 UNICODE 字符,而不是返回一个 "中" 字符。因此,我们需要使用 bytes = string.getBytes("iso-8859-1") 得到原始的字节串,再用 string = new String(bytes, "GB2312") 重新得到正确的字符串 "中


感谢回答说的很好,
在页面我做一个含有中文的参数的form提交过程是这样的:
提交form时候浏览器会默认将中文已页面编码方式做 application/x-www-form-urlencode,这时候“中”字被编码为%D6%D0,等效代码为URLEncoder.encode("中","GBK");
而后再servlet中通过做这样的代码处理:
String test = request.getParameter("test");
byte[] bytes = test.getBytes("iso8859-1");
for(int i=0;i<bytes.length;i++)
{
System.out.println(Integer.toHexString(bytes[i]&0xff));
}
打印的字节为D6,D0 得到字节正确,而后从新用GBK编码即可。
大概流程搞懂了,这里有点为什么先用iso8859-1解码呢,难道java系统默认有次iso8859-1的编码吗

问题补充:
langshao 写道
引用
而后再servlet中通过做这样的代码处理:
String test = request.getParameter("test");
byte[] bytes = test.getBytes("iso8859-1");
for(int i=0;i<bytes.length;i++)
{
System.out.println(Integer.toHexString(bytes[i]&0xff));
}
打印的字节为D6,D0 得到字节正确,而后从新用GBK编码即可。
大概流程搞懂了,这里有点为什么先用iso8859-1解码呢,难道java系统默认有次iso8859-1的编码吗


Java代码   收藏代码
  1. byte[] bytes = test.getBytes("iso8859-1");   


改为

Java代码   收藏代码
  1. byte[] bytes = test.getBytes();   


看看。

Java代码   收藏代码
  1. public byte[] getBytes()  
  2. {  
  3.     return StringCoding.encode(value, offset, count);  
  4. }  

Java代码   收藏代码
  1. static byte[] encode(char ac[], int i, int j)  
  2. {  
  3.     String s = Charset.defaultCharset().name();  
  4.     try  
  5.     {  
  6.         return encode(s, ac, i, j);  
  7.     }  
  8.     catch(UnsupportedEncodingException unsupportedencodingexception)  
  9.     {  
  10.         warnUnsupportedCharset(s);  
  11.     }  
  12.     try  
  13.     {  
  14.         return encode("ISO-8859-1", ac, i, j);  
  15.     }  
  16.     catch(UnsupportedEncodingException unsupportedencodingexception1)  
  17.     {  
  18.         MessageUtils.err((new StringBuilder()).append("ISO-8859-1 charset not available: ").append(unsupportedencodingexception1.toString()).toString());  
  19.     }  
  20.     System.exit(1);  
  21.     return null;  
  22. }  
谢谢你的代码了,这里是如果 String s = Charset.defaultCharset().name();得不到编码名的时候会有异常进而传入"iso8859-1" 有什么方式可以给它设置上defaultCharset吗?也就是说让它在
String s = Charset.defaultCharset().name();得到值
另外我在servlet中执行了
System.out.println("默认编码"+Charset.defaultCharset());这样的代码得到是GBK,难道是有代码执行先后的问题吗?
2011年1月06日 11:02
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值