0 0

关于URLEncoder编码的问题5

今天遇到了一个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:

    <Connector port="8080" protocol="HTTP/1.1" 
               connectionTimeout="20000" 
               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的编码吗


byte[] bytes = test.getBytes("iso8859-1"); 


改为

byte[] bytes = test.getBytes(); 


看看。

    public byte[] getBytes()
    {
        return StringCoding.encode(value, offset, count);
    }

    static byte[] encode(char ac[], int i, int j)
    {
        String s = Charset.defaultCharset().name();
        try
        {
            return encode(s, ac, i, j);
        }
        catch(UnsupportedEncodingException unsupportedencodingexception)
        {
            warnUnsupportedCharset(s);
        }
        try
        {
            return encode("ISO-8859-1", ac, i, j);
        }
        catch(UnsupportedEncodingException unsupportedencodingexception1)
        {
            MessageUtils.err((new StringBuilder()).append("ISO-8859-1 charset not available: ").append(unsupportedencodingexception1.toString()).toString());
        }
        System.exit(1);
        return null;
    }
谢谢你的代码了,这里是如果 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

16个答案 按时间排序 按投票排序

0 0

在你的Tomcat的server.xml 这个位置加上就行了` 我以前碰到过这样的问题` 加上这样就行了!

URIEncoding="UTF-8" 


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

2011年1月06日 16:43
0 0

引用
System.out.println("默认编码"+Charset.defaultCharset());这样的代码得到是GBK,难道是有代码执行先后的问题吗?


返回此 Java 虚拟机的默认 charset。
默认 charset 在虚拟机启动时决定,通常根据语言环境和基础操作系统的 charset 来确定。

2011年1月06日 13:53
0 0

引用
在页面我做一个含有中文的参数的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的编码吗


    因为URL采用ISO-8859-1编码,因此,我们需要使用 bytes = string.getBytes("iso-8859-1") 得到原始的字节串,再用 string = new String(bytes, "GBK") 重新得到正确的字符串

2011年1月06日 13:36
0 0

引用
而后再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的编码吗


byte[] bytes = test.getBytes("iso8859-1"); 


改为

byte[] bytes = test.getBytes(); 


看看。

    public byte[] getBytes()
    {
        return StringCoding.encode(value, offset, count);
    }

    static byte[] encode(char ac[], int i, int j)
    {
        String s = Charset.defaultCharset().name();
        try
        {
            return encode(s, ac, i, j);
        }
        catch(UnsupportedEncodingException unsupportedencodingexception)
        {
            warnUnsupportedCharset(s);
        }
        try
        {
            return encode("ISO-8859-1", ac, i, j);
        }
        catch(UnsupportedEncodingException unsupportedencodingexception1)
        {
            MessageUtils.err((new StringBuilder()).append("ISO-8859-1 charset not available: ").append(unsupportedencodingexception1.toString()).toString());
        }
        System.exit(1);
        return null;
    }

2011年1月06日 13:22
0 0

因为URL采用ISO-8859-1编码,所以得把它转换成与页面相同的编码方式

2011年1月06日 13:18
0 0

引用
String test = request.getParameter("test");


这句话才是重点

http你可以看成三部分(其实不止,其它部分与这个问题关系不大)
uri
header
body

如果你post的参数神马的都放在了uri里面,比如http://xxxx/?userId=xx&usernam=xx
这里会URIEncoding

但是
header和body不同
这个和你的httpclient实现息息相关
你现在通过request.getParameter("test"),是来解析body这部分,全看httpclient如何编码了,跟uriencoding一点关系都没有

2011年1月06日 12:50
0 0

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


“中文”在传输过程中会转换为 %D6%D0%CE%C4 再提交到服务器,按页面编码转

2011年1月06日 12:01
0 0

网页提交字符串:
    当页面中的表单提交字符串时,首先把字符串按照当前页面的编码,转化成字节串。然后再将每个字节转化成 "%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") 重新得到正确的字符串 "中

2011年1月06日 11:46
0 0

关于 字符,字节和编码,有一篇说得很详细的文章,大家有空都看看吧,很有收获的
http://www.regexlab.com/zh/encoding.htm

2011年1月06日 11:38
0 0

tomcat 设置server.xml文件中的URIEncoding="UTF-8"是为了解决请求信息在传输过程中乱码的问题。一般在web项目开发的时候需要把页面、数据库、url三者的编码格式统一,为了兼容汉字需要将他们统一设置为utf-8

2011年1月06日 11:31
0 0

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


对,设置好之后容器自己会做。你在生成URL时 URLEncoder.encode(url, "UTF-8") ,这样就可以了。 当然尽可能采用整个系统一个编码。

2011年1月06日 11:28
0 0

http://www.javanb.com/java/1/17391.html

2011年1月06日 11:24
0 0

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

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

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

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

2011年1月06日 11:21
0 0

2、
假如你页面使用的是GBK编码,
在接收的时候new String(test.getBytes("iso8859-1"))
new String会使用本地编码(GBK)将字节数据test.getBytes("iso8859-1")重新组装为字符串,这样就不会出现乱码了

2011年1月06日 11:17
0 0

还要看你的网站服务器用的什么编码,最好全部统一

2011年1月06日 11:16
0 0

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解码,都按指定的编码格式进行编码、解码,可以保证不会出现乱码

2011年1月06日 11:13

相关推荐

    C++ 版本UrlEncoder编码解码工具:支持ANSIC和UTF8格式

    C++ 版本UrlEncoder编码解码工具:支持ANSIC和UTF8格式,是URLEncoderHTML 格式编码的实用工具类。详情参照文章:...

    java使用URLDecoder和URLEncoder对中文字符进行编码和解码

    在Java编程语言中,`URLDecoder`和`URLEncoder`是两个非常重要的工具类,主要用于处理URL中的中文字符和其他特殊...理解它们的工作原理和使用方法,能帮助开发者避免编码解码过程中的常见问题,保证数据传输的准确性。

    URLEncoder与URLDecoder的应用

    在Java编程语言中,`URLEncoder`与`URLDecoder`是处理URL编码和解码的两个重要工具类。它们主要应用于对字符串进行编码或解码,确保这些字符串能够安全地在网络上传输。尤其是在处理包含特殊字符(如中文字符)的...

    深入分析 Java 中的中文编码问题

    对于URL编码,Java提供了`URLEncoder.encode()`方法,但默认使用的是ISO-8859-1编码,对于中文字符会存在问题。我们需要显式指定UTF-8编码,如下所示: ```java String url = ...

    J2ME URLEncoder 和 URLDecoder 类的实现

    在Java Micro Edition (J2ME)环境中,开发者可能会遇到一个问题:标准Java API中的一些功能可能并未包含在其中,比如`URLEncoder`和`URLDecoder`类。这两个类在标准Java SE环境中用于对URL字符串进行编码和解码,以...

    java中的URLEncoder和URLDecoder类.docx

    在 Java 中,URLEncoder 和 URLDecoder 是两个非常重要的类,它们用于处理 URL 编码和解码问题。在本文中,我们将深入探讨这两个类的使用方法、特点和应用场景。 一、URLEncoder 类 URLEncoder 类是一个静态类,它...

    j2ME URLEncoder Vs URLDEcoder

    URLEncoder的主要作用是对URL中的参数进行编码,这是因为URL中不能包含某些特殊字符,如空格、引号、冒号等。使用URLEncoder.encode()方法,可以将字符串转换为适合在URL中传输的形式。例如,如果有一个包含空格的...

    web编码问题小结.doc

    ### Web编码问题详解 在Web开发中,字符编码问题时常困扰开发者,尤其是在处理中文或其它非ASCII字符时。本文档《web编码问题小结》详细总结了Java开发中可能遇到的各种编码问题及其解决方案,覆盖了数据库、Cookie...

    AJAX编码问题

    4. **URL参数编码**:对于GET请求,可以通过`URLEncoder.encode()`方法对URL中的参数进行编码,避免乱码问题。例如: ```java String encodedParam = URLEncoder.encode(param, "UTF-8"); ``` #### 四、总结 ...

    UniEncoder解码库-可以快速解码和编码

    在IT行业中,编码和解码是开发者...通过理解编码和解码的基本概念,以及C#中如何进行这些操作,开发者可以更好地利用这个库来解决实际问题。同时,深入研究源代码和API文档,可以帮助我们充分利用其潜在的性能优势。

    解析URL和文件的编码方式

    此外,Java的`java.net.URLDecoder`和`java.net.URLEncoder`类也提供了URL编码和解码的功能。 文件的编码方式有时会在文件的头部或通过其他方式指定,如XML文件的`&lt;?xml version="1.0" encoding="UTF-8"?&gt;`声明。在...

    url编码gbk格式

    这两个工具类可能分别采用了不同的编码策略,例如一个可能使用了Java的`java.net.URLEncoder`类并指定GBK为字符集,另一个可能实现了自定义的编码算法来确保GBK字符的正确转换。 在实际应用中,使用这样的工具类...

    jsp使用URL编码传递中文参数问题.doc

    在JSP开发中,处理URL编码传递...通过正确使用`URLEncoder.encode()`进行编码,以及适当地解码`request.getParameter()`返回的值,可以有效地解决乱码问题。同时,保持整个应用的编码规范,有助于减少类似问题的发生。

    C# 字符编码与解码(Encoder and Decoder)

    C# Encoder 与 Decoder的例子,详细注释。 Encoder Decoder 编码 解码 C# Encoder Decoder 编码 解码 C# Encoder Decoder 编码 解码 C# Encoder Decoder 编码 解码 C#

    JAVA字符编码系列三[借鉴].pdf

    - URL编码:URL中非ASCII字符需要使用`URLEncoder.encode()`进行编码,`URLDecoder.decode()`解码。 3. **系统软件和工具软件的编码** - 操作系统、编辑器、数据库等可能有自己的默认字符集,与Java程序交互时需...

    tomcat字符编码总结

    - **解决方案**: 在生成链接时,使用`URLEncoder.encode("中文", "UTF-8")`对参数进行编码,确保传输过程中字符集的一致性。 **4. 地址栏中直接输入中文参数** - **问题**: 直接在地址栏输入包含中文的URL参数时,...

    java中的编码知识

    4. **URL编码与解码**:在网络请求中,URL中的特殊字符需要进行编码,可以使用`URLEncoder.encode(urlPart, "UTF-8")`。相应的,`URLDecoder.decode(encodedUrlPart, "UTF-8")`用于解码。 5. **国际化与本地化**:...

    URL解码-编码器URL解码-编码器

    - 不要对已经编码过的URL再次编码,以免造成双编码问题。 - 遵循RFC 3986标准,对于某些保留字符(如:/, ?, #, &, =, +)在特定上下文中,可能不需要编码。 综上所述,URL编码与解码是网络通信中的基础操作,对于...

Global site tag (gtag.js) - Google Analytics