spring boot (二) servlet listener filter interceptor

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/fox9916/article/details/78342112

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

猜你喜欢

转载自blog.csdn.net/fox9916/article/details/78342112
今日推荐