SpringBoot使用过滤器、拦截器和监听器的案例代码(Springboot搭建java项目)
dreamer_0423 人气:0SpringBoot使用过滤器、拦截器和监听器
一、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<<<<<<<"); }
加载全部内容