从sun.misc.BASE64迁移到Java 8 java.util.Base64 [英] Migrating from sun.misc.BASE64 to Java 8 java.util.Base64
问题描述
问题
Java 8 java.util.Base64
MIME编码器和解码器是否是不受支持的内部Java API sun.misc.BASE64Encoder
和sun.misc.BASE64Decoder
的直接替代 ?>
我到目前为止的想法以及原因
根据我的调查和快速测试(请参见下面的代码) 它应该是直接替代品 ,因为
-
根据其JavaDoc的
-
sun.misc.BASE64Encoder
是 RFC1521 中指定的BASE64字符编码器.该RFC是 MIME 规范的一部分... -
java.util.Base64
基于其 JavaDoc 使用 RFC 2045 表1中指定的"Base64字母"进行 MIME >
假设RFC 1521和2045中没有重大更改(我找不到任何更改),并且基于使用Java 8 Base64 MIME编码器/解码器的快速测试,应该没问题.
我在寻找什么
- 确认或反驳即插即用"要点的权威消息来源或
- 一个反例,显示java.util.Base64与sun.misc.BASE64Encoder具有不同行为的情况解决方案
下面是一个小型测试程序,它说明了编码字符串的不同之处:
byte[] bytes = new byte[57]; String enc1 = new sun.misc.BASE64Encoder().encode(bytes); String enc2 = new String(java.util.Base64.getMimeEncoder().encode(bytes), StandardCharsets.UTF_8); System.out.println("enc1 = <" + enc1 + ">"); System.out.println("enc2 = <" + enc2 + ">"); System.out.println(enc1.equals(enc2));
其输出是:
enc1 = <AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA > enc2 = <AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA> false
请注意,
sun.misc.BASE64Encoder
的编码输出在末尾有换行符.它不会总是附加一个换行符,但是如果编码字符串的最后一行恰好有76个字符,它就会这样做. (java.util.Base64
的作者认为这是sun.misc.BASE64Encoder
实现中的一个小错误–请参阅JavaDoc Uses the "The Base64 Alphabet" as specified in Table 1 of RFC 2045 for encoding and decoding operation... under MIME
Assuming no significant changes in the RFC 1521 and 2045 (I could not find any) and based on my quick test using the Java 8 Base64 MIME Encoder/Decoder should be fine.
What I am looking for
- an authoritative source confirming or disproving the "drop-in replacement" point OR
- a counterexample which shows a case where java.util.Base64 has different behaviour than the sun.misc.BASE64Encoder OpenJDK Java 8 implementation (8u40-b25) (BASE64Decoder) OR
- whatever you think answers above question definitely
For reference
My test code
public class Base64EncodingDecodingRoundTripTest {
public static void main(String[] args) throws IOException {
String test1 = " ~!@#$%^& *()_+=`| }{[]\\;: \"?><,./ ";
String test2 = test1 + test1;
encodeDecode(test1);
encodeDecode(test2);
}
static void encodeDecode(final String testInputString) throws IOException {
sun.misc.BASE64Encoder unsupportedEncoder = new sun.misc.BASE64Encoder();
sun.misc.BASE64Decoder unsupportedDecoder = new sun.misc.BASE64Decoder();
Base64.Encoder mimeEncoder = java.util.Base64.getMimeEncoder();
Base64.Decoder mimeDecoder = java.util.Base64.getMimeDecoder();
String sunEncoded = unsupportedEncoder.encode(testInputString.getBytes());
System.out.println("sun.misc encoded: " + sunEncoded);
String mimeEncoded = mimeEncoder.encodeToString(testInputString.getBytes());
System.out.println("Java 8 Base64 MIME encoded: " + mimeEncoded);
byte[] mimeDecoded = mimeDecoder.decode(sunEncoded);
String mimeDecodedString = new String(mimeDecoded, Charset.forName("UTF-8"));
byte[] sunDecoded = unsupportedDecoder.decodeBuffer(mimeEncoded); // throws IOException
String sunDecodedString = new String(sunDecoded, Charset.forName("UTF-8"));
System.out.println(String.format("sun.misc decoded: %s | Java 8 Base64 decoded: %s", sunDecodedString, mimeDecodedString));
System.out.println("Decoded results are both equal: " + Objects.equals(sunDecodedString, mimeDecodedString));
System.out.println("Mime decoded result is equal to test input string: " + Objects.equals(testInputString, mimeDecodedString));
System.out.println("\n");
}
}
Here's a small test program that illustrates a difference in the encoded strings:
byte[] bytes = new byte[57];
String enc1 = new sun.misc.BASE64Encoder().encode(bytes);
String enc2 = new String(java.util.Base64.getMimeEncoder().encode(bytes),
StandardCharsets.UTF_8);
System.out.println("enc1 = <" + enc1 + ">");
System.out.println("enc2 = <" + enc2 + ">");
System.out.println(enc1.equals(enc2));
Its output is:
enc1 = <AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
>
enc2 = <AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA>
false
Note that the encoded output of sun.misc.BASE64Encoder
has a newline at the end. It doesn't always append a newline, but it happens to do so if the encoded string has exactly 76 characters on its last line. (The author of java.util.Base64
considered this to be a small bug in the sun.misc.BASE64Encoder
implementation – see the review thread).
This might seem like a triviality, but if you had a program that relied on this specific behavior, switching encoders might result in malformed output. Therefore, I conclude that java.util.Base64
is not a drop-in replacement for sun.misc.BASE64Encoder
.
Of course, the intent of java.util.Base64
is that it's a functionally equivalent, RFC-conformant, high-performance, fully supported and specified replacement that's intended to support migration of code away from sun.misc.BASE64Encoder
. You need to be aware of some edge cases like this when migrating, though.
这篇关于从sun.misc.BASE64迁移到Java 8 java.util.Base64的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!