我希望 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 中,维护以毫秒为单位的时间戳,该时间戳应与资源的上次修改时间相同。我将其设置为部署时间,假设我的内容在应用程序运行时不会被修改。如果您想强制浏览器加载新副本,即使它们有旧版本,您也可以选择根据需要更新此时间。
接受 org.springframework.web.context.request.WebRequest 作为 Controller 方法的参数。
仅当
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/