聶永的博客

          記錄工作/學(xué)習(xí)的點(diǎn)點(diǎn)滴滴。

          servlet 3.0筆記之servlet的動(dòng)態(tài)注冊(cè)

          說(shuō)實(shí)話,對(duì)servlet 3動(dòng)態(tài)加載servlet的機(jī)制有些失望,本來(lái)期望著可以在運(yùn)行時(shí)完成對(duì)servlet的注冊(cè)和銷毀,但現(xiàn)狀是,只能在webapp啟動(dòng)在初始化時(shí)進(jìn)行完成注冊(cè),可能是為了安全考慮吧.
          在Servlet3.0中可以動(dòng)態(tài)注冊(cè)Servlet,Filter,Listener,在ServletContext對(duì)應(yīng)注冊(cè)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);
          每個(gè)組件注冊(cè)都提供三個(gè)方法,很細(xì)心。
          下面談?wù)剟?dòng)態(tài)注冊(cè)Servlet,但不要希望太高,只能在初始化時(shí)進(jìn)行注冊(cè)。在運(yùn)行時(shí)為了安全原因,無(wú)法完成注冊(cè)。在初始化情況下的注冊(cè)Servlet組件有兩種方法:
          1.實(shí)現(xiàn)ServletContextListener接口,在contextInitialized方法中完成注冊(cè).
          2.在jar文件中放入實(shí)現(xiàn)ServletContainerInitializer接口的初始化器
          先說(shuō)在ServletContextListener監(jiān)聽(tīng)器中完成注冊(cè)。
              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");
              }
          很簡(jiǎn)單,難度不大。
          再說(shuō)說(shuō)在jar文件中的servlet組件注冊(cè),需要在jar包含META-INF/services/javax.servlet.ServletContainerInitializer文件,文件內(nèi)容為已經(jīng)實(shí)現(xiàn)ServletContainerInitializer接口的類:
          com.learn.servlet3.jardync.CustomServletContainerInitializer
          該實(shí)現(xiàn)部分代碼:
          @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 方法中,可以通過(guò)Set<Class<?>> c 獲取得到。
          jar文件中不但可以包含需要自定義注冊(cè)的servlet,也可以包含應(yīng)用注解的servlet,具體怎么做,視具體環(huán)境而定。
          把處理某類事物的servlet組件打包成jar文件,有利于部署和傳輸,功能不要了,直接去除掉jar即可,方便至極!

          posted on 2010-12-30 17:27 nieyong 閱讀(19962) 評(píng)論(0)  編輯  收藏 所屬分類: Servlet3

          公告

          所有文章皆為原創(chuàng),若轉(zhuǎn)載請(qǐng)標(biāo)明出處,謝謝~

          新浪微博,歡迎關(guān)注:

          導(dǎo)航

          <2010年12月>
          2829301234
          567891011
          12131415161718
          19202122232425
          2627282930311
          2345678

          統(tǒng)計(jì)

          常用鏈接

          留言簿(58)

          隨筆分類(130)

          隨筆檔案(151)

          個(gè)人收藏

          最新隨筆

          搜索

          最新評(píng)論

          閱讀排行榜

          評(píng)論排行榜

          主站蜘蛛池模板: 丹巴县| 上饶县| 万盛区| 定安县| 涿鹿县| 永丰县| 通辽市| 阿坝县| 永州市| 宁津县| 社旗县| 阿拉善左旗| 南丰县| 措勤县| 东兰县| 潞西市| 清丰县| 财经| 郑州市| 大英县| 大同市| 岑溪市| 三明市| 青川县| 莱西市| 阳东县| 南陵县| 平塘县| 吉林市| 杭州市| 西昌市| 昌平区| 渭源县| 永嘉县| 平定县| 分宜县| 上林县| 新龙县| 舒城县| 南丹县| 芜湖市|