SpringBoot使用过滤器、拦截器和监听器的案例代码(Springboot搭建java项目)

 更新时间:2023年02月02日 10:54:06   作者:dreamer_0423  
这篇文章主要介绍了SpringBoot使用过滤器、拦截器和监听器(Springboot搭建java项目),本文是基于Springboot搭建java项目,结合案例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

SpringBoot使用过滤器、拦截器和监听器

一、SpringBoot使用过滤器

Spring boot过滤器的使用(两种方式)

  • 使用spring boot提供的FilterRegistrationBean注册Filter
  • 使用原生servlet注解定义Filter

两种方式的本质都是一样的,都是去FilterRegistrationBean注册自定义Filter

方式一:

第一步:先定义Filter。

import javax.servlet.*;
import java.io.IOException;
public class MyFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        // do something 处理request 或response
        System.out.println("filter1");
        // 调用filter链中的下一个filter
        filterChain.doFilter(servletRequest,servletResponse);
    }
    @Override
    public void destroy() {
    }
}

第二步:注册自定义Filter

@Configuration
public class FilterConfig {
    @Bean
    public FilterRegistrationBean registrationBean() {
        FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(new MyFilter());
        filterRegistrationBean.addUrlPatterns("/*");
        filterRegistrationBean.setOrder(1);//定义过滤器的执行先后顺序  值越小越先执行 不影响Bean的加载顺序
        return filterRegistrationBean;
    }
}

方式二:

// 注入spring容器
@Order(1)//定义过滤器的执行先后顺序  值越小越先执行 不影响Bean的加载顺序
@Component
// 定义filterName 和过滤的url
@WebFilter(filterName = "my2Filter" ,urlPatterns = "/*")
public class My2Filter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("filter2");
    }
    @Override
    public void destroy() {
    }
}

二、SpringBoot使用拦截器

第一步:定义拦截器

public class MyInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("preHandle");
        return true;
    }
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {
        System.out.println("postHandle");
    }
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {
        System.out.println("afterCompletion");
    }
}

第二步:配置拦截器

@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new MyInterceptor());
    }
}

三、过滤器和拦截器的执行顺序

过滤器的执行顺序是安装@Order注解中的值,或者是setOrder()中值的进行执行顺序排序的,值越小就越靠前。

拦截器则是先声明的拦截器 preHandle() 方法先执行,而postHandle()方法反而会后执行。也即是:postHandle() 方法被调用的顺序跟 preHandle() 居然是相反的。如果实际开发中严格要求执行顺序,那就需要特别注意这一点。

四、SpringBoot使用监听器

1、统计网站最多在线人数监听器的例子

/**
 * 上下文监听器,在服务器启动时初始化onLineCount和maxOnLineCount两个变量,
 * 并将其置于服务器上下文(ServletContext)中,其初始值都是0。
 */
@WebListener
public class InitListener implements ServletContextListener {
    public void contextDestroyed(ServletContextEvent evt) {
    }
    public void contextInitialized(ServletContextEvent evt) {
        evt.getServletContext().setAttribute("onLineCount", 0);
        evt.getServletContext().setAttribute("maxOnLineCount", 0);
    }
}
/**
 * 会话监听器,在用户会话创建和销毁的时候根据情况修改onLineCount和maxOnLineCount的值。
 */
@WebListener
public class MaxCountListener implements HttpSessionListener {
    public void sessionCreated(HttpSessionEvent event) {
        ServletContext ctx = event.getSession().getServletContext();
        int count = Integer.parseInt(ctx.getAttribute("onLineCount").toString());
        count++;
        ctx.setAttribute("onLineCount", count);
        int maxOnLineCount = Integer.parseInt(ctx.getAttribute("maxOnLineCount").toString());
        if (count > maxOnLineCount) {
            ctx.setAttribute("maxOnLineCount", count);
            DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            ctx.setAttribute("date", df.format(new Date()));
        }
    }
    public void sessionDestroyed(HttpSessionEvent event) {
        ServletContext app = event.getSession().getServletContext();
        int count = Integer.parseInt(app.getAttribute("onLineCount").toString());
        count--;
        app.setAttribute("onLineCount", count);
    }
}

新建一个servlet处理

@WebServlet(name = "SessionServlet",value = "/sessionCount")
public class SessionServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html");
        //获取上下文对象
        ServletContext servletContext = this.getServletContext();
        Integer onLineCount = (Integer) servletContext.getAttribute("onLineCount");
        System.out.println("invoke doGet");
        PrintWriter out = resp.getWriter();
        out.println("<html><body>");
        out.println("<h1>" + onLineCount + "</h1>");
        out.println("</body></html>");
    }
}

2、springboot监听器的使用(以实现异步Event监听为例子)

定义事件类 Event

创建一个类,继承ApplicationEvent,并重写构造函数。ApplicationEvent是Spring提供的所有应用程序事件扩展类。

public class Event extends ApplicationEvent {
    private static final long serialVersionUID = 1L;
    private String msg ;
    private static final Logger logger=LoggerFactory.getLogger(Event.class);
    public Event(String msg) {
        super(msg);
        this.msg = msg;
        logger.info("add event success! message: {}", msg);
    }
    public String getMsg() {
        return msg;
    }
    public void setMsg(String msg) {
        this.msg = msg;
    }
}

创建一个用于监听指定事件的类,需要实现ApplicationListener接口,说明它是一个应用程序事件的监听类。注意这里需要加上@Component注解,将其注入Spring容器中。

@Component
public class MyListener implements ApplicationListener<Event>{
    private static final Logger logger= LoggerFactory.getLogger(MyListener.class);
    @Override
    public void onApplicationEvent(Event event) {
        logger.info("listener get event,sleep 2 second...");
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        logger.info("event msg is:{}",event.getMsg());
    }
}

事件发布
事件发布很简单,只需要使用Spring 提供的ApplicationEventPublisher来发布自定义事件

@Autowired 注入ApplicationEventPublisher

@RequestMapping("/notice/{msg}")
    public void notice(@PathVariable String msg){
        logger.info("begin>>>>>");
        applicationEventPublisher.publishEvent(new Event(msg));
        logger.info("end<<<<<<<");
    }

到此这篇关于SpringBoot使用过滤器、拦截器和监听器(Springboot搭建java项目)的文章就介绍到这了,更多相关SpringBoot使用过滤器、拦截器和监听器内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 浅谈使用setBounds()方法需要注意的地方

    浅谈使用setBounds()方法需要注意的地方

    下面小编就为大家带来一篇浅谈使用setBounds()方法需要注意的地方。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-05-05
  • Java 基础全面讲解StringBuffer类的使用

    Java 基础全面讲解StringBuffer类的使用

    当对字符串进行修改的时候,需要使用 StringBuffer 和 StringBuilder类,和String类不同的是,StringBuffer和 StringBuilder类的对象能够被多次的修改,并且不产生新的未使用对象
    2022-01-01
  • 一篇文章带你入门java算术运算符(加减乘除余,字符连接)

    一篇文章带你入门java算术运算符(加减乘除余,字符连接)

    这篇文章主要介绍了Java基本数据类型和运算符,结合实例形式详细分析了java基本数据类型、数据类型转换、算术运算符、逻辑运算符等相关原理与操作技巧,需要的朋友可以参考下
    2021-08-08
  • 浅谈Java中各种修饰符与访问修饰符的说明

    浅谈Java中各种修饰符与访问修饰符的说明

    下面小编就为大家带来一篇浅谈Java中各种修饰符与访问修饰符的说明。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-01-01
  • Java经典面试题最全汇总208道(一)

    Java经典面试题最全汇总208道(一)

    这篇文章主要介绍了Java经典面试题最全汇总208道(一),本文章内容详细,该模块分为了六个部分,本次为第一部分,需要的朋友可以参考下
    2023-01-01
  • Java 自定义线程池和线程总数控制操作

    Java 自定义线程池和线程总数控制操作

    这篇文章主要介绍了Java 自定义线程池和线程总数控制操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-02-02
  • 2020年支持java8的Java反编译工具汇总(推荐)

    2020年支持java8的Java反编译工具汇总(推荐)

    这篇文章主要介绍了2020年支持java8的Java反编译工具汇总,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-06-06
  • Java手写图书管理基本功能附代码

    Java手写图书管理基本功能附代码

    随着网络技术的高速发展,计算机应用的普及,利用计算机对图书馆的日常工作进行管理势在必行,本篇文章手把手带你用Java实现一个图书管理系统,大家可以在过程中查缺补漏,提升水平
    2022-04-04
  • mybatis where 标签使用

    mybatis where 标签使用

    where标记的作用类似于动态sql中的set标记,本文主要介绍了mybatis where 标签使用,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-03-03
  • 关于Spring @Transactional事务传播机制详解

    关于Spring @Transactional事务传播机制详解

    我们日常工作中极少使用事务传播级别,单纯只是使用事务和rollbackfor抛出异常来解决事务问题,但其实我们很多时候使用的是不正确的,或者说会造成事务粒度过大,本文详解一下事务传播级别,也让自己更好地处理事务问题,需要的朋友可以参考下
    2023-08-08

最新评论