Consume JSON / Base64 encoded file in Android / Java

I have a web service capable of returning PDF files in two ways:

RAW : The file is simply included in the response body. For example:

HTTP/1.1 200 OK
Content-Type: application/pdf

<file_contents>

JSON : The file is encoded (Base 64) and served as a JSON with the following structure:

HTTP/1.1 200 OK
Content-Type: application/json

{
  "base64": <file_contents_base64>
}

I want to be able to consume both services on Android / Java by using the following architecture:

// Get response body input stream (OUT OF THE SCOPE OF THIS QUESTION)
InputStream bodyStream = getResponseBodyInputStream();

// Get PDF file contents input stream from body stream
InputStream fileStream = getPDFFileContentsInputStream(bodyStream);

// Write stream to a local file (OUT OF THE SCOPE OF THIS QUESTION)
saveToFile(fileStream);

For the first case ( RAW response), the response body will the file itself. This means that the getPDFFileContentsInputStream(InputStream) method implementation is trivial:

@NonNull InputStream getPDFFileContentsInputStream(@NonNull InputStream bodyStream) {
    // Return the input
    return bodyStream;
}

The question is: how to implement the getPDFFileContentsInputStream(InputStream) method for the second case (JSON response)?


You can use any json parser (like Jackson or Gson), and then use Base64InputStream from apache-commons codec.

EDIT: You can obtain an input stream from string using ByteArrayInputStream , ie

InputStream stream = new ByteArrayInputStream(exampleString.getBytes(StandardCharsets.UTF_8));

as stated here.

EDIT 2: This will cause 2 pass over the data, and if the file is big, you might have memory problems. To solve it, you can use Jackson and parse the content yourself like this example instead of obtaining the whole object through reflection. you can wrap original input stream in another one, say ExtractingInputStream , and this will skip the data in the underlying input stream until the encoded part. Then you can wrap this ExtractingInputStream instance in a Base64InputStream . A simple algorithm to skip unnecessary parts would be like this: In the constructor of ExtractingInputStream , skip until you have read three quotation marks. In read method, return what underlying stream returns except return -1 if the underlying stream returns quotation mark, which corresponds to the end of base 64 encoded data.

链接地址: http://www.djcxy.com/p/78478.html

上一篇: 在android中将XML字符串转换为流

下一篇: 在Android / Java中使用JSON / Base64编码文件