在Android / Java中使用JSON / Base64编码文件

时间:2017-02-20 19:03:05

标签: java android json http inputstream

我有一个能够以两种方式返回PDF文件的Web服务:

RAW :该文件只包含在响应正文中。例如:

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

<file_contents>

JSON :文件已编码(Base 64)并作为JSON提供,具有以下结构:

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

{
  "base64": <file_contents_base64>
}

我希望能够使用以下架构在Android / Java上使用这两种服务:

// 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);

对于第一种情况( RAW 响应),响应正文将是文件本身。这意味着getPDFFileContentsInputStream(InputStream)方法实现很简单:

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

问题是:如何为第二种情况(JSON响应)实施getPDFFileContentsInputStream(InputStream)方法?

1 个答案:

答案 0 :(得分:1)

您可以使用任何json解析器(如Jackson或Gson),然后使用apache-commons编解码器中的Base64InputStream

编辑:您可以使用ByteArrayInputStream从字符串中获取输入流,即

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

here所述。

编辑2:这将导致2次传递数据,如果文件很大,则可能存在内存问题。要解决它,你可以使用Jackson并自己解析内容,如this示例,而不是通过反射获取整个对象。你可以将原始输入流包装在另一个中,比如{{1这将跳过底层输入流中的数据,直到编码部分。然后,您可以将此ExtractingInputStream实例包装在ExtractingInputStream中。跳过不必要部分的简单算法如下:在Base64InputStream的构造函数中,跳过直到读过三个引号。在read方法中,返回基础流返回的内容,但如果基础流返回引号,则返回-1,该引号对应于base 64编码数据的结尾。