【问题标题】:java.lang.IllegalArgumentException: Illegal base64 character -1java.lang.IllegalArgumentException:非法base64字符-1
【发布时间】:2019-12-11 07:52:37
【问题描述】:
我正在通过 Android 应用程序将 byte[] 作为编码字符串发送。我转换 byte[] 的方式如下(基本上 byte[] 是 thumbscan/fingerscan 图像):Android
byte[] imageData = m_left_enrollment_fmd(); // returns byte[] which is OK!
// Base64 belongs to android.util package
String forJson = Base64.encodeToString(imageData , Base64.DEFAULT);
这就是我在服务器端解码它的方式(Java):
// Base64 belongs to java.util package
byte[] imageData = Base64.getDecoder().decode(sqlJsonParams.optString("IMAGE_DATA"));
它会产生以下异常:
]] ServletException 的根本原因。
java.lang.IllegalArgumentException:非法 base64 字符 -1
在 java.util.Base64$Decoder.decode0(Base64.java:714)
在 java.util.Base64$Decoder.decode(Base64.java:526)
在 java.util.Base64$Decoder.decode(Base64.java:549)
在 org.skm.webresources.mobilehis.v2.Fingerprint.getByteArray(Fingerprint.java:470)
在 org.skm.webresources.mobilehis.v2.Fingerprint.postFingerprint(Fingerprint.java:86)
截断。查看完整堆栈跟踪的日志文件
-
问题 1:我做错了什么?
-
问题2: REST Service中发送byte[]的方式是否正确?
目前看到的Q&A如下:
【问题讨论】:
标签:
java
android
arrays
base64
【解决方案1】:
我已将图像作为多部分发送,也许会有所帮助:
ArrayList<MultipartBody.Part> list = new ArrayList<>();
File photo = new File(image_uri);
RequestBody file = RequestBody.create(MediaType.parse(getMimeType(photo.getAbsolutePath())), photo);
MultipartBody.Part partImage = MultipartBody.Part.createFormData("image", photo.getName(), file);
list.add(partImage);
Call<Void> call = api.uploadMyImage(agreement, list, "@");
getMimeType():
public static String getMimeType(String url) {
String type = null;
String extension = MimeTypeMap.getFileExtensionFromUrl(url);
if (extension != null){
type = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension);
}
return type;
}
到 Base64:
public static String convertToBase64(String path) {
Bitmap bm = BitmapFactory.decodeFile(path);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bm.compress(Bitmap.CompressFormat.PNG, 100, baos);
byte[] byteArrayImage = baos.toByteArray();
String encodedImage = android.util.Base64.encodeToString(byteArrayImage, android.util.Base64.DEFAULT);
return encodedImage;
}
【解决方案2】:
我也遇到了这个问题。查看 Android 和 Java 的 base64 API,它们都遵循 RFC 2045,但 Java 的版本也遵循 RFC 4846,其中有一个小问题:
MIME [4] 通常用作 base 64 编码的参考。
但是,MIME 本身并没有定义“base 64”,而是定义了“base 64”。
64 Content-Transfer-Encoding”,用于在 MIME 中使用。因此,MIME
将 base 64 编码数据的行长度限制为 76
人物。 MIME 从 Privacy Enhanced Mail 继承编码
(PEM) [3],声明它“几乎相同”;然而,PEM
使用 64 个字符的行长。 MIME 和 PEM 限制为
都是由于 SMTP 的限制。
实现不得在基本编码数据中添加换行符,除非
引用本文档的规范明确指示 base
编码器在特定数量的字符后添加换行符。
您的 Android 的 base64 编码器正在在 76 个字符后进行换行,而 Java 的编码器则完全不需要换行。在 Android 端处理这个问题的方法是使用 no_wrap 选项,然后你的 Java 服务器可以读取它:
String forJson = Base64.encodeToString(imageData , Base64.NO_WRAP);
现在可以正常阅读了。这是选项 Base64.DEFAULT 的输出:
ZI4069Ue3D5Ikbp93eJ/r6HQG3CPj3FxGE1SoywcgCuaJ0t5M/D79utSyF1Uf7C7NHdQ9fGuHQ2P\nJnNpsHAEpA==
相对于 Base64.NO_WRAP 的输出:
ZI4069Ue3D5Ikbp93eJ/r6HQG3CPj3FxGE1SoywcgCuaJ0t5M/D79utSyF1Uf7C7NHdQ9fGuHQ2PJnNpsHAEpA==