Apache commons 之 codec 深入学习以及URLCodec

我们在入门代码里,写了一些示例,感觉貌似这个类,就只有这么些内容,打开javadoc再看看,发现这个包里货还真不少。

Commons Codec 1.4 API


Packages


org.apache.commons.codec


A small set of interfaces used by the various implementations in the sub-packages.


org.apache.commons.codec.binary


Base64, Binary, and Hexadecimal String encoding and decoding.


org.apache.commons.codec.digest


Operations to simplifiy common MessageDigest tasks.


org.apache.commons.codec.language


Language and phonetic encoders.


org.apache.commons.codec.net


Network related encoding and decoding.

首先看看一些URL编码相关的知识。

简介

当我们每天上网冲浪时,有一些技术我们无时无刻不在面对。有数据本身(网页),数据的格式化,能够让我们获取数据的传输机制,以及让Web网络能够真正成为Web的基础及根本:从一页到另一页的链接。这些链接都是URL。

HTTP URL语法

对于HTTP URL (使用http 或 https 协议),URL的scheme描述部分定义了数据的路径(path),后面是可选的query 和fragment

path 部分看上去是一个分层的结构,类似于文件系统中文件夹和文件的分层结构。path由"/"字符开始,每一个文件夹由"/"分隔,最后是文件。例如"/photos/egypt/cairo/first.jpg"有四个路径片段(segment):"photos"、"egypt"、"cairo" 和 "first.jpg",可以由此推出:"first.jpg"文件在文件夹"cairo"中,而"egypt"文件夹位于web站点的根文件夹"photos"里面。

URL 语法

http URL方案最初由 RFC 1738 定义(实际上,在之前的 RFC 1630也有涉及),而在 http URL
方案被重新定义之前,整个 URL 语法就已经由扩展几次 以适应发展的规范进化为一套 统一资源标识符(Uniform
Resource Identifiers 即 URIs)

对于 URLs 如何拼装,各部分如何分隔有一套语法。例如:"://"分隔方案主机部分。主机路径片段部分由"/"分隔,而查询部分紧跟在"?"之后。这意味着有些字符为语法保留。有些为整个URIs保留,而有些则被特定方案保留。所有出现在不应出现位置的 保留符(例如路径片段——以文件名为例——可能包含"?")必须被URL 编码

URL编码将字符转变成对 URL 解析无意义的无害形式。它将字符转化成为一种特定字符编码的字节序列,然后将字节转换为16进制形式,并将其前面加上"%"。问号的 URL 编码形式为"%3F"。

我们可以将指向 "to_be_or_not_to_be?.jpg"图片的 URL 写成:"http://example.com/to_be_or_not_to_be%3F.jpg",这样就没有人会认为这儿可能由一个查询部分了。

现今多数浏览器显示 URLs 前都会对其解码(将百分号编码字节转回其原本字符),并在获取其网络资源的时候重新编码。这样一来,很多用户从未意识到编码的存在。

另一方面,网页作者,开发者必须明确认识到这一点,因为这里存在着很多陷阱。

URL常见陷阱

如果你正和URL打交道,了解下能够避免的常见陷阱绝对是值得的。现在我们给大家介绍下不仅限于此的一些常见陷阱。

使用哪类字符编码?

URL编码规范并没有定义使用何种字符编码形式去编码字节。一般的ASCII字母数字字符并不需要转义,但是ASCII之外的保留字需要(例如法语单词“n?ud”中的"?")。我们必须提出疑问,应该使用哪类字符编码来编码URL字节。

当然如果只有Unicode的话,这个世界就会清净很多。因为每个字符都包含其中,但是它只是一个集合,或者说是列表如果你愿意,它本身并不是一中编码。Unicode可以使用多种方式进行编码,譬如UTF-8或者UTF-16(也有其它格式),但是问题并没有解决:我们应该使用哪类字符来编码URL(通常也指URI)。

标准并没有定义一个URI应该以何种方式指定其编码,所以其必须从环境信息中进行推导。对于HTTP URL,它可以是HTML页面的编码格式,或HTTP头的。这通常会让人迷惑,也是许多错误的根源。事实上,最新版的URI标准 定义了新的URI scheme将采用UTF-8,host(甚至已有的scheme)也使用UTF-8,这让我更加怀疑:难道host和path真的可以使用不同的编码方式?

每一部分的保留字都是不同。

是的,他们是,是的,他们,是的,他们是。。。

对于一个httpd连接,路径片段部分中的空格被编码为"%20"(不,完全没有"+"),而“+”字符在路径片段部分可以保持不编码。

现在,在查询部分,一个空格可能会被编码为“+”(为了向后兼容:不要试图在URI标准去搜索他)或者“%20”,当作为“+”字符(作为个统配符的结果)会被编译为“%2B”。

这意味着“blue+light blue”字串,如果在路径部分或者查询部分,将会有不同的编码。比如得到"http://example.com/blue+light%20blue?blue%2Blight+blue"这样的编码形式,这样我们不需从语法上分析url结构,就可以推导这个url的整个结构是可能

考虑如下组装URL的Java代码片段

?


1

2


String str = "blue+light blue";

String url = "http://example.com/"
+ str + "?" + str;

编码URL并不是为了转义保留字而进行的简单字符迭代,我们需要确切的知道哪个URL部份有哪些保留字,而有针对性的进行编码。

这也意味着URL重写过滤器如果不考虑合适的编码细节而对URL直接进行分段转换通常是有问题的。对URL进行编码而不考虑具体的分段规则是不切实际的。

保留字不是你想象的那样

大多数人不知道"+"在路径部分是被允许的并且特指正号而不是空格。其他类似的有:

·        "?"在查询部分允许不被转义,

·        "/"在查询部分允许不被转义,

·        "="在作为路径参数或者查询参数值以及在路径部分允许不被转义,

·        ":@-._~!$&‘()*+,;="等字符在路径部分允许不被转义,

·        "/?:@-._~!$&‘()*+,;="等字符在任何段中允许不被转义。

这样下面的地址虽然看起来有点混乱:"http://example.com/:@-._~!$&‘()*+,=;:@-._~!$&‘()*+,=:@-._~!$&‘()*+,==?/?:@-._~!$‘()*+,;=/?:@-._~!$‘()*+,;==#/?:@-._~!$&‘()*+,;="

按照上面的规则,其实上是一个合法的地址。

如果有兴趣的话,相关的知识有非常的多,从使用的角度简单归纳下:

1.       需要通过URL转码的字符,比如汉字等;

2.       不需要通过URL转码的字符,比如12*等;

3.       需要处理的保留字,比如 #等。

如果所有的字符都要自己处理,那么开发应用会比较复杂,而且非常枯燥,org.apache.commons.codec.net这个包就提供了这些数据的处理。

我们看源代码:

package test.ffm83.commons.codec;

import org.apache.commons.codec.CharEncoding;

import org.apache.commons.codec.net.URLCodec;

import org.apache.commons.lang.BooleanUtils;

import org.apache.commons.lang.StringUtils;

/**

* 通过apache commons
codec的net包进行url数据的加密

*

* @author范芳铭

*/

public
class
URLCodecUsage {

public
static void
main(String[] args)
throws Exception{

URLCodecUsage usage = new URLCodecUsage();

usage.useUrlEncode();

usage.useSafeCharEncodeDecode();

usage.useUnsafeEncodeDecode();

}

//普通字符的URL加密

public
void
useUrlEncode() throws Exception{

System.out.println(StringUtils.center("普通字符的URL加密",
50, "-"));

final String msg =
"范芳铭在做Url encode测试,123456";

final URLCodec urlCodec =
new URLCodec();

String enMsg =urlCodec.encode(msg, CharEncoding.UTF_8);

System.out.println(msg +
",加密之后");

System.out.println(enMsg);

}

//安全字符的编码解码

public
void
useSafeCharEncodeDecode() throws Exception {

System.out.println(StringUtils.center("安全字符的编码解码", 50,
"-"));

final URLCodec urlCodec =
new URLCodec();

final String plain =
"abc123_-.*";

//final String plain = "12345";

final String encoded = urlCodec.encode(plain);

System.out.println("plain:" + plain);

System.out.println("encoded:" + encoded);

System.out.println("Safe chars URL encoding test:"+ BooleanUtils.toStringYesNo(

plain.equals(encoded)));

System.out.println("Safe chars URL encoding test:"+ BooleanUtils.toStringYesNo(

plain.equals(urlCodec.decode(encoded))));

}

//不安全字符的编码解码

public
void
useUnsafeEncodeDecode()throwsException {

System.out.println(StringUtils.center("不安全字符的编码解码", 50,
"-"));

final URLCodec urlCodec =
new URLCodec();

final String plain =
"[email protected]#$%^&()+{}\"\\;:`,/[]";

final String encoded = urlCodec.encode(plain);

System.out.println("plain:" + plain);

System.out.println("encoded:" + encoded);

System.out.println("Safe chars URL encoding test:"+ BooleanUtils.toStringYesNo(

plain.equals(encoded)));

System.out.println("Safe chars URL encoding test:"+ BooleanUtils.toStringYesNo(

plain.equals(urlCodec.decode(encoded))));

}

}

运行后结果

--------------------普通字符的URL加密--------------------

范芳铭在做Urlencode测试,123456,加密之后

%E8%8C%83%E8%8A%B3%E9%93%AD%E5%9C%A8%E5%81%9AUrl+encode%E6%B5%8B%E8%AF%95%EF%BC%8C123456

--------------------安全字符的编码解码---------------------

plain:abc123_-.*

encoded:abc123_-.*

Safe chars URL encoding test:yes

Safe chars URL encoding test:yes

--------------------不安全字符的编码解码--------------------

plain:[email protected]#$%^&()+{}"\;:`,/[]

encoded:%7E%21%40%23%24%25%5E%26%28%29%2B%7B%7D%22%5C%3B%3A%60%2C%2F%5B%5D

Safe chars URL encoding test:no

Safechars URL encoding test:yes

时间: 2024-10-29 11:25:54

Apache commons 之 codec 深入学习以及URLCodec的相关文章

Apache commons lang工具类学习笔记(2)--StringUtils

StringUtils工具类具有对String具有简单而强大的处理能力,从检查空串到分割字符串,到生成格式化的字符串,使用都很方便简洁,能减少很多代码量; 详细的使用方法可以参考下面的例子或者官方的API(http://commons.apache.org/proper/commons-lang/javadocs/api-release/org/apache/commons/lang3/StringUtils.html#isAlpha(java.lang.CharSequence)) packa

Apache commons 之 codec 简介和入门代码

Java JDK有一个 java.security 的 package, 提供了 MessageDigest 的编码方式, Digest Algorithms 包括了 MD2, MD5, SHA-1, SHA-256, SHA-384, 及 SHA-512 等等: Codec 是Commons项目中用来处理常用的编码方法的工具类包,例如HEX.SHA1.MD5.Base64等等目前最新版本为1.4. Base64/HEX是对称加密,MD5是不可逆加密,千万要注意 一些简单的加密示例代码: pac

apache commons类库的学习

原文地址http://www.tuicool.com/articles/iyEbquE 1.1. 开篇 在Java的世界,有很多(成千上万)开源的框架,有成功的,也有不那么成功的,有声名显赫的,也有默默无闻的.在我看来,成功而默默无闻的那些框架值得我们格外的尊敬和关注,Jakarta Commons就是这样的一个框架.如果你至少参与了一个中型规模的Java项目,那么我想有超过一大半的机会你都接触和使用到了Jakarta Commons,不管你自己有没有察觉.就我所知,除了Apache Jakar

Apache commons codec 之language

Apache commons codec的language是一个功能比较强大的包,主要是用在对各种语言的处理上,当然,这个包对汉字的支持很糟糕.这一块的内容,在网上非常少,只能自己写一些挺肤浅的代码,以后如果有机会接触,再完善. 我们先学习下编码的范例. Examples of Soundex Coding Name                Letters Coded       Coding Allricht            l, r, c             A-462 Eb

ANDROID : java.lang.NoSuchMethodError: org.apache.commons.codec.binary.Base64.encodeBase64String in android

Andriod系统包中现在已经自带加密函数,如果用apache的codec包则会报以上错误,用android.util.Base64以下方法代替org.apache.commons.codec.binary.Base64 --- String str = Base64.encodeBase64String(byte[] data); ---byte[] data = Base64.decodeBase64(String str); android.util.Base64 ---String st

Apache Commons Codec 编码解码

Apache Commons Codec jar包官方下载地址 下载解压后把commons-codec-1.9.jar 放到lib中 关于SHA1算法的介绍可以参看Wiki:http://en.wikipedia.org/wiki/SHA-1 这里简单介绍一下通过 Apache Commons Codec 实现Base64/MD5/SHA1/SHA256等算法,代码如下: package com.ricky.java.csv.util; import org.apache.commons.cod

Apache Commons Codec 与消息摘要算法(hash算法)

首先我们要明白 Codec 是什么含义.它是 Coder + decoder = Codec,也就是编码器解码器.即是编码器,也是解码器. 官网地址:http://commons.apache.org/proper/commons-codec/ Apache Commons Codec (TM) software provides implementations of common encoders and decoders such as Base64, Hex, Phonetic and U

Java加密工具类(依赖:java.security.MessageDigest或org.apache.commons.codec.digest.DigestUtils)

依赖于java.security.MessageDigest,支持MD5,SHA-1,SHA-256 1 import java.security.MessageDigest; 2 import java.security.NoSuchAlgorithmException; 3 4 /** 5 * CiphertextUtil 6 * 7 * @author ysj 8 */ 9 public class CiphertextUtil { 10 public static final Strin

java.lang.IllegalAccessError: tried to access method org.apache.commons.codec.digest.DigestUtils.getDigest(Ljava/lang/String;)Ljava/security/MessageDigest; from class com.xyb.mis.pay.jingdong.util.Sig

严重: Servlet.service() for servlet [springmvc] in context with path [/xyb-mis-web] threw exception [Handler processing failed; nested exception is java.lang.IllegalAccessError: tried to access method org.apache.commons.codec.digest.DigestUtils.getDige