我正在尝试在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();
}
答案 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框架,实现它非常容易。
创建了一个由DB中的CLOB支持的BinaryImage类。从Spring 4.1 +实现Resource
接口。
然后我创建了一个新的ResourceResolver
,根据已知路径查找传入的请求&#34; / images&#34;。
然后在WebMVC框架中对其进行了配置。
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();