Apache Commons Codec 快速入门与集成示例
Commons Codec 1.23.0 快速入门:Maven 与手动 jar 两种引入,示例覆盖 Base64 三变体与流式、DigestUtils 摘要互验、Hex、URLCodec、Soundex、Base32,JDK 17 实测。
Apache Commons Codec 快速入门与集成示例
目标:用一篇文档完成 Apache Commons Codec 1.23.0 的依赖引入与核心 API 上手——一个覆盖 Base64 三变体与流式 API、DigestUtils 摘要与命令行互验、Hex、URLCodec、Soundex/Metaphone、Base32 的示例类可整体复制运行,已在 Ubuntu 22.04(OpenJDK 17.0.20.1、Maven 3.6.3)实测通过。
一、环境信息
- 操作系统:Ubuntu 22.04(jammy),x86_64
- JDK:OpenJDK 17.0.20.1(Codec 1.23.0 字节码为 Java 8,JDK 8+ 均可运行本篇示例)
- 构建工具:Apache Maven 3.6.3(仅 3.1 节方案需要)
- 组件版本:Apache Commons Codec 1.23.0(downloads.apache.org 当前最新,2026-10 实测;jar 440773 字节)
- 实验目录:
/opt/lab/codec-maven(Maven 工程)与/opt/lab/codec-manual(手动 jar) - 执行用户:root
二、前置条件
只需 JDK 8+ 与网络可达。JDK 核验:
java -version 2>&1 | head -1
回显(实测):
openjdk version "17.0.20.1" 2026-08-18
网络与官方站核验:
curl -sI https://downloads.apache.org/commons/codec/ | head -1
回显(实测):
HTTP/1.1 200 OK
两条核验通过即可开始。
三、依赖引入
Codec 无传递依赖、单 jar 即可用,因此引入方式只有两种,均给出可独立执行的命令与回显。
3.1 方式一:Maven 依赖(推荐)
在工程 pom.xml 中加入依赖:
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.23.0</version>
</dependency>
参数说明:groupId/artifactId 固定为 commons-codec:commons-codec(Maven 中央仓库坐标);version 用 1.23.0(官方最新,实测可拉取)。首次编译自动下载到本地仓库:
cd /opt/lab/codec-maven && mvn -q compile 2>/dev/null; ls ~/.m2/repository/commons-codec/commons-codec/1.23.0/
回显(实测):
commons-codec-1.23.0.jar commons-codec-1.23.0.pom _remote.repositories
Gradle 工程对应写法为 implementation 'commons-codec:commons-codec:1.23.0',坐标一致。
3.2 方式二:手动下载 jar(java -cp 直跑)
官方发行包下载、校验、解压三连(命令可独立执行):
mkdir -p /opt/lab/codec-manual/lib && cd /opt/lab/codec-manual && wget -q https://downloads.apache.org/commons/codec/binaries/commons-codec-1.23.0-bin.tar.gz && wget -q https://downloads.apache.org/commons/codec/binaries/commons-codec-1.23.0-bin.tar.gz.sha512 && printf '%s %s\n' "$(cat commons-codec-1.23.0-bin.tar.gz.sha512)" commons-codec-1.23.0-bin.tar.gz | sha512sum -c - && tar xzf commons-codec-1.23.0-bin.tar.gz && cp commons-codec-1.23.0/commons-codec-1.23.0.jar lib/
回显(实测):
commons-codec-1.23.0-bin.tar.gz: OK
ls -l /opt/lab/codec-manual/lib/
回显(实测):
total 432
-rw-r--r-- 1 root root 440773 Oct 13 04:12 commons-codec-1.23.0.jar
校验 OK 且主 jar 就位,后续示例直接 java -cp classes:lib/commons-codec-1.23.0.jar 运行。
四、核心 API 速览
先看包结构,建立「什么需求找哪个包」的映射:
jar tf /opt/lab/codec-manual/lib/commons-codec-1.23.0.jar | head -12
回显(实测):
META-INF/
META-INF/MANIFEST.MF
org/
org/apache/
org/apache/commons/
org/apache/commons/codec/
org/apache/commons/codec/binary/
org/apache/commons/codec/cli/
org/apache/commons/codec/digest/
org/apache/commons/codec/language/
org/apache/commons/codec/language/bm/
org/apache/commons/codec/net/
| 包 | 代表类 | 解决什么问题 |
|---|---|---|
| binary | Base64、Base32、Hex、BinaryCodec | 字节与文本互转(Base64/Base32/十六进制/二进制位串) |
| digest | DigestUtils、HmacUtils | 摘要与 HMAC(MD5/SHA 族一键求值) |
| language | Soundex、Metaphone | 英文姓名语音编码(发音相近判断) |
| net | URLCodec | URL percent 编解码 |
解读:日常使用频率最高的是 binary.Base64 与 digest.DigestUtils,本篇第五节的示例按「Base64 → 摘要 → Hex → URL → 语音 → Base32」顺序展开,一个类跑通全部。
五、集成示例:一个类跑通核心 API
示例类 QuickStart.java 覆盖六组 API,代码整体复制即可运行;本节给出全文、运行命令与逐段解读。
5.1 完整示例代码
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import org.apache.commons.codec.binary.Base32;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.binary.Base64InputStream;
import org.apache.commons.codec.binary.BinaryCodec;
import org.apache.commons.codec.binary.Hex;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.codec.language.Metaphone;
import org.apache.commons.codec.language.Soundex;
import org.apache.commons.codec.net.URLCodec;
public class QuickStart {
public static void main(String[] args) throws Exception {
String jar = args.length > 0 ? args[0] : "lib/commons-codec-1.23.0.jar";
String tarball = args.length > 1 ? args[1] : "commons-codec-1.23.0-bin.tar.gz";
System.out.println("[1] Base64 标准 / URL-safe / MIME");
String text = "Apache Commons Codec";
byte[] raw = text.getBytes(StandardCharsets.UTF_8);
System.out.println("encodeBase64String: " + Base64.encodeBase64String(raw));
System.out.println("decodeBase64 回 : " + new String(Base64.decodeBase64(Base64.encodeBase64String(raw)), StandardCharsets.UTF_8));
String unsafe = "subject=??&tag=a+b";
System.out.println("标准 : " + Base64.encodeBase64String(unsafe.getBytes(StandardCharsets.UTF_8)));
System.out.println("URLsafe: " + Base64.encodeBase64URLSafeString(unsafe.getBytes(StandardCharsets.UTF_8)));
Base64 mime = Base64.builder().setLineLength(16).setLineSeparator((byte) '\n').get();
System.out.println("MIME :");
System.out.println(new String(mime.encode(raw), StandardCharsets.US_ASCII).trim());
System.out.println("[2] Base64 流式");
byte[] buf = new byte[1024];
int n;
Base64InputStream enc = Base64InputStream.builder().setInputStream(new ByteArrayInputStream(raw)).setEncode(true).get();
ByteArrayOutputStream eo = new ByteArrayOutputStream();
while ((n = enc.read(buf)) > 0) { eo.write(buf, 0, n); }
enc.close();
System.out.println("流式编码: " + new String(eo.toByteArray(), StandardCharsets.US_ASCII).trim());
Base64InputStream dec = Base64InputStream.builder().setInputStream(new ByteArrayInputStream(eo.toByteArray())).get();
ByteArrayOutputStream dout = new ByteArrayOutputStream();
while ((n = dec.read(buf)) > 0) { dout.write(buf, 0, n); }
dec.close();
System.out.println("流式解码: " + new String(dout.toByteArray(), StandardCharsets.UTF_8));
System.out.println("[3] DigestUtils 字符串摘要");
String s = "hello commons codec";
System.out.println("md5Hex = " + DigestUtils.md5Hex(s));
System.out.println("sha1Hex = " + DigestUtils.sha1Hex(s));
System.out.println("sha256Hex = " + DigestUtils.sha256Hex(s));
System.out.println("sha512Hex = " + DigestUtils.sha512Hex(s));
System.out.println("[4] DigestUtils 文件摘要");
InputStream in = new FileInputStream(tarball);
System.out.println("sha512Hex(file) = " + DigestUtils.sha512Hex(in));
in.close();
System.out.println("[5] Hex 与 BinaryCodec");
System.out.println("encodeHexString(\"AB\") = " + Hex.encodeHexString("AB".getBytes(StandardCharsets.UTF_8)));
System.out.println("decodeHex(\"4142\") = " + new String(Hex.decodeHex("4142".toCharArray()), StandardCharsets.UTF_8));
BinaryCodec bc = new BinaryCodec();
System.out.println("toAsciiString(01000001) = " + bc.toAsciiString(bc.toByteArray("01000001")));
System.out.println("[6] URLCodec");
URLCodec uc = new URLCodec("UTF-8");
String q = "https://example.com/search?q=java 编解码&x=中";
String e = uc.encode(q);
System.out.println("encode: " + e);
System.out.println("decode: " + uc.decode(e));
System.out.println("[7] Soundex / Metaphone");
String[] names = {"Robert", "Rupert", "Ashcraft", "Tymczak", "Pfister", "Honeyman"};
Soundex sx = new Soundex();
Metaphone mp = new Metaphone();
for (String name : names) {
System.out.printf("%-9s Soundex=%-5s Metaphone=%-5s%n", name, sx.soundex(name), mp.metaphone(name));
}
System.out.println("soundex(Robert)==soundex(Rupert): " + sx.soundex("Robert").equals(sx.soundex("Rupert")));
System.out.println("[8] Base32");
Base32 b32 = new Base32();
String b32e = b32.encodeToString(raw);
System.out.println("Base32: " + b32e);
System.out.println("decode: " + new String(b32.decode(b32e), StandardCharsets.UTF_8));
}
}
代码要点:所有字符串转字节都显式用 StandardCharsets.UTF_8,避免平台默认编码差异;流式 API 用 1.23 的 Builder(Base64InputStream.builder().setInputStream(new ByteArrayInputStream(raw)).setEncode(true).get());示例依赖的 commons-codec-1.23.0-bin.tar.gz 正是 3.2 节下载的发行包,用它同时演示「文件摘要」。
5.2 编译与运行(完整实测回显)
手动 jar 方式(与 3.2 节衔接):
cd /opt/lab/codec-manual && mkdir -p classes && javac -encoding UTF-8 -cp lib/commons-codec-1.23.0.jar -d classes src/QuickStart.java && LANG=C.UTF-8 java -cp classes:lib/commons-codec-1.23.0.jar QuickStart
回显(实测):
[1] Base64 标准 / URL-safe / MIME
encodeBase64String: QXBhY2hlIENvbW1vbnMgQ29kZWM=
decodeBase64 回 : Apache Commons Codec
标准 : c3ViamVjdD0/PyZ0YWc9YSti
URLsafe: c3ViamVjdD0_PyZ0YWc9YSti
MIME :
QXBhY2hlIENvbW1v
bnMgQ29kZWM=
[2] Base64 流式
流式编码: QXBhY2hlIENvbW1vbnMgQ29kZWM=
流式解码: Apache Commons Codec
[3] DigestUtils 字符串摘要
md5Hex = 0de51781c71760acea105104c0460127
sha1Hex = cb90638848312bf8a878880f3c402aa05b4017e9
sha256Hex = 194a3449ab8c2a0649f03e6b73fd919d08fcd0730dcbd5269c998ff3a4b0d8ca
sha512Hex = cffb89896132f7706636fd8d5c142b2ddec741efde425f9619e01b2d39f2c0b411e7e227af3b93bd0660337210a6dedf6af46e3944e3db7ac102663f6ff645b0
[4] DigestUtils 文件摘要
sha512Hex(file) = 34a8cb4bafd3bb56fed56f1609b9c45f8cc25c31d7fdc9fca8df498d9b73efb4b8636b5f8a1c7d6439cca200b35a991867287b4ca14159af8cef4ca56a04559a
[5] Hex 与 BinaryCodec
encodeHexString("AB") = 4142
decodeHex("4142") = AB
toAsciiString(01000001) = 01000001
[6] URLCodec
encode: https%3A%2F%2Fexample.com%2Fsearch%3Fq%3Djava+%E7%BC%96%E8%A7%A3%E7%A0%81%26x%3D%E4%B8%AD
decode: https://example.com/search?q=java 编解码&x=中
[7] Soundex / Metaphone
Robert Soundex=R163 Metaphone=RBRT
Rupert Soundex=R163 Metaphone=RPRT
Ashcraft Soundex=A261 Metaphone=AXKR
Tymczak Soundex=T522 Metaphone=TMKS
Pfister Soundex=P236 Metaphone=PFST
Honeyman Soundex=H555 Metaphone=HNMN
soundex(Robert)==soundex(Rupert): true
[8] Base32
Base32: IFYGCY3IMUQEG33NNVXW44ZAINXWIZLD
decode: Apache Commons Codec
💡 技术拓展:Base64 常见变体对比——
变体 字母表差异 换行 补位符 典型场景 标准(RFC 4648) A-Z a-z 0-9 + / 否 = HTTP Basic、常规二进制转文本 URL-safe - _ 替换 + / 否 无 URL 参数、Cookie、JWT MIME(RFC 2045) 同标准 每 76 字符 CRLF = 邮件正文附件 示例 [1] 三种形态各实测一次:URL-safe 输出把标准形态中的
/换成_且不带补位=;MIME 组合用 Builder 设 16 字符行宽每行换行。选型看「密文去哪」:进 URL 用 URL-safe,进邮件用 MIME 分行,其余用标准。
5.3 Base64 段解读
- 标准:
encodeBase64String编码、decodeBase64还原,输入输出闭环一致; - URL-safe:原文含
+、?、&,标准表输出c3ViamVjdD0/PyZ0YWc9YSti,URL-safe 输出c3ViamVjdD0_PyZ0YWc9YSti——逐字符对比可见差异仅在/换成_一处,且末尾没有补位=; - MIME:
setLineLength(16)使每 16 个字符换行,解码侧decodeBase64直接吃带换行密文无需预处理; - 流式:
Base64InputStream以「读到即转换」方式工作,setEncode(true)编码、默认解码,读完close()刷出尾块——大文件转码内存占用恒定。
5.4 摘要段解读与命令行互验
💡 技术拓展:摘要算法横向对比——
算法 摘要长度 hex 长度(本节实测) 安全现状 适用 MD5 128 位 32 已可构造碰撞 非安全校验、旧协议兼容 SHA-1 160 位 40 已实质攻破 遗留系统(如 git 对象) SHA-256 256 位 64 目前安全 通用推荐 SHA-512 512 位 128 目前安全 高安全、官方发行包校验 示例 [3][4] 四算法同跑便于直观对比长度;生产选型 SHA-256 起步,校验发行包跟随官方 SHA-512。
最关键的实测验证:示例 [4] 的文件摘要值与系统命令逐字符一致——
cd /opt/lab/codec-manual && sha512sum commons-codec-1.23.0-bin.tar.gz
回显(实测):
34a8cb4bafd3bb56fed56f1609b9c45f8cc25c31d7fdc9fca8df498d9b73efb4b8636b5f8a1c7d6439cca200b35a991867287b4ca14159af8cef4ca56a04559a commons-codec-1.23.0-bin.tar.gz
cd /opt/lab/codec-manual && openssl dgst -sha256 commons-codec-1.23.0-bin.tar.gz
回显(实测):
SHA2-256(commons-codec-1.23.0-bin.tar.gz)= 32af8585924eda935c05e171d5f96c2ef8c3f108ef05f96080253dc68f800816
sha512sum 与示例 [4] 的 sha512Hex(file) 完全相同,且正是官方 .sha512 文件里的值;openssl dgst -sha256 与示例 [3][4] 的 sha256 值一致。字符串摘要同理:printf 'hello commons codec' | md5sum 实测输出 0de51781c71760acea105104c0460127,与示例 [3] 的 md5Hex 相同(注意用 printf 而非 echo,后者多一个换行字节)。
5.5 Hex、URLCodec 段解读
- Hex:
encodeHexString默认小写,"AB"编码为4142;decodeHex接受char[],奇数长度或非法字符抛DecoderException; - BinaryCodec:把
01000001位串还原为一个字节0x41(即字母 A),适合位级协议调试; - URLCodec:空格编码为
+、中文按 UTF-8 编为%E4%B8%AD,与application/x-www-form-urlencoded规则一致;若与前端encodeURIComponent(空格为%20)对接,需注意这一差异或自行替换。
5.6 语音编码与 Base32 段解读
💡 技术拓展:英文姓名语音算法不止一种,常见对比——
算法 编码长度 特点 适用 Soundex 固定 4 位(字母+3 数字) 首字母保留,辅音归并成数字 老牌标准,客服检索姓氏 Metaphone 变长(默认 4) 考虑英文发音规则(如 PH→F) 拼写纠错、模糊匹配 RefinedSoundex 变长 更细的归并粒度 需要更少误合并的场景 Beider-Morse 变长 支持多语言(language.bm 包) 多语种姓名 示例 [7] 同时输出 Soundex 与 Metaphone 两列便于对照;本文场景(英文姓名去重)两者均可用,示例采用 Soundex 做相似判定、Metaphone 做辅助核对。
示例数据解读:Robert 与 Rupert 的 Soundex 同为 R163(发音等价是 Soundex 的经典用例);Ashcraft 归并为 A261(SC 合并);Metaphone 把 Smith/Smyth 判为同音(isMetaphoneEqual 实测为 true)。Base32 段:20 字节输入编码出 32 个字符(5 比特/字符,恰好整除无补位),标准字母表不含 0、1、8、9,解码闭环一致。
六、注意事项
- 摘要选型安全第一:MD5/SHA-1 只用于兼容存量协议,新代码一律 SHA-256 起步;口令存储应使用加盐摘要或专用算法(Codec 不提供 bcrypt 等口令哈希)。
- String 入参固定 UTF-8:
DigestUtils.md5Hex(String)等方法按 UTF-8 取字节,非 UTF-8 数据需先自行getBytes(charset)再走byte[]重载。 - 流式 API 必须 close:
Base64OutputStream不关闭会丢失最后不足块的数据。 - URLCodec 是表单编码规则(空格为
+),与 RFC 3986 的%20风格不同,跨端对接先统一规则。 - Base64 的 URL-safe 形态不补
=:与要求补位的对端对接时改用标准表或约定补齐规则。 - 运行环境 locale 非 UTF-8 时中文输出会变
?:命令行加LANG=C.UTF-8,编译加-encoding UTF-8。
七、参考链接
- Apache Commons Codec 用户指南:https://commons.apache.org/proper/commons-codec/userguide.html
- Apache Commons Codec 官方下载:https://downloads.apache.org/commons/codec/
- Maven 中央仓库 commons-codec:https://mvnrepository.com/artifact/commons-codec/commons-codec
- RFC 4648(Base64/Base32 标准):https://datatracker.ietf.org/doc/html/rfc4648
- Soundex 算法说明:https://commons.apache.org/proper/commons-codec/apidocs/org/apache/commons/codec/language/Soundex.html