2014-04-07 67 views
1

我有一個純粹的JavaConfig Java webapp,它使用從AbstractAnnotationConfigDispatcherServletInitializer擴展的類。它適用於配置我的調度程序servlet,但我的調度程序servlet僅映射到具有url模式「/ rest/*」的請求。對於所有其他請求(即css,html,js等),沒有彈簧映射,所有事情都通過默認的servlet。對於這些請求,我想實現一個GZip過濾器。我使用了多年前在許多項目中在網上找到的自定義gzip過濾器。Spring 3.2 - AbstractAnnotationConfigDispatcherServletInitializer onStartup - 添加一個servlet過濾器返回null

使用JavaConfig實現,我明白受保護的Filter [] getServletFilters()方法適用於調度程序serlvet ...這是不正確的嗎?

我現在要做的是將gzip過濾器應用於任何不會發送到調度程序servlet的請求。我重寫onStartup方法,像這樣:

@Override 
    public void onStartup(ServletContext servletContext) throws ServletException { 
     super.onStartup(servletContext);  
     FilterRegistration.Dynamic encodingFilter = servletContext.addFilter("encodingFilter", new CharacterEncodingFilter()); 
     encodingFilter.setInitParameter("encoding", "UTF-8"); 
     encodingFilter.setInitParameter("forceEncoding", "true"); 
     encodingFilter.addMappingForUrlPatterns(null, true, "/*"); 

     FilterRegistration.Dynamic gzipFilter = servletContext.addFilter("gzipFilter", new GzipFilter()); 
     gzipFilter.addMappingForUrlPatterns(null, true, "/*"); 
    } 

編碼過濾器工作正常,但我得到的GzipFilter一個NullPointerException當我添加映射...的servletContext.addFilter返回null。我想可能是因爲我的自定義類和新的JavaConfig實現有些奇怪,所以我在網上發現人們使用的是ehacache-web軟件包中包含的gzip過濾器,所以我添加了它作爲依賴項並嘗試使用該過濾器。同樣的事情... CharacterEncodingFilter工作正常,並且addFilter方法正確地返回一個FilterRegistration.Dynamic對象,但是gzip過濾器仍然返回null。

任何想法是什麼造成這種情況?

編輯:

這裏是我的整個配置文件:

public class WebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer { 

    @Override 
    public void onStartup(ServletContext servletContext) throws ServletException { 
     super.onStartup(servletContext); 

     FilterRegistration.Dynamic encodingFilter = servletContext.addFilter("encodingFilter", new CharacterEncodingFilter()); 
     encodingFilter.setInitParameter("encoding", "UTF-8"); 
     encodingFilter.setInitParameter("forceEncoding", "true"); 
     encodingFilter.addMappingForUrlPatterns(null, true, "/*"); 

     FilterRegistration.Dynamic gzipFilter = servletContext.addFilter("gzipFilter", new GzipFilter()); 
     gzipFilter.addMappingForUrlPatterns(null, true, "/*"); 


    } 

    @Override 
    protected Class<?>[] getRootConfigClasses() { 
     return new Class[]{SecurityConfig.class, Log4jConfig.class, PersistenceConfig.class, ServiceConfig.class}; 
    } 

    @Override 
    protected Class<?>[] getServletConfigClasses() { 
     return new Class[]{SpringMvcConfig.class}; 
    } 

    @Override 
    protected String[] getServletMappings() { 
     return new String[]{ 
      "/rest/*", 
      "/index.html", 
      "/login.html", 
      "/admin.html", 
      "/index/*", 
      "/login/*", 
      "/admin/*" 
     }; 
    } 

    @Override 
    protected Filter[] getServletFilters() { 
     OpenEntityManagerInViewFilter openEntityManagerInViewFilter = new OpenEntityManagerInViewFilter(); 
     openEntityManagerInViewFilter.setBeanName("openEntityManagerInViewFilter"); 
     openEntityManagerInViewFilter.setPersistenceUnitName("HSQL"); 

     return new javax.servlet.Filter[]{openEntityManagerInViewFilter}; 
    } 

} 

不管,如果我GzipFilter添加到getServletFilters(),或從servletContext.addFilter()以創建FilterRegistration.Dynamic 「/ *」的URL映射,只有通過調度程序servlet處理的請求才會被壓縮。

編輯2:

這裏是一個沒有被gzip壓縮的URL:

http://localhost:8084/swtc/js/ServiceWidget/templates/ServiceWidget.html 

Response Headers 
Accept-Ranges bytes 
Content-Length 399 
Content-Type text/html 
Date Mon, 07 Apr 2014 18:47:08 GMT 
Etag W/"399-1377195848751" 
Last-Modified Thu, 22 Aug 2013 18:24:08 GMT 
Server Apache-Coyote/1.1 

這裏是正在gzip壓縮的URL:

http://localhost:8084/swtc/rest/mapServices/getEnabledServices 

Response Headers 
Content-Encoding gzip 
Content-Length 76 
Content-Type application/json;charset=UTF-8 
Date Tue, 08 Apr 2014 18:34:11 GMT 
Server Apache-Coyote/1.1 

會的一個選項是改變調度員serlvet映射到/ *,只是將我的js,css,img等文件夾定義爲資源?雖然我覺得這樣做是爲了避免這個問題......我很高興知道爲什麼我可以在web.xml中指定一個與Spring無關的過濾器。

+0

請發佈您的完整堆棧跟蹤和其餘配置。 –

+0

這只是一個NullPointerException。在NPE生成之前,servletContext.addFilter方法返回一個FilterRegistration.Dynamic時返回null。當gzipFilter爲null時,NPE會嘗試調用gzipfilter上的addMappingforUrlPatterns。 – Bal

回答

2

你還沒有給我們,就像我想但這裏是爲ServletContext#addFilter(String, Filter)的Javadoc說

返回:可用於進一步 配置給定的過濾器FilterRegistration對象, null如果ServletContext中已經 包含了帶有過濾器的完整FilterRegistration給定 filterName或者相同的過濾器實例已經註冊 用這種或者其他的ServletContext在S AME容器

你似乎已經註冊了Filter或其他與已經相同的名稱。

+0

檢查上下文對象顯示有一個gzip過濾器,我在getServletFilters方法中註冊了...所以我想我的假設是受保護的Filter [] getServletFilters()方法僅適用於調度程序servlet的過濾器...要麼傳遞給onStartup(ServletContext servletContext)方法的servlet上下文是調度程序servlet上下文。無論哪種方式,我現在有一個很好的方法來解決這個問題。感謝您的回答! – Bal

+0

@Bal每個Web應用程序只有一個由Servlet容器提供的ServletContext對象。不要被容器提供的'ServletContext'和'DispatcherServlet'加載的'ApplicationContext'混淆, Spring調用servlet上下文。 –

+0

感謝您的信息!我在重寫的getServletFilters()方法中添加了一個新的gzip過濾器實例,但是我認爲只能映射到調度器servlet請求,因爲我無法指定URL模式,在我的情況下,這只是模式/ rest/*。我刪除了它,並將其直接添加到帶有「/ *」模式的ServletContext對象,但仍然只有來自調度程序servlet的請求被壓縮。對我的/ js或/ css文件夾的任何請求都未被解壓縮。有任何想法嗎? – Bal

相關問題