如何使用org.apache.commons.codec.binary.base64对Java对象进行Base64编码?

15

我一直在尝试进行对象序列化并对结果进行Base64编码。使用Sun的库可以实现:

Bean01 bean01 = new Bean01();
bean01.setDefaultValues();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
new ObjectOutputStream( baos ).writeObject( bean01 );
System.out.println(Base64.encode(baos.toByteArray()));

这个可以正常工作。但是,我希望使用org.apache.commons.codec.binary.base64做同样的事情,但是它没有返回相同的字符串:

System.out.println(org.apache.commons.codec.binary.Base64.encodeBase64(baos.toByteArray()));

如何才能正确地使用Apache的编码器对byteArray进行正确的Base64编码?


你在第一个示例中使用了“sun的lib”中的哪个Base64类? - QuantumMechanic
com.sun.org.apache.xerces.internal.impl.dv.util.Base64 - Ta Sas
2个回答

25
实际上,您使用的 commons-codec 版本和特定的 Sun 内部版本确实会给出相同的结果。我认为您之前认为它们会给出不同的版本是因为在执行以下代码时隐式地对数组调用了 toString() 方法:
System.out.println(org.apache.commons.codec.binary.Base64.encodeBase64(baos.toByteArray()));

这绝对不会打印出数组的内容,而只会打印出数组引用的地址。

我编写了以下程序来测试编码器之间的差异。从下面的输出可以看出它们给出相同的结果:

import java.util.Random;

public class Base64Stuff
{
    public static void main(String[] args) {
        Random random = new Random();
        byte[] randomBytes = new byte[32];
        random.nextBytes(randomBytes);

        String internalVersion = com.sun.org.apache.xerces.internal.impl.dv.util.Base64.encode(randomBytes);
        byte[] apacheBytes =  org.apache.commons.codec.binary.Base64.encodeBase64(randomBytes);
        String fromApacheBytes = new String(apacheBytes);

        System.out.println("Internal length = " + internalVersion.length());
        System.out.println("Apache bytes len= " + fromApacheBytes.length());
        System.out.println("Internal version = |" + internalVersion + "|");
        System.out.println("Apache bytes     = |" + fromApacheBytes + "|");
        System.out.println("internal equal apache bytes?: " + internalVersion.equals(fromApacheBytes));
    }
}

以下是运行它的输出结果:

Internal length = 44
Apache bytes len= 44
Internal version = |Kf0JBpbxCfXutxjveYs8CXMsFpQYgkllcHHzJJsz9+g=|
Apache bytes     = |Kf0JBpbxCfXutxjveYs8CXMsFpQYgkllcHHzJJsz9+g=|
internal equal apache bytes?: true

2

commons-codec主页

Codec项目的成立旨在将开发工作集中在一个确定的Base64编码器实现上。在Codec提出时,Foundation的CVS存储库中有大约34个不同的Java类来处理Base64编码。Jakarta Tomcat项目的开发人员已经实现了Base64编解码器的原始版本,并被Commons HttpClient和Apache XML项目的XML-RPC子项目复制。但是,在将近一年的时间里,这两个派生版本的Base64相互分离。XML-RPC已经应用了许多修补程序和补丁,而这些都没有应用到Commons HttpClient Base64中。不同的子项目在RFC 2045的各个级别上具有不同的实现。

我认为你们的问题是“不同级别”的兼容性。

我的建议:选择一个Base64编码器/解码器并坚持使用它。


我想要,除了一个不能进行的标准,我对sun很满意:http://www.techiegyan.com/2009/01/11/warning-sunmiscbase64encoder-is-sun-proprietary-api-and-may-be-removed-in-a-future-release/。这就是为什么我必须转换,尽管我不想这样做。 - Ta Sas
2
想要和需要常常分道扬镳,但是需求总是占据上风。 - David Harkness

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接