每当我需要在Spring MVC上处理自定义响应数据类型时,似乎有些尴尬。
就我而言,我需要返回一个JavaScript内容。但是,我希望它是缓存。
所以要澄清一下,这不是一个静态文件大小写(<mvc:resources...
),而是它是在服务器上生成的动态文件,我想要缓存(即HttpResponse 200和HttpResponse 302)。
就代码而言,在客户端我只是:
<script src="<spring:url value='/some-file.js'/>"></script>
比SpringMVC控制器:
@RequestMapping(value = "/some-file.js")
public ResponseEntity<String> resourceBundles(HttpServletRequest request, HttpServletResponse response, Locale locale) throws IOException {
responseHeaders.add("Cache-Control", "public, max-age");
responseHeaders.add("Content-Type", "text/javascript; charset=UTF-8");
responseHeaders.add("Expires", "max-age");
// Turn this into JSON response:
String someJson = "{ a:a, b;b};";
return new ResponseEntity<String>("var data = " + someJson, responseHeaders, HttpStatus.OK);
}
但是,似乎浏览器总是试图访问这个动态的JS文件。
由于此文件是会话依赖的,我无法生成它并将其视为静态文件。
有什么建议吗?
答案 0 :(得分:0)
这是正确的行为。大多数浏览器会向您发送GET
请求,并带有If-Modified-Since
+时间戳,以检查文件是否已更改。
在通常情况下,您可以使用时间戳来确定文件是否已更改。但是,因为它永远不会改变你的情况,你可以回复304
/ HttpStatus.NOT_MODIFIED
response without a response body(而不是200
/ OK)。
告诉浏览器文件没有改变。
这应该有效:
@RequestMapping(value = "/some-file.js")
public ResponseEntity<String> resourceBundles(
HttpServletRequest request,
HttpServletResponse response, Locale locale) throws IOException {
Date lmod = session.getAttribute("lmod");
if( null == lmod ) {
lmod = new Date();
session.setAttribute("lmod", lmod);
}
responseHeaders.add("Last-Modified", lmod);
String ifModifiedSince = request.getHeader("If-Modified-Since");
if( null != ifModifiedSince ) { // You may want to compare lmod and ifModifiedSince here, too
return new ResponseEntity( responseHeaders, HttpStatus.NOT_MODIFIED );
}
... create first time response ...
}
告诉浏览器Last-Modified
,它会向您发送If-Modified-Since