`
desert3
  • 浏览: 2160726 次
  • 性别: Icon_minigender_1
  • 来自: 合肥
社区版块
存档分类
最新评论

UrlEncoder,UrlDecoder, 字符集对Encoder的影响

 
阅读更多
字符集对Encoder的影响,其实就是字符在不同字符集下编码不同,即使用的字节数不同,而每个字节都用2个16进制的字母在url中表示(它们之间的关系是,第一个16进制数代表一个字节的前4位,后一个16进制数代表一个字节的后4位!)
相应的我们可以看到,Tomcat中类org.apache.catalina.util.RequestUtil对url进行转码的方法,其中case '%'后面,data[ox++] = (byte)((convertHexDigit(data[ix++]) < <  4) + convertHexDigit(data[ix++]));就是根据这个规则来把%xx,转成字节,然后根据字节以及编码,转成正确的字符串。同时从convertHexDigit方法可以看出,%后面的字母是大小写不敏感的。
 public static  void parseParameters(Map map,
    byte[] data,
    String encoding) throws UnsupportedEncodingException 

{
        if (data != null && data.length  > 0) {
            int    ix = 0;
            int    ox = 0;
            String key = null;
            String value = null;
            while (ix <  data.length) {
                byte c = data[ix++];
                switch ((char) c) {
                case '&':
                    value = new String(data, 0, ox, encoding);
                    if (key != null) {
                        putMapEntry(map, key, value);
                        key = null;
                    }
                    ox = 0;
                    break;
                case '=':
                    if (key == null) {
                        key = new String(data, 0, ox, encoding);
                        ox = 0;
                    } else {
                        data[ox++] = c;
                    }                   
                    break;  
                case '+':
                    data[ox++] = (byte)' ';
                    break;
                case '%':
                    data[ox++] = (byte)((convertHexDigit(data[ix++]) < <  4)
                                    + convertHexDigit(data[ix++]));
                    break;
                default:
                    data[ox++] = c;
                }
            }
            //The last value does not end in '&'.  So save it now.
            if (key != null) {
                value = new String(data, 0, ox, encoding);
                putMapEntry(map, key, value);
            }
        }
}

 private static byte convertHexDigit( byte b ) {
        if ((b >= '0') && (b <= '9')) return (byte)(b - '0');
        if ((b >= 'a') && (b <= 'f')) return (byte)(b - 'a' + 10);
        if ((b >= 'A') && (b <= 'F')) return (byte)(b - 'A' + 10);
        throw new IllegalArgumentException(sm.getString("requestUtil.convertHexDigit.notHex",Character.valueOf((char)b)));
    }

URLEncode,RFC 3986規範了哪些字符是作為保留字(如:!、@、/、?等),如果URL中使用到了這些保留字,就必須將它編碼為「%HEXHEX」的16进制形式[/color],舉例來說,「空白字元」的 ASCII code 是32,所以會被編碼為 %20,而其它 non-ASCII 字元(如:中文字)則以 UTF-8 字元編碼後的字节数组來編碼成 %HEXHEX 的形式(每个字节8位,取值在-128-127之间,用2个16进制的值来表示)。(这样就是在URL中用US-ASCII字符来表示非US-ASCII或者URL保留字的值)

在 RFC 3986 之前,HTTP 也有為 GET/POST 在傳遞參數時的 url encode 方式作定義,基本上也是 encode 成 %HEXHEX 的形式,保留字跟 RFC 3986 的有部份出入,不過就沒有限定一定是 UTF-8 的文字編碼了,而且還有一個重點--「空白字元」會被編碼成 + 而不是 %20。

常用語言的函式庫
因為有這樣的差異,所以開發人員在使用函式庫的時候常常會搞混什麼時候該用/不該用什麼函式,以 PHP 來說就分為兩組函式:
    urlencode / urldecode
    簡單地說就是以 HTTP 所使用的 application/x-www-form-urlencoded 的編碼規則,也就是會將空白字元編碼成 + 而不是%20。
    rawurlencode / rawurldecode
    按照 RFC 3986 所定義的方式來作編碼。

Python 版本的話就是:
    urllib.urlencode / urllib.urldecode
    會把空白字元編碼成 +
    目前要使用 Python 3 以後的 urllib.parse.urlencode 才會按照 RFC 3986 的方式來作編碼,若是 2.x 的版本就要另外處理或是找 3rd-party 資料庫來做。

JavaScript 的 encodeURI 或是 encodeURIComponent (兩者僅相差一些保留字是否要作編碼,如 #)目前則是都使用 RFC 3986 的方式來作編碼,所以要作 application/x-www-form-urlencoded 的編碼時(AJAX POST),就要自己把 %20 替換成 + (jQuery 目前的程式碼就是這樣做的)

Java 的 java.net.URLEncoder.encode 這個 method 也是編碼成 application/x-www-form-urlencoded 的方式,如果要遵照 RFC 3986 的定義,則可以自行再把 + 替換成 %20 即可。
参考:混亂的 URLEncode

使用不同的编码,来进行UrlEncoder
汉字“中”,在不同的编码中使用不同长度的字节来表示,而每个字节是8位的,可以用16进制的2个字符来表示
在UTF-8中用3个字节表示的值:%E4%B8%AD,
而在GB2312编码中用的是2个字节的值:%D6%D0
它们字节的编码没有任何关系,但是可以通过Unicode编码中转后相互转换。

编码后,就把%后跟着2个16进制值的字符传递到服务器上去。
try {

			System.out.println(((byte) 0x01));
			
			// 汉字“中”用UTF-8进行URLEncode的时候,得到%e4%b8%ad(对应的ISO-8859-1的字符是中)
			String item = new String(new byte[] { (byte) 0xe4, (byte) 0xb8, (byte) 0xad }, "UTF-8");
			// 中
			System.out.println(item);

			item = new String(new byte[] { (byte) 0xe4, (byte) 0xb8, (byte) 0xad }, "ISO-8859-1");
			// 中
			System.out.println(item);

			System.out.println(new BigInteger("253").toByteArray());
			System.out.println(Integer.toBinaryString(253));

			// 中
			item = new String(item.getBytes("ISO_8859_1"), "UTF-8");
			System.out.println(item);
			// 中
			item = new String(item.getBytes("UTF-8"), "ISO_8859_1");
			System.out.println(item);

			// %E4%B8%AD
			System.out.println(URLEncoder.encode("中", "UTF-8"));
			// %3F
			System.out.println(URLEncoder.encode("中", "ISO-8859-1"));
			// %D6%D0
			System.out.println(URLEncoder.encode("中", "GB2312"));

			// 中文
			System.out
					.println(URLDecoder.decode("%E4%B8%AD%E6%96%87", "UTF-8"));
			// 乱码 ??
			System.out.println(URLDecoder.decode("%3F%3F", "ISO-8859-1"));
			// 中文
			System.out.println(URLDecoder.decode("%D6%D0%CE%C4", "GB2312"));
			// 乱码 涓��
			System.out.println(URLDecoder
					.decode("%E4%B8%AD%E6%96%87", "GB2312"));
		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
分享到:
评论

相关推荐

    使用URLDecoder和URLEncoder 区别

    在使用 URLDecoder 和 URLEncoder 时,需要指定字符集,以避免乱码问题。不同的字符集对应不同的字节数,因此在转换时需要指定正确的字符集。例如,在上面的程序中,我们使用 UTF-8 和 GBK 两个字符集。 总结 ...

    j2ME URLEncoder Vs URLDEcoder

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

    J2ME URLEncoder 和 URLDecoder 类的实现

    首先,`URLEncoder`类的主要任务是对字符串中的非字母数字字符进行编码,将其转换为百分比编码(%nn)的形式,其中nn是字符的ASCII值的十六进制表示。在实现这个类时,我们需要遍历输入字符串,对每个字符进行检查,...

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

    在Java编程语言中,`URLDecoder`和`URLEncoder`是两个非常重要的工具类,主要用于处理URL中的中文字符和其他特殊字符。这两个类位于`java.net`包下,可以帮助开发者进行字符串编码和解码,确保数据在网络传输过程中...

    java中的URLEncoder和URLDecoder类.docx

    URLEncoder 类可以将这些数据编码为 URL 可以识别的格式,而 URLDecoder 类可以将这些数据解码回原始字符串。 四、结论 URLEncoder 和 URLDecoder 是两个非常有用的类,它们可以帮助我们处理 URL 编码和解码问题。...

    URLEncoder与URLDecoder的应用

    在这个例子中,之前通过`URLEncoder`编码的字符串`enUft`被`URLDecoder.decode()`方法解码回其原始状态。 #### 三、注意事项 1. **异常处理**:使用这两个类时需要注意捕获并处理`UnsupportedEncodingException`...

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

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

    字符集转换_SAP字符集转换_SAP

    字符集转换_SAP字符集转换_SAP字符集转换_SAP

    java中URLEncoder.encode与URLDecoder.decode处理url特殊参数的方法

    **`URLDecoder.decode()`** 方法则用于对已编码的URL参数进行解码,它同样需要两个参数:待解码的字符串和字符集。这个方法将百分号编码转换回原始字符,以便在服务器端或客户端恢复原始数据。例如,当服务器接收到 ...

    JAVA字符集

    此外,`java.net.URLDecoder`和`java.net.URLEncoder`则用于处理URL中的编码问题,URL编码通常使用UTF-8。 在实际开发中,不正确的字符集设置可能会导致乱码问题。例如,当读取一个UTF-8编码的网页,但使用GBK解码...

    java 使用URLDecoder和URLEncoder对中文进行处理

    在Java编程语言中,URLDecoder和URLEncoder是两个非常重要的工具类,主要用于处理URL(统一资源定位符)中的中文字符。这是因为URL的标准格式不支持直接包含非ASCII字符,特别是中文等多字节字符,需要进行特定的...

    UrlDecoder和UrlEncoder使用详解_动力节点Java学院整理

    UrlDecoder和UrlEncoder使用详解 UrlDecoder和UrlEncoder是Java语言中两个重要的工具类,分别用于URL编码和解码。下面是对这两个类的详细介绍和使用方法。 一、UrlEncoder UrlEncoder是Java语言中一个静态方法的...

    Labview_encoder_

    在IT行业中,编码器(Encoder)是一种常见的传感器设备,用于检测物体的位置、速度或角度变化。在本案例中,我们关注的是360度旋转编码器,它通过以太网接口与计算机通信,读取其测量的数据。"Labview_encoder_"这个...

    Java中的UrlDecoder 和 UrlEncoder_动力节点Java学院整理

    Java中的`UrlDecoder`和`UrlEncoder`是两个非常重要的工具类,主要用于处理URL编码和解码的问题。在Web开发中,特别是在HTTP请求和响应中,URL编码是必不可少的步骤,因为URL中不能包含某些特殊字符,如空格、中文...

    URLDecoder

    根据提供的文件信息,我们可以从标题、描述以及部分代码中提炼出与 `URLDecoder` 和 `URLEncoder` 相关的知识点。以下是对这些知识点的详细解释: ### 关于URL编码与解码 #### 1. **URL编码的概念** URL 编码(也...

    urlencoder:java.net.URLEncoder

    urlencoder 在Node.js中实现Java Land URLEncoder安装$ npm install urlencoder 例子超级简单: var encoder = require ( 'urlencoder' ) ;encoder . encode ( '哈哈' ) ;执照麻省理工学院

    PB 进制转换 url编码 urlencode urldecode 数组排序

    hexdecode 将16进制字符串以指定字符集进行解码成字符 hexencode 将字符串指定字符集进行编码成16进制字符串 hexstring 将字符串指定字符集进行编码成16进制字符串 power 求数字的幂函数 replace 将指定字符串中的源...

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

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

    java中文乱码字符集解决大全.pdf

    大多数浏览器默认使用UTF-8编码传递参数,因此,服务器端接收中文参数时,需确保正确解码,如使用URLEncoder/URLDecoder进行编码解码。 总结,Java中文乱码问题涉及多个层面,包括源文件编码、编译过程、执行环境...

Global site tag (gtag.js) - Google Analytics