spring boot (二) servlet listener filter interceptor

spring boot 二 servlet listenerfilter interceptor

 

         一般做web開發,使用controller就可以滿足大部分的需要,但是有的時候也會用到servlet listener filter 和interceptor等,spring boot中取消了繁雜的xml配置,但是功能並沒有減少,所以要對於這些需求,也有相應的解決辦法。

         servlet

         我們知道spingMVC的主servlet 是DispatcherServlet,其默認的url-pattern“/”,當然springboot也是,spring boog中添加servlet有兩種方法,代碼註冊Servlet和註解自動註冊Servletspring bootfilterlistener的添加同樣也是這兩種方法。不過springboot大量使用註解,來簡化配置,應該是比較推薦使用註解來自動註冊Servlet

第一種,通過註解自動註冊Servlet,先在啓動類上加上註解@ServletComponentScan,來掃描算定義的servlet,

啓動類示例:

@SpringBootApplication

@ServletComponentScan

public class DemoApplication {

 

   public static void main(String[] args) {

      SpringApplication.run(DemoApplication.class,args);

   }

}

示例DemoServlet2.java

@WebServlet(urlPatterns="/gaox/hello",description="測試")

public class DemoServlet2 extends HttpServlet {

 

   @Override

   protected void service(HttpServletRequest req, HttpServletResponseresp)

        throws ServletException, IOException {

      // TODO Auto-generatedmethod stub

      resp.setContentType("text/html");

      resp.setCharacterEncoding("utf-8");

      resp.getWriter().print("hello ,baby !");

   }

}

run as 啓動類啓動,在瀏覽器中輸入http://localhost:8080/gaox/hello,結果:


第二種,通過代碼來註冊servlet,新建一個普通的類繼承HttpServlet,重寫service或doGet 、doPost方法,示例DemoServlet.java

public class DemoServlet extends HttpServlet {

 

   @Override

   protected void service(HttpServletRequest request, HttpServletResponseresponse)

        throws ServletException, IOException {

      // TODO Auto-generatedmethod stub

      request.setCharacterEncoding("utf-8");

      response.setContentType("text/html");

      response.setCharacterEncoding("utf-8");

      response.getWriter().print("測試一下");

   }

}

然後把自己自定義的Servlet、監聽器、過濾器,在啓動的時候註冊到容器中,示例:

@SpringBootApplication

public class DemoApplication {

 

      public static void main(String[] args) {

      SpringApplication.run(DemoApplication.class,args);

   }

   /**

    * 註冊自定義的servlet

    * @return

    */

   @Bean

   public ServletRegistrationBean getServletRegistrationBean(){

      return new ServletRegistrationBean(new DemoServlet(),"/gaox/demo");

   }

   /**

    * 註冊自定義的監聽器

    * @return

    */

   @Bean

   public ServletListenerRegistrationBeangetServletListenerRegistrationBean(){

      return new ServletListenerRegistrationBean(newDemoListener3());

   }

   /**

    * 註冊自定義的過濾器

    * @return

    */

   @Bean

   public FilterRegistrationBean getFilterRegistrationBean(){

      FilterRegistrationBean registrationBean=newFilterRegistrationBean();

      registrationBean.setFilter(new DemoFilter());

      registrationBean.addUrlPatterns("/*");

      return registrationBean;

   }}

run as 啓動類啓動,在瀏覽器中輸入http://localhost:8080/gaox/demo,結果:


listener

在java web應用中,listener監聽器似乎是必不可少的,常常用來監聽servletContext、httpSession、servletRequest等域對象的創建、銷燬以及屬性的變化等等,可以在這些事件動作前後進行一定的邏輯處理。

而我暫時先說其中三個用來監聽域對象的,分別是servletContextListener、httpSessionListener、servletRequestListener。 這三個接口寫法上實際是差不多的,都有兩個分別代表了該域對象創建時調用和銷燬時調用的方法,這三個對象最大的區別應該就是作用域不一樣。 servletContext在整個應用啓動到結束中生效,啓動系統時創建這個對象,整個過程中這個對象是唯一的。 httpSession則是在一個session會話中生效,在一個session被創建直到失效的過程中都起作用,不過一個啓動的應用中httpSession對象可以有多個,比如同一臺電腦兩個瀏覽器訪問,就會創建兩個httpSession對象。 而servletRequest是在一個request請求被創建和銷燬的過程中生效,每發起一次請求就會創建一個新的servletRequest對象,比如刷新瀏覽器頁面、點擊應用的內鏈等等。

    監聽器以及過慮器的添加與servlet的添加一樣,也是兩種方法,通過代碼註冊與註解自動註冊,方法很類似,其實就是註冊的方式不同,一種是用註解,別一種就是代碼,兩種訪求的共同點就是都要繼承或實現相應的接口,新建一個實例,然後就是用不同的方式注入到容器裏。上面已經在代碼中體現了怎麼把servlet、listener、filter用代碼注入到容器中,這裏只貼出用註解怎麼註冊listener、filter,如果想用代碼來註冊,那就把相應的解去掉,然後在啓動的時候用代碼把自己自定義的listener、filter實例添加進去即可。

DemoListener.java:

@WebListener

public class DemoListener implements HttpSessionListener {

   private Loggerlog=Logger.getLogger(DemoListener2.class);

   @Override

   public void sessionCreated(HttpSessionEvent se) {

      // TODO Auto-generatedmethod stub

      log.info("會話範圍內的監聽器創建/HttpSessionListener");       

   }

 

   @Override

   public void sessionDestroyed(HttpSessionEvent se) {

      // TODO Auto-generatedmethod stub

      log.info("會話範圍內監聽器被銷燬/HttpSessionListener");

   }

}

DemoListener2.java
@WebListener

public class DemoListener2 implements ServletContextListener {

   private Loggerlog=Logger.getLogger(DemoListener2.class);

  

   @Override

   public void contextInitialized(ServletContextEvent sce) {

      // TODO Auto-generatedmethod stub

      log.info("全局的監聽器初始化/ServletContextListener");

   }

 

   @Override

   public void contextDestroyed(ServletContextEvent sce) {

      // TODO Auto-generatedmethod stub

      log.info("全局監聽器被銷燬/ServletContextListener");

   }

 

}

DemoListener3.java

@WebListener

public class DemoListener3 implements ServletRequestListener {

   private Loggerlog=Logger.getLogger(DemoListener2.class);

   @Override

   public void requestDestroyed(ServletRequestEvent sre) {

      // TODO Auto-generatedmethod stub

      log.info("請求作用域內監聽器結束被銷燬/ServletRequestListener");

   }

 

   @Override

   public void requestInitialized(ServletRequestEvent sre) {

      // TODO Auto-generatedmethod stub

      log.info("請求作用域內被初始化/ServletRequestListener");

   }

}

 Filter

@WebFilter(urlPatterns="/*",filterName="demoFilter")

public class DemoFilter implements Filter {

 

   @Override

   public void init(FilterConfig filterConfig)throws ServletException {

      // TODO Auto-generatedmethod stub

     

      System.out.println("過濾器初始化");;

   }

 

   @Override

   public void doFilter(ServletRequest request, ServletResponseresponse,

        FilterChain chain) throws IOException, ServletException {

      // TODO Auto-generatedmethod stub

        System.out.println("通過過濾器");

        chain.doFilter(request,response);

   }

 

   @Override

   public void destroy() {

      // TODO Auto-generatedmethod stub

      System.out.println("過濾器衩銷燬");

   }

 

}

 

執行結果:


HandlerInterceptor的功能跟過濾器類似,但是提供更精細的的控制能力:在request被響應之前、request被響應之後、視圖渲染之前以及request全部結束之後。我們不能通過攔截器修改request內容,但是可以通過拋出異常(或者返回false)來暫停request的執行。

 

配置攔截器也很簡單,Spring提供了基礎類WebMvcConfigurerAdapter,我們只需要重寫 addInterceptors方法添加註冊攔截器。實現自定義攔截器只需要3步: 
1
、創建我們自己的攔截器類並實現 HandlerInterceptor接口。 
2
、創建一個Java類繼承WebMvcConfigurerAdapter,並重寫 addInterceptors方法。 
2
、實例化我們自定義的攔截器,然後將對像手動添加到攔截器鏈中(在addInterceptors方法中添加)。

MyInterceptor.java:

public class MyInterceptor implements HandlerInterceptor{

  

   private Loggerlog=Logger.getLogger(MyInterceptor.class);

 

   @Override

   public void afterCompletion(HttpServletRequest arg0,

        HttpServletResponse arg1, Objectarg2, Exception arg3)

        throws Exception {

      // TODO Auto-generatedmethod stub

      log.info("1>>>MyInterceptor1>>>>>>>在整個請求結束之後被調用,也就是在DispatcherServlet渲染了對應的視圖之後執行(主要是用於進行資源清理工作)");

   }

 

   @Override

   public void postHandle(HttpServletRequest arg0, HttpServletResponsearg1,

        Object arg2, ModelAndViewarg3) throws Exception {

      // TODO Auto-generatedmethod stub

      log.info("1>>>MyInterceptor1>>>>>>>請求處理之後進行調用,但是在視圖被渲染之前(Controller方法調用之後)");

   }

 

   @Override

   public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1,

        Object arg2) throws Exception {

      // TODO Auto-generatedmethod stub

      log.info("1>>>MyInterceptor1>>>>>>>在請求處理之前進行調用(Controller方法調用之前)");

      return true;// 只有返回true纔會繼續向下執行,返回false取消當前請求

   }

 

}

MyInterceptor2.java

public class MyInterceptor2 implements HandlerInterceptor{

  

   private Loggerlog=Logger.getLogger(MyInterceptor2.class);

 

   @Override

   public void afterCompletion(HttpServletRequest arg0,

        HttpServletResponse arg1, Objectarg2, Exception arg3)

        throws Exception {

      // TODO Auto-generatedmethod stub

      log.info("2>>>MyInterceptor1>>>>>>>在整個請求結束之後被調用,也就是在DispatcherServlet渲染了對應的視圖之後執行(主要是用於進行資源清理工作)");

   }

 

   @Override

   public void postHandle(HttpServletRequest arg0, HttpServletResponsearg1,

        Object arg2, ModelAndViewarg3) throws Exception {

      // TODO Auto-generatedmethod stub

      log.info("2>>>MyInterceptor1>>>>>>>請求處理之後進行調用,但是在視圖被渲染之前(Controller方法調用之後)");

   }

 

   @Override

   public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1,

        Object arg2) throws Exception {

      // TODO Auto-generatedmethod stub

      log.info("2>>>MyInterceptor1>>>>>>>在請求處理之前進行調用(Controller方法調用之前)");

      return true;// 只有返回true纔會繼續向下執行,返回false取消當前請求

   }

 

}

CustomMVCConfiguration.java:

 

@Configuration

public class CustomMVCConfiguration extends WebMvcConfigurerAdapter {

 

 

   @Override

   public void addInterceptors(InterceptorRegistry registry) {

      // TODO Auto-generatedmethod stub

      super.addInterceptors(registry);

      registry.addInterceptor(new MyInterceptor()).addPathPatterns("/**");

      registry.addInterceptor(new MyInterceptor2()).addPathPatterns("/**");

   }

}

run as 啓動類後,在瀏覽器中輸入http://localhost:8081/gaox/test3

結果:

 


有興趣可以到碼雲上獲取源碼仔細研究:https://gitee.com/fox9916/springboot_demo.git

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章