如何将缓存控件标题添加到spring mvc提供的映像中

时间:2015-02-14 14:58:54

标签: spring-mvc

我正在尝试在Spring MVC中实现二进制内容控制器。

它工作正常,但我想在响应中添加缓存控件头。

我查看了这个相关的问题:Unable to cache images served by Spring MVC

但它使用的是另一种方法。我想使用这个requestMapping - 生成注释。这是我到目前为止所做的,但我不确定如何使用缓存控制元素设置响应头。

@RequestMapping(value="/binaries/**", method = RequestMethod.GET, produces={MediaType.TEXT_PLAIN_VALUE, MediaType.APPLICATION_JSON_VALUE, MediaType.IMAGE_GIF_VALUE,
 MediaType.IMAGE_JPEG_VALUE, MediaType.IMAGE_PNG_VALUE})
public @ResponseBody byte[] serveResource(WebRequest webRequest, String uri) throws IOException {
    String path = (String)request.getAttribute( HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE );

    BinaryFile bf = binaryService.findByUri(path.replaceFirst("/binaries", ""));
    if (webRequest.checkNotModified(bf.getLastModifiedDate().toDate().getTime()))
    {
        return null;
    };
    return bf.getResource();
}

4 个答案:

答案 0 :(得分:2)

您可以像这样使用ResponseEntity

@ResponseBody
public ResponseEntity<byte[]> serveResource() {
    //..
    return ResponseEntity.ok()
             .lastModified(lastModified)
             .body(bf);
}

serve resources directly with Spring Resource Handling support

请注意multiple HTTP caching improvements are scheduled for Spring Framework 4.2,现在是时候就此发表意见了(您可以对问题进行评论/投票)。

答案 1 :(得分:1)

这个怎么样:

public @ResponseBody byte[] serveResource(WebRequest webRequest, HttpServletResponse response, String uri) throws IOException {
  response.addHeader("Cache-Control", "private, max-age=0, no-cache");
// ...

答案 2 :(得分:1)

所以我刚刚重新实现了资源处理,并认为我将答案发回这个问题。

基本上我使用了新的ResourceHandling框架,实现它非常容易。

  1. 创建了一个由DB中的CLOB支持的BinaryImage类。从Spring 4.1 +实现Resource接口。

  2. 然后我创建了一个新的ResourceResolver,根据已知路径查找传入的请求&#34; / images&#34;。

  3. 然后在WebMVC框架中对其进行了配置。

  4. 2&amp;的代码下面是图3(省略了1,实现接口很简单):

    /**
     * The Frontend Binary Controller
     */
    @Component
    public class BinaryResourceResolver implements ResourceResolver{
    
        private static Logger logger = LogManager.getLogger(BinaryResourceResolver.class.getName());
    
        @Autowired
        HttpServletRequest request;
    
        @Autowired
        BinaryImageService binaryService;
    
        @Override
        public Resource resolveResource(HttpServletRequest request, String requestPath, List<? extends Resource> locations, ResourceResolverChain chain) {
            if (!requestPath.startsWith("/"))
            {
                requestPath = "/" + requestPath;
            }
            Resource bf = binaryService.findByUrl(requestPath);
    
            return bf;
        }
    
        @Override
        public String resolveUrlPath(String resourcePath, List<? extends Resource> locations, ResourceResolverChain chain) {
            return null;
        }
    
    
    }
    

    然后配置代码:在扩展WebMVCConfigurerAdapter

    的配置类中
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
            registry.addResourceHandler("/resources/**").addResourceLocations(new String[]{"/resources/", "/products/", "/categories/"})
                    .setCachePeriod(30);
            registry.addResourceHandler("/assets/**").addResourceLocations(new String[]{"/assets/"}).setCachePeriod(3600);
            registry.addResourceHandler("/frontend/**").addResourceLocations(new String[]{"/frontend/"}).setCachePeriod(3600);
    
    
        registry.addResourceHandler("/images/**").setCachePeriod(3600).resourceChain(true).addResolver(binaryResourceResolver);
        registry.setOrder(-1);
    }
    

答案 3 :(得分:0)

您应该在返回字节数组时提供最后修改的标头

if (webRequest.checkNotModified(bf.getLastModifiedDate().toDate().getTime()))
{
    return null;
};

SimpleDateFormat dateFormat=new SimpleDateFormat();
response.addHeader("Last-Modified",    dateFormat.format(bf.getLastModifiedDate().toDate().getTime()));   
return bf.getResource();