我是通过将其作为参考来编写一个非常简单的代理servlet。我想要o添加缓存功能,其中缓存中的键是URI。
当然,问题是我无法缓存整个响应,因为如果我通过管道将输入流传递,则将消耗输入流,然后缓存的流程将不再可用。
您认为最好的方法是什么?我如何复制httpresponse(或仅仅是httpentity(用来消耗其内容的内容?
InputStream
除非另有说明,否则是单次拍摄:您一次消耗它。
如果您想多次阅读它,这不仅仅是流,它是带有缓冲区的流。要缓存输入流,您应该将响应内容写入文件或内存中,因此您可以再次阅读(多次(。
HTTPEntity
可以重新阅读,但取决于实现的类型。例如,您可以使用.isRepeatable()
进行检查。这是Apache的原始Javadoc。
流式:内容是从流中接收的,或者即时生成的。特别是,此类别包括从连接收到的实体。流式实体通常不可重复。
自包含的:内容在内存中或通过独立于连接或其他实体获得的方式获得。独立的实体通常是可重复的。
包装:内容是从另一个实体获得的。
您可以使用FileEntity
,即 subvented ,因此可重复(可重读(。
要存档此(缓存到文件中(,您可以读取HTTPEntity
的内容并将其写入File
。之后,您可以使用File
创建一个FileEntity
,我们以前创建和编写。最后,您只需要用新的FileEntity
替换HTTPResponse
的实体即可。
这是一个没有上下文的简单示例:
// Get the untouched entity from the HTTPResponse
HttpEntity originalEntity = response.getEntity();
// Obtain the content type of the response.
String contentType = originalEntity.getContentType().getElements()[0].getValue();
// Create a file for the cache. You should hash the the URL and pass it as the filename.
File targetFile = new File("/some/cache/folder/{--- HERE the URL in HASHED form ---}");
// Copy the input stream into the file above.
FileUtils.copyInputStreamToFile(originalEntity.getContent(), targetFile);
// Create a new Entity, pass the file and the replace the HTTPResponse's entity with it.
HttpEntity newEntity = new FileEntity(targetFile, ContentType.getByMimeType(contentType));
response.setEntity(newEntity);
现在,您可以将来一次又一次地重新阅读文件中的内容。
您只需要基于uri :)
要在内存中缓存您可以使用ByteArrayEntity
。
这种方法只是缓存身体。不是HTTP标题。
更新:替代
或者您可以使用 Apache HttpClient Cache 。
https://hc.apache.org/httpcomponents-client-ga/tutorial/html/caching.html