如何在RestController中缓存InputStreamResource?

成员之声

我有一个Servlet,返回的图像为InputStreamResource根据某些get query参数,将返回大约50张静态图像

由于不必在每次请求时都查找每个图像(这是很常见的),因此我想缓存这些图像响应。

@RestController
public class MyRestController {
    //code is just example; may be any number of parameters
    @RequestMapping("/{code}")
    @Cachable("code.cache")
    public ResponseEntity<InputStreamResource> getCodeLogo(@PathVariable("code") String code) {
        FileSystemResource file = new FileSystemResource("d:/images/" + code + ".jpg");
        return ResponseEntity.ok()
            .contentType("image/jpg")
            .lastModified(file.lastModified())
            .contentLength(file.contentLength())
            .body(new InputStreamResource(file.getInputStream()));

    }
}

使用@Cacheable注释时(无论是直接在RestMapping方法上还是重构到外部服务),I_都会收到以下异常:

cause: java.lang.IllegalStateException: InputStream has already been read - do not use InputStreamResource if a stream needs to be read multiple times - error: InputStream has already been read - do not use InputStreamResource if a stream needs to be read multiple times
org.springframework.core.io.InputStreamResource.getInputStream(InputStreamResource.java:96)
org.springframework.http.converter.ResourceHttpMessageConverter.writeInternal(ResourceHttpMessageConverter.java:100)
org.springframework.http.converter.ResourceHttpMessageConverter.writeInternal(ResourceHttpMessageConverter.java:47)
org.springframework.http.converter.AbstractHttpMessageConverter.write(AbstractHttpMessageConverter.java:195)
org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.writeWithMessageConverters(AbstractMessageConverterMethodProcessor.java:238)
org.springframework.web.servlet.mvc.method.annotation.HttpEntityMethodProcessor.handleReturnValue(HttpEntityMethodProcessor.java:183)
org.springframework.web.method.support.HandlerMethodReturnValueHandlerComposite.handleReturnValue(HandlerMethodReturnValueHandlerComposite.java:81)
org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:126)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:832)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:743)

问题:那么我该如何缓存ResponseEntity类型InputStreamResource的呢?

肯·贝科夫(Ken Bekov)

高速缓存管理器将添加到高速缓存ResponseEntityInputStreamResource它里面。第一次可以。但是当缓存ResponseEntity将尝试InputStreamResouce第二次读取时,您将获得异常,因为它无法多次读取流。

解决方案:不缓存InputStreamResouce自身,而是缓存流的内容。

@RestController
public class MyRestController {    
    @RequestMapping("/{code}")
    @Cachable("code.cache")
    public ResponseEntity<byte[]> getCodeLogo(@PathVariable("code") String code) {
        FileSystemResource file = new FileSystemResource("d:/images/" + code + ".jpg");

        byte [] content = new byte[(int)file.contentLength()];
        IOUtils.read(file.getInputStream(), content);

        return ResponseEntity.ok()
            .contentType(MediaType.IMAGE_JPEG)
            .lastModified(file.lastModified())
            .contentLength(file.contentLength())
            .body(content);
    }
}

我使用过IOUtils.read()from org.apache.commons.io,将字节从流复制到数组,但是您可以通过任何首选方式来实现。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

如何在 RestController 中映射嵌套的 JSON?

来自分类Dev

如何在ZODB中设置缓存大小?

来自分类Dev

如何在Guava缓存中存储地图

来自分类Dev

如何在Laravel中缓存模型属性

来自分类Dev

如何在fastcgi中取消Django缓存

来自分类Dev

如何在CPU中实现LRU缓存?

来自分类Dev

如何在jQuery中缓存DOM变量

来自分类Dev

如何在Voyage for Pharo中禁用缓存?

来自分类Dev

如何在Opencart中还原vqmod缓存?

来自分类Dev

如何在Vala的libsoup中缓存DNS?

来自分类Dev

如何在Django中缓存模型方法?

来自分类Dev

如何在OSX中查看DNS缓存?

来自分类Dev

如何在Ruby中缓存方法?

来自分类Dev

如何在抖动中缓存视频

来自分类Dev

如何在jquery ajax中启用缓存

来自分类Dev

如何在DIV中缓存图像

来自分类Dev

如何在Durandal中禁用缓存视图

来自分类Dev

如何在CPU中实现LRU缓存?

来自分类Dev

如何在JBOSS 4.0.4中禁用缓存?

来自分类Dev

如何在Laravel中缓存模型属性

来自分类Dev

如何在Vala的libsoup中缓存DNS?

来自分类Dev

如何在 Blaze 中缓存模板?

来自分类Dev

如何在chrome中重置api缓存?

来自分类Dev

如何在scala中缓存函数结果

来自分类Dev

无论缓存如何,如何在React中更新Redux存储

来自分类Dev

如何在Android中删除WebView中的缓存?

来自分类Dev

如何在Android中删除WebView中的缓存?

来自分类Dev

如何在 Spring 的 @RestController 中验证参数对象中的 url 参数包

来自分类Dev

如何在Scala中实现不可变缓存?