0

I am sending byte[] as encoded string through Android app. They way I am converting my byte[] is as follows (Basically byte[] is the thumbscan/fingerscan image): 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);

And this is how I am decoding it on Server side (Java):

// Base64 belongs to java.util package
byte[] imageData = Base64.getDecoder().decode(sqlJsonParams.optString("IMAGE_DATA"));

It generates following exception:

]] Root cause of ServletException. java.lang.IllegalArgumentException: Illegal base64 character -1 at java.util.Base64$Decoder.decode0(Base64.java:714) at java.util.Base64$Decoder.decode(Base64.java:526) at java.util.Base64$Decoder.decode(Base64.java:549) at org.skm.webresources.mobilehis.v2.Fingerprint.getByteArray(Fingerprint.java:470) at org.skm.webresources.mobilehis.v2.Fingerprint.postFingerprint(Fingerprint.java:86) Truncated. see log file for complete stacktrace

  • Question 1: What I am doing wrong?
  • Question 2: Is it the correct way to send byte[] in REST Service?

The Q&A I have seen so far are as follows:

2 Answers 2

0

I've sent images as multipart, maybe it will help:

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;
    }

to 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;
    }
Sign up to request clarification or add additional context in comments.

Comments

0

I ran into this issue as well. Looking at Android and Java's base64 API's, they both follow RFC 2045 but Java's version also follows RFC 4846 which has this small catch:

MIME [4] is often used as a reference for base 64 encoding. However, MIME does not define "base 64" per se, but rather a "base 64 Content- Transfer-Encoding" for use within MIME. As such, MIME enforces a limit on line length of base 64-encoded data to 76 characters. MIME inherits the encoding from Privacy Enhanced Mail (PEM) [3], stating that it is "virtually identical"; however, PEM uses a line length of 64 characters. The MIME and PEM limits are both due to limits within SMTP.

Implementations MUST NOT add line feeds to base-encoded data unless the specification referring to this document explicitly directs base
encoders to add line feeds after a specific number of characters.

Your Android's base64 encoder is doing a line feed after 76 characters while Java's encoder is expecting no line feeds at all. The way to handle this on Android's side is to use the no_wrap option and then it can be read by your Java server:

String forJson = Base64.encodeToString(imageData , Base64.NO_WRAP);

Now it will read fine. This is the output of option Base64.DEFAULT:

ZI4069Ue3D5Ikbp93eJ/r6HQG3CPj3FxGE1SoywcgCuaJ0t5M/D79utSyF1Uf7C7NHdQ9fGuHQ2P\nJnNpsHAEpA==

versus the output of Base64.NO_WRAP:

ZI4069Ue3D5Ikbp93eJ/r6HQG3CPj3FxGE1SoywcgCuaJ0t5M/D79utSyF1Uf7C7NHdQ9fGuHQ2PJnNpsHAEpA==

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.