Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to prevent Grails from caching old versions of gsp file?

Tags:

grails

gsp

I am making modifications to /grails-app/views/index.gsp.

When I save the file and refresh http://localhost:8080/index.gsp in Firefox, I am getting an old version of the file.

Is there a way to prevent Grails from caching and rendering old versions of the file?

(I tried restarting the server and clearing Firefox's cache.)

Thanks!

like image 673
Emmett Avatar asked Aug 30 '09 05:08

Emmett


2 Answers

can't we use a filter like this?

class CacheFilters{

    def filters = {
        all(controller: '*', action: '*') {
            before = {
                ((HttpServletResponse) response).setHeader("Cache-Control", "no-store, no-cache, must-revalidate");
            }
            after = {

            }
            afterView = {

            }
        }
    }

}
like image 130
VasiliyL Avatar answered Sep 25 '22 02:09

VasiliyL


There doesn't seem to be a simple way to do this, but it's not much work. My solution subclasses the servlet that renders GSPs (and also the controller that's used for non-GSP requests).

Here's the servlet subclass:

package com.burtbeckwith;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.codehaus.groovy.grails.web.pages.GroovyPagesServlet;

public class CachingPageServlet extends GroovyPagesServlet {

   private static final String HEADER_PRAGMA = "Pragma";
   private static final String HEADER_EXPIRES = "Expires";
   private static final String HEADER_CACHE_CONTROL = "Cache-Control";

   @Override
   public void doPage(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
      response.setHeader(HEADER_PRAGMA, "no-cache");
      response.setDateHeader(HEADER_EXPIRES, 1L);
      response.setHeader(HEADER_CACHE_CONTROL, "no-cache");
      response.addHeader(HEADER_CACHE_CONTROL, "no-store");
      super.doPage(request, response);
   }
}

and you'll need to replace the original in web.xml (run "grails install-templates" and edit src/templates/war/web.xml):

<servlet>
   <servlet-name>gsp</servlet-name>
   <servlet-class>com.burtbeckwith.CachingPageServlet</servlet-class>
</servlet>

and you'll probably also want to do the same for Controller-based responses, so to do that use this controller subclass:

package com.burtbeckwith;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.codehaus.groovy.grails.web.servlet.mvc.SimpleGrailsController;
import org.springframework.web.servlet.ModelAndView;

public class CachingSimpleGrailsController extends SimpleGrailsController {

   private static final String HEADER_PRAGMA = "Pragma";
   private static final String HEADER_EXPIRES = "Expires";
   private static final String HEADER_CACHE_CONTROL = "Cache-Control";

   @Override
   public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
      response.setHeader(HEADER_PRAGMA, "no-cache");
      response.setDateHeader(HEADER_EXPIRES, 1L);
      response.setHeader(HEADER_CACHE_CONTROL, "no-cache");
      response.addHeader(HEADER_CACHE_CONTROL, "no-store");
      return super.handleRequest(request, response);
   }
}

and you'll need to register it in grails-app/conf/spring/resources.groovy to override the regular Spring bean:

mainSimpleController(com.burtbeckwith.CachingSimpleGrailsController) {
   grailsApplication = ref('grailsApplication', true)
}

The shared header-setting code should probably be extracted into a utility class instead of being copy/pasted like I did here.

like image 21
Burt Beckwith Avatar answered Sep 25 '22 02:09

Burt Beckwith