java动态注册Filter,Servlet,Listener
创建一个简单项目有如下结构:
在TestServletContainerInitializer类中实现这个接口,并实现onStartup方法:
public class TestServletContainerInitializer implements ServletContainerInitializer { /** * * @param set 这个参数得到的是实现了ServletContainerInitializer接口的所有实现类 * @param servletContext servlet上下文,通过上下文对象来实现动态注册 * @throws ServletException */ @Override public void onStartup(Set<Class<?>> set, ServletContext servletContext) throws ServletException { //注册Servlet,参数一指定servlet-name,参数二指定servlet-class //这个方法返回一个动态注册器 ServletRegistration.Dynamic reg = servletContext.addServlet("test", TestServlet.class); //添加请求映射(相当于配置url-pattern) reg.addMapping("/test"); //注册监听器 servletContext.addListener(TestListener.class); //注册过滤器 //该方法返回一个动态注册器 FilterRegistration.Dynamic filterReg = servletContext.addFilter("testFilter", TestFilter.class); /** * 映射请求的url * 参数一:表示请求或者转发或者包含时会经过这个过滤器 * 参数二:表示动态配置的过滤器是否优先于web.xml中配置的过滤器 * true表示优先 * 参数三:请求过滤的url */ filterReg.addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST), true, "/*"); } }
在Spring中,提供了AbstractAnnotationConfigDispatcherServletInitializer类专门用于取代web.xml,同时这个类也提供了onStartup方法,重写这个方法就可以动态注册相关组件。
在配置类中继承这个类,并重写onStartup方法:
@Override public void onStartup(ServletContext servletContext) throws ServletException { //注册自定义过滤器 //addFilter中分别提供filter-name和filter的class对象 FilterRegistration.Dynamic reg = servletContext.addFilter("testFilter", TestFilter.class); reg.addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST), true, "/*"); //注册spring mvc 提供字符编码过滤器 FilterRegistration.Dynamic encodingFilter = servletContext.addFilter("encodingFilter", new CharacterEncodingFilter()); encodingFilter.addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST), true, "/*"); //注意重写onStartup方法后必须将ServletContext对象传回给父类, //否则DispatcherServlet不会生效 super.onStartup(servletContext); }