在Android / Java中使用JSON / Base64编码文件
我有一个Web服务能够以两种方式返回PDF文件:
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)
方法?
您可以使用任何json解析器(如Jackson或Gson),然后使用apache-commons编解码器中的Base64InputStream
。
编辑:你可以从字符串使用ByteArrayInputStream
,即获得输入流
InputStream stream = new ByteArrayInputStream(exampleString.getBytes(StandardCharsets.UTF_8));
如此处所述。
编辑2:这将导致数据2通过,如果文件很大,则可能有内存问题。 为了解决这个问题,你可以使用Jackson并且像这个例子一样解析内容,而不是通过反射来获取整个对象。 你可以将原始输入流换成另一个输入流,比如说ExtractingInputStream
,这会跳过底层输入流中的数据直到编码部分。 然后,您可以将此ExtractingInputStream
实例包装在Base64InputStream
。 一个简单的算法可以跳过不必要的部分,如下所示:在ExtractingInputStream
的构造函数中,跳过直到读完三个引号。 在read方法中,返回基础流返回的内容,除非返回-1,否则基础流将返回引号,该引号对应于基本64编码数据的末尾。