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

前端 未结 6 1470
心在旅途
心在旅途 2021-02-04 10:20

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

6条回答
  •  夕颜
    夕颜 (楼主)
    2021-02-04 10:43

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

    
       gsp
       com.burtbeckwith.CachingPageServlet
    
    

    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.

提交回复
热议问题