SpringBoot使用过滤器、拦截器和监听器的案例代码(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<<<<<<<");
 }
作者:dreamer_0423原文地址:https://blog.csdn.net/m0_46616045/article/details/128823964

%s 个评论

要回复文章请先登录注册