1

我有一个纯 JavaConfig Java webapp,它使用从 AbstractAnnotationConfigDispatcherServletInitializer 扩展的类。它非常适合配置我的调度程序 servlet,但我的调度程序 servlet 仅映射到具有 url 模式“/rest/*”的请求。对于所有其他请求(即 css、html、js 等),没有 spring 映射,一切都通过默认的 servlet。对于这些请求,我想实现一个 GZip 过滤器。我在许多项目中使用了多年前在网上找到的自定义 gzip 过滤器。

通过 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() 或使用 URL 映射“/*”从 servletContext.addFilter() 创建 FilterRegistration.Dynamic,只有通过调度程序 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 无关的过滤器。

4

1 回答 1

2

你没有给我们我想要的那么多,但这就是javadocServletContext#addFilter(String, Filter)所说的

返回:一个FilterRegistration可用于进一步配置给定过滤器的对象,或者null如果此 ServletContext 已经包含具有给定过滤器的完整FilterRegistration过滤器, filterName或者如果相同的过滤器实例已经在同一容器中使用此或另一个 ServletContext 注册

您似乎已经Filter用相同的名称注册了那个或另一个。

于 2014-04-07T22:09:17.233 回答