我有一个能够以两种方式返回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)
方法?
答案 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编码数据的结尾。