0

每当我需要处理 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 文件。

由于此文件依赖于会话,因此我无法生成它并将其视为静态文件。

有什么建议么?

4

1 回答 1

1

这是正确的行为。大多数浏览器会向您GET发送带有If-Modified-Since+ 时间戳的请求,以检查文件是否已更改。

在通常情况下,您将使用时间戳来确定文件是否已更改。但是由于它在您的情况下永远不会改变,您可以使用304/HttpStatus.NOT_MODIFIED响应而不使用响应正文(而不是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

于 2012-07-25T09:54:25.907 回答