java - Spring MVC Controller 响应作为静态内容缓存在浏览器中

标签 java spring hibernate spring-mvc tiles

我希望 Spring MVC Controller 的响应在浏览器中被视为静态内容。只需获取一次,然后从浏览器缓存中获取即可获得 304 Not Modified 状态代码。 我有普通的 Spring MVC Controller ,方法简单。 simpleService.getVariables() 正在从数据库中获取大量内容。它返回字符串。

@RequestMapping(value = "/jsContent.htm")
public ModelAndView jsContent(@RequestParam("ver") String version, 
        HttpServletRequest request, HttpServletResponse response) {
    ModelAndView mav = new ModelAndView("jsContent");
    mav.addObject("variables", simpleService.getVariables());
    return mav;
}

响应由 Apache Tiles 处理。 firstPart 是普通的 JavaScript 文件,secondPart 是添加到 ModelAndView 对象中的 String

<definition name="javascript" template="/WEB-INF/tiles/javascript.jsp" />
<definition name="jsContent" extends="javascript">
    <put-attribute name="firstPart" expression="/js/content/static.js" />
    <put-attribute name="secondPart" expression="${variables}" />
</definition>

为了在图 block 中启用表达式,我添加了以下tilesProperties:

这是我的tiles/javascript.jsp:

<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %>
<tiles:insertAttribute name="firstPart" />
<tiles:insertAttribute name="secondPart" />

通过将此 Spring 过滤器添加到 web.xml,我仅获得了 304 Not Modified 状态代码。然而,每次仍然会获取内容,并且通过 Etag header 比较,当有任何更改时,状态代码为 304

<filter>
    <filter-name>etagFilter</filter-name>
    <filter-class>org.springframework.web.filter.ShallowEtagHeaderFilter</filter-class>
</filter>

<filter-mapping>
    <filter-name>etagFilter</filter-name>
    <servlet-name>dispatcher</servlet-name>
</filter-mapping>

如何获取 Spring Controller 的缓存响应?我尝试通过 HTTP header 实现此目的,但没有成功。

最佳答案

ETag 方法不适合您的需要。过滤器的工作方式是,每次收到请求时都会调用 Controller ,然后计算响应的哈希值,将哈希值 (ETag) 与请求中发送的 Etag 进行比较,如果匹配,则过滤器假定数据没有改变,并且向客户端发送 304,没有响应正文。

正如你所看到的,这种方法并没有减少你的实际 Controller 需要为请求做的工作量,它只是提高了带宽利用率并为客户端提供了更快的响应(因为我们不是发送响应正文,而是仅发送状态代码)。

因此,对于您的情况,您应该使用 Last-Modified 响应 header 和 If-Modified-Since 请求 header 。要使用 Spring MVC 来做到这一点,您可以尝试以下方法: 1. 在 Controller 中,维护以毫秒为单位的时间戳,该时间戳应与资源的上次修改时间相同。我将其设置为部署时间,假设我的内容在应用程序运行时不会被修改。如果您想强制浏览器加载新副本,即使它们有旧版本,您也可以选择根据需要更新此时间。

  1. 接受 org.springframework.web.context.request.WebRequest 作为 Controller 方法的参数。

  2. 仅当 webRequest.checkNotModified(lastModifiedTime) 为 false 时,才在您的方法中进行实际处理。

示例代码:

public class MyController {
//Injected 
private long lastModifiedTime;

public void getFullSdk(WebRequest webRequest, HttpServletRequest request, 
                HttpServletResponse response) throws Exception {

    if (webRequest.checkNotModified(lastModifiedTime)) {
        return;
    } else {
        // real expensive code goes here
        // write to response
    }
}
}

希望这有帮助。

关于java - Spring MVC Controller 响应作为静态内容缓存在浏览器中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15339216/

相关文章:

java - @ResponseBody 导致 EofException

java - Spring Boot 不加载 logback-spring.xml

javascript - 使用 Spring MVC 的 Ajax 响应中出现 406 错误

mysql - 使用 JPA2 + Hibernate + Eclipse 4.2 + MySQL 5.5 从实体生成模式

java - JBoss EAP : @TransactionTimeout not affecting @Timeout Method?

java smack 4.0.3库facebook登录错误

java - 为什么不创建一个 Object[] 并转换为通用类型?解决办法是什么?

java - Spring Rest 模板 - 将请求字符串主体发布到 azure 给出 500 错误

Hibernate如何使用order by子句按字段总和排序

java - JPA/Hibernate 返回 BigDecimal 不长