2013-11-18 7 views
7

Каков наилучший способ установить заголовки управления кешем статических активов в службе Dropwizard?Установить заголовки управления кешем статических активов в Dropwizard

Некоторые Googling появился в AssetsBundle конструктор:

AssetsBundle(String resourcePath, com.google.common.cache.CacheBuilderSpec cacheBuilderSpec, String uriPath)

Однако на доследование, это выглядит как пакет com.yammer.dropwizard.bundles, начиная с версии 5.1 не была частью Dropwizard.

Возможно, мне не хватает чего-то очевидного, но есть ли предпочтительный способ справиться с этим?

ответ

1

Опираясь на ответ от Тима Barclay, я создал фильтр, который устанавливает Cache-Control и Expires один год в будущем, если ресурс запрашивается, является файл с расширением js, css, png, jpg, gif или svg. В противном случае кеш отключается.

Надеюсь, это может быть полезно для кого-то!

protected void setCacheHeaders(Environment environment, String urlPattern, int seconds) { 
    FilterRegistration.Dynamic filter = environment.servlets().addFilter(
      "cacheControlFilter", 
      new Filter() { 
       @Override 
       public void init(FilterConfig filterConfig) throws ServletException { 

       } 

       @Override 
       public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { 

        HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest; 
        HttpServletResponse httpServletResponse = (HttpServletResponse) servletResponse; 

        String[] cacheFileTypes = {"js","css","png","jpg","gif","svg"}; 
        String filetypeRequested = FilenameUtils.getExtension(httpServletRequest.getRequestURL().toString()); 

        if (httpServletRequest.getMethod() == "GET" && seconds > 0 && Arrays.asList(cacheFileTypes).contains(filetypeRequested)) { 
         httpServletResponse.setHeader("Cache-Control", "public, max-age=" + seconds); 
         Calendar c = Calendar.getInstance(); 
         c.setTime(new Date()); 
         c.add(Calendar.SECOND, seconds); 
         SimpleDateFormat format = new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss zzz", Locale.US); 
         format.setTimeZone(TimeZone.getTimeZone("GMT")); 
         httpServletResponse.setHeader("Expires", format.format(c.getTime())); 
        } else { 
         httpServletResponse.setHeader("Cache-Control", "no-cache, no-store, must-revalidate"); 
         httpServletResponse.setHeader("Expires", "0"); 
         httpServletResponse.setHeader("Pragma", "no-cache"); 
        } 

        filterChain.doFilter(servletRequest, servletResponse); 

       } 

       @Override 
       public void destroy() { 

       } 
      } 
    ); 
    filter.addMappingForUrlPatterns(EnumSet.allOf(DispatcherType.class), true, urlPattern); 
} 

PS: Я не мог так принято отвечать, чтобы установить Expires -header работать:

resp.setHeader("Expires", new Date().getTime()+500000 + ""); 

Шахта ужасно раздутой в сравнении, но она работает:

Calendar c = Calendar.getInstance(); 
c.setTime(new Date()); 
c.add(Calendar.SECOND, seconds); 
SimpleDateFormat format = new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss zzz", Locale.US); 
format.setTimeZone(TimeZone.getTimeZone("GMT")); 
httpServletResponse.setHeader("Expires", format.format(c.getTime())); 
+0

Основываясь на комментарии от @Rich о моем ответе, похоже, возможно, что я предложил больше не работать с текущими версиями Dropwizard. использовал его (или Java вообще на самом деле) с 2014 года, поэтому я не могу проверить. –

8

В случае, если кто-то заинтересован (что, судя по количеству просмотров, которое у этого вопроса было, они, вероятно, нет), так я решил это.

Я создал класс CacheControlFilter в том же пакете моего класса обслуживания:

public class CacheControlFilter implements Filter{ 

    public void doFilter(ServletRequest request, ServletResponse response, 
     FilterChain chain) throws IOException, ServletException { 

     HttpServletResponse resp = (HttpServletResponse) response; 

     // Add whatever headers you want here 
     resp.setHeader("Cache-Control", "public, max-age=500000"); 
     resp.setHeader("Expires", new Date().getTime()+500000 + ""); 

     chain.doFilter(request, response); 
    } 

    public void destroy() {} 

    public void init(FilterConfig arg0) throws ServletException {} 
} 

Тогда в классе обслуживания, просто добавьте строку:

env.addFilter(new CacheControlFilter(), "/*"); 

Конечно, вы могли бы быть более мелкозернистый и добавьте другой фильтр, скажем, файлы изображений и файлы css, но это добавляет заголовки для всех запросов.

+4

Это помогло мне, спасибо. Но следует отметить, что этот фильтр, записанный (и установленный), применяется ко всем запросам любого типа (GET, PUT и т. Д.).Он НЕ относится только к сервису статических активов. – Lambart

+0

Спасибо, отредактирован для исправления. И только 14 месяцев поздно! –

+0

Это не работает с Dropwizard 9.0 – Rich

2

Если вы хотите очистить кеш для каждого запроса, ниже мое решение, которое использует CacheBustingFilter, предоставляемое DropWizard.

  1. Определите пользовательскую конфигурацию, в моем случае ее WebConfiguration. Используйте эту конфигурацию при настройке приложения DropWizard.

    public class WebConfiguration extends Configuration { 
    
    @JsonProperty 
    private String enableCacheControl; 
    
    public String getEnableCacheControl() { 
        return enableCacheControl; 
    } 
    
    public void setEnableCacheControl(String enableCacheControl) { 
        this.enableCacheControl = enableCacheControl; 
    } 
    

    }

  2. Получить конфигурацию, которую Вы определили в # 1 и зарегистрировать CacheBustingFilter на основе его стоимости.

Добавьте это в методе выполнения -

// get the cache control settings from the YAML - configuration 
    String enableCacheControl = configuration.getEnableCacheControl(); 
    boolean enableCacheBustingFilter = Boolean.parseBoolean(enableCacheControl); 

    if(enableCacheBustingFilter){ 
     // caching was enabled in YAML - was set to true - enabling the cacheBustingFilter 
     // this will ALWAYS return "must-revalidate,no-cache,no-store" in the Cache-Control response header 
     environment.servlets().addFilter("CacheBustingFilter", new CacheBustingFilter()) 
      .addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST), true, "/*"); 
    } 
+0

Спасибо - это работает! Мне не хватало «addMappingForUrlPatterns», без которого это молча ничего не делает :-( – Rich

Смежные вопросы