基于Springboot搭建java项目(二十三)——SpringBoot使用过滤器拦截器和监听器
Posted dreamer_0423
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了基于Springboot搭建java项目(二十三)——SpringBoot使用过滤器拦截器和监听器相关的知识,希望对你有一定的参考价值。
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搭建java项目(二十三)——SpringBoot使用过滤器拦截器和监听器的主要内容,如果未能解决你的问题,请参考以下文章
Java网络商城项目 SpringBoot+SpringCloud+Vue 网络商城(SSM前后端分离项目)二十三(项目打包和部署)
SpringBoot和Vue集成视频播放组件——基于SpringBoot和Vue的后台管理系统项目系列博客(二十二)