2012-10-18 37 views
1

我在我的Grails項目中使用緩存資源插件,但每次使用F5刷新頁面時,它都會使用http響應代碼200而不是304重新加載資源。我錯過了什麼嗎?緩存資源插件不工作?

回答

2

通過重寫緩存資源-1.0緩存頭-1.1.5插件的一些方法解決了這個問題。

看看他的插件。在緩存頭插件,無效緩存(響應,地圖參數)方法,而不是它,我添加動態地無效緩存(REQ,響應,地圖參數)方法在CacheHeadersService
收費attantion(見下面的類)查看請求標題併發送304如果資源被瀏覽器緩存。
而且還HashAndCacheResourceMapper緩存資源插件,方法高清地圖(資源配置)至極我重寫使用我NE方法從CacheHeadersService

在BootStrap運行方法void cacheResources(GrailsApplication應用程序)將更改應用於您的項目。

class CustomCachedResourcesProcessor { 

public static void cacheResources(GrailsApplication application){ 
    addMethodsToMapResources(application) 
    application.mainContext.grailsResourceProcessor.reloadAll() 
} 

private static void addMethodsToMapResources(GrailsApplication application){ 
    addCacheMethod() 
    application.getClassForName("org.grails.plugin.cachedresources.HashAndCacheResourceMapper").metaClass.map{resource, config-> 
     if (log.debugEnabled) { 
      log.debug "Hashing resources to unique names..." 
     } 

     resource.processedFile = renameToHashOfContents(resource.processedFile, resource.processedFileExtension) 
     resource.updateActualUrlFromProcessedFile() 

     // Do all the horrible cache header stuff 
     resource.requestProcessors << { req, resp -> 
      if (log.debugEnabled) { 
       log.debug "Setting caching headers on ${req.requestURI}" 
      } 
      cacheHeadersService.cache(req,resp, [neverExpires: true, shared: true]) 
     } 
    } 
} 

private static void addCacheMethod(){ 
    CacheHeadersService.metaClass.cache{request,response, Map args-> 
     if (!enabled) { 
      return 
     } 
     def store = args.store 
     def share = args.shared 
     def validFor = args.validFor 
     def validUntil = args.validUntil 
     def neverExpires = args.neverExpires 
     def requiresAuth = args.auth 

     def now = new Date() 

     def expiresOn 
     def maxage 
     if (validFor != null) { 
      expiresOn = new Date(now.time + validFor*1000L) 
      maxage = Math.max(0, validFor) 
     } else if (validUntil != null) { 
      expiresOn = validUntil 
      maxage = Math.round(Math.max(0, validUntil.time-now.time)/1000L) 
     } else if (neverExpires) { 
      // HTTP 1.1 spec says SHOULD NOT set more than 1 yr in future 
      // @todo Investigate if impls of servletresponse.setDateHeader() are using efficient threadlocals, 
      // and if so change to use those 
      expiresOn = now + 365 
      maxage = Math.round(Math.max(0, expiresOn.time-now.time)/1000L) 
     } 

     def cacheControl = [] 

     // Now set the headers 
     if ((store != null) && !store) { 
      cacheControl << 'no-store' 
     } 

     // Always set private if no explicit share - help grails devs by defaulting to safest 
     if (share) { 
      cacheControl << 'public' 
      // Note, for authentication sites we still need to add no-cache to force verification 
      // to which the app can return "not modified" if it handles etag/lastmod 
      if (requiresAuth) { 
       cacheControl << 'no-cache' 
      } 
     } else { 
      cacheControl << 'private' 
     } 

     if (maxage != null) { 
      if (share) { 
       cacheControl << "s-maxage=$maxage" 
      } 
      // Always set max-age anyway, even if shared. Browsers may not pick up on s-maxage 
      cacheControl << "max-age=$maxage" 
     } 

     if (cacheControl) { 
      response.setHeader('Cache-Control', cacheControl.join(', ')) 
     } 

     if (expiresOn != null) { 
      response.setDateHeader('Expires', expiresOn.time) 
     } 

     def possibleTags = request.getHeader('If-None-Match') 
     def modifiedDate = -1 
     try { 
      modifiedDate = request.getDateHeader('If-Modified-Since') 
     } catch (IllegalArgumentException iae) { 
      log.error ("Couldn't parse If-Modified-Since header", iae) 
     } 

     def lastModChanged = false 

     if (possibleTags || (modifiedDate != -1)) { 
      if (modifiedDate != -1) { 
       def compareDate = new Date(modifiedDate) 
       if (compareDate > now) { 
        lastModChanged = true 
       } 
      } 

      if (!lastModChanged) { 
       response.sendError(304) // Not modified 
       return false 
      } 
     } 

     // Always set last modified for courtesy and older clients, 
     // only if not already set by application (load balancers need identical lastmods) 
     if (!response.containsHeader('Last-Modified')) { 
      lastModified(response, now) 
     } 
    } 
    } 
} 

讓我知道你對它有什麼看法。

0

我添加了相同的代碼,但不工作。 我使用 Grails的2.1.4 Groovy的2.0.4 的apache-tomcat的-7.0.37 JDK 1.7 Windows 7的

而且在Config.groovy中

// changed 
grails.resources.modules = { 
    'core' { 
     defaultBundle 'core-ui' 
     resource url: '/css/cisco_base.css', attrs: [ media: 'screen' ] 
     resource url: '/css/cl.min.css', attrs: [ media: 'screen' ] 
     resource url: '/css/errors.css', attrs: [ media: 'screen' ] 
     resource url: '/css/jquery.multiselect.css', attrs: [ media: 'screen' ] 
     resource url: '/css/main.css', attrs: [ media: 'screen' ] 
     resource url: '/css/masterbrand.min.css', attrs: [ media: 'screen' ] 
     resource url: '/css/mcd.min.css', attrs: [ media: 'screen' ] 
     resource url: '/css/mobile.css', attrs: [ media: 'screen' ] 
     resource url: '/css/Sampleapp.css', attrs: [ media: 'screen' ] 
     resource url: '/css/style.css', attrs: [ media: 'screen' ] 
     resource url: '/css/table.css', attrs: [ media: 'screen' ] 
     wrapper: { s -> "<!--[if lt IE 8]>$s<![endif]-->" 

     } 
     //resource url: '/css/all.css', attrs: [ media: 'screen' ] 
     //resource url: '/css/lt7.css', attrs: [ media: 'screen' ], 
    } 

    'ui' { 
     defaultBundle 'core-ui' 
     resource url: '/js/SampleApp.js', disposition: 'head' 
    } 
} 
// changed 

而且我得到了你的代碼(以上)並放置在src/groovy/com.sample.resources的 中。

I am testing like this, 
1. With my changes I am creating a war file with maven package. 
2. Deploying in tomcat. 
3. Open browser and login to SampleGrailsApp(just open few pages in SampleGrailsApp). 
4. After, changing some code(in SampleApp.js, i added alert() method to every function in that file) in js/css files in tomcat/webapps/SampleGrailsApp folder. 
5. Check those changes are reflecting or not in browser. 
    I checked by -- opening the SampleApp in another tab -- Not reflecting changes. 
       -- Clean the browser cache -- Not reflecting changes. 
       -- Close all browsers and opened new browser -- Not reflecting changes. 
+0

難道你忘了在BootStrap中運行void cacheResources(GrailsApplication應用程序)嗎? –