首页 > 学院 > 开发设计 > 正文

servlet 3.0笔记之servlet的动态注册

2019-11-06 09:12:31
字体:
来源:转载
供稿:网友

http://www.blogjava.NET/yongboy/archive/2010/12/30/346209.html

说实话,对servlet 3动态加载servlet的机制有些失望,本来期望着可以在运行时完成对servlet的注册和销毁,但现状是,只能在webapp启动在初始化时进行完成注册,可能是为了安全考虑吧.

在Servlet3.0中可以动态注册Servlet,Filter,Listener,在ServletContext对应注册API为:
  /**    * 添加Servlet    */   public ServletRegistration.Dynamic addServlet(String servletName,       String className);   public ServletRegistration.Dynamic addServlet(String servletName,       Servlet servlet);   public ServletRegistration.Dynamic addServlet(String servletName,       Class<? extends Servlet> servletClass);   /**    * 添加Filter    */   public FilterRegistration.Dynamic addFilter(String filterName,       String className);   public FilterRegistration.Dynamic addFilter(String filterName, Filter filter);   public FilterRegistration.Dynamic addFilter(String filterName,       Class<? extends Filter> filterClass);   /**    * 添加Listener    */   public void addListener(String className);   public <T extends EventListener> void addListener(T t);   public void addListener(Class<? extends EventListener> listenerClass);
每个组件注册都提供三个方法,很细心。下面谈谈动态注册Servlet,但不要希望太高,只能在初始化时进行注册。在运行时为了安全原因,无法完成注册。在初始化情况下的注册Servlet组件有两种方法:1.实现ServletContextListener接口,在contextInitialized方法中完成注册.2.在jar文件中放入实现ServletContainerInitializer接口的初始化器先说在ServletContextListener监听器中完成注册。
    public void contextInitialized(ServletContextEvent sce) {         ServletContext sc = sce.getServletContext();         // Register Servlet         ServletRegistration sr = sc.addServlet("DynamicServlet",             "web.servlet.dynamicregistration_war.TestServlet");         sr.setInitParameter("servletInitName", "servletInitValue");         sr.addMapping("/*");         // Register Filter         FilterRegistration fr = sc.addFilter("DynamicFilter",             "web.servlet.dynamicregistration_war.TestFilter");         fr.setInitParameter("filterInitName", "filterInitValue");         fr.addMappingForServletNames(EnumSet.of(DispatcherType.REQUEST),                                      true, "DynamicServlet");         // Register ServletRequestListener         sc.addListener("web.servlet.dynamicregistration_war.TestServletRequestListener");     }
很简单,难度不大。再说说在jar文件中的servlet组件注册,需要在jar包含META-INF/services/javax.servlet.ServletContainerInitializer文件,文件内容为已经实现ServletContainerInitializer接口的类:
com.learn.servlet3.jardync.CustomServletContainerInitializer该实现部分代码:
@HandlesTypes({ JarWelcomeServlet.class }) public class CustomServletContainerInitializer implements     ServletContainerInitializer {   PRivate static final Log log = LogFactory       .getLog(CustomServletContainerInitializer.class);   private static final String JAR_HELLO_URL = "/jarhello";   public void onStartup(Set<Class<?>> c, ServletContext servletContext)       throws ServletException {     log.info("CustomServletContainerInitializer is loaded here...");         log.info("now ready to add servlet : " + JarWelcomeServlet.class.getName());         ServletRegistration.Dynamic servlet = servletContext.addServlet(         JarWelcomeServlet.class.getSimpleName(),         JarWelcomeServlet.class);     servlet.addMapping(JAR_HELLO_URL);     log.info("now ready to add filter : " + JarWelcomeFilter.class.getName());     FilterRegistration.Dynamic filter = servletContext.addFilter(         JarWelcomeFilter.class.getSimpleName(), JarWelcomeFilter.class);     EnumSet<DispatcherType> dispatcherTypes = EnumSet         .allOf(DispatcherType.class);     dispatcherTypes.add(DispatcherType.REQUEST);     dispatcherTypes.add(DispatcherType.FORWARD);     filter.addMappingForUrlPatterns(dispatcherTypes, true, JAR_HELLO_URL);     log.info("now ready to add listener : " + JarWelcomeListener.class.getName());     servletContext.addListener(JarWelcomeListener.class);   } }
其中@HandlesTypes注解表示CustomServletContainerInitializer 可以处理的类,在onStartup 方法中,可以通过Set<Class<?>> c 获取得到。jar文件中不但可以包含需要自定义注册的servlet,也可以包含应用注解的servlet,具体怎么做,视具体环境而定。把处理某类事物的servlet组件打包成jar文件,有利于部署和传输,功能不要了,直接去除掉jar即可,方便至极!
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表