2013-03-11 68 views
0

我想我的Spring MVC Controller响应被视为浏览器中的静态内容。只需获取一次,然后从浏览器缓存中获取304 Not Modified状态码。 我用普通的方法有普通的Spring MVC控制器。 simpleService.getVariables()正在从数据库中获取大量内容。它返回String。Spring MVC Controller响应作为静态内容缓存在浏览器中

@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文件,并且secondPartString添加到ModelAndView对象。

<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> 

要启用瓷砖expressions我已经加入这个tilesProperties

这是我tiles/javascript.jsp

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

我只用添加了这个弹簧过滤器实现304 Not Modified状态码到web.xml。但是,每次仍然获取内容,并且通过Etag标题比较,状态代码为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控制器的缓存响应?我试图通过HTTP头来实现这一点,但它不起作用。

回答

1

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

正如您所看到的,此方法不会减少您的实际控制器为请求所做的工作量,它只会提高带宽利用率并为客户端提供更快的响应(由于不是发送响应正文,我们只发送一个状态码)。

因此,对于您的情况,您应该使用Last-Modified响应标头和If-Modified-Since请求标头。要使用Spring MVC执行此操作,可以尝试以下方法: 1.在您的控制器中,以毫秒为单位维护时间戳,该时间戳应与资源的最后修改时间相同。我将其设置为部署时间,假定我的内容在应用程序处于活动状态时不会被修改。如果您想强制浏览器加载新副本,即使它们的版本较旧,您也可以根据需要选择更新此时间。

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

  2. 在您的方法中,只有在webRequest.checkNotModified(lastModifiedTime)为假的情况下才执行实际处理。

示例代码:

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 
    } 
} 
} 

希望这有助于。