SpringBoot使用過濾器、攔截器和監(jiān)聽器的案例代碼(Springboot搭建java項目)
SpringBoot使用過濾器、攔截器和監(jiān)聽器
一、SpringBoot使用過濾器
Spring boot過濾器的使用(兩種方式)
- 使用spring boot提供的FilterRegistrationBean注冊Filter
- 使用原生servlet注解定義Filter
兩種方式的本質(zhì)都是一樣的,都是去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"); // 調(diào)用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);//定義過濾器的執(zhí)行先后順序 值越小越先執(zhí)行 不影響B(tài)ean的加載順序 return filterRegistrationBean; } }
方式二:
// 注入spring容器 @Order(1)//定義過濾器的執(zhí)行先后順序 值越小越先執(zhí)行 不影響B(tài)ean的加載順序 @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()); } }
三、過濾器和攔截器的執(zhí)行順序
過濾器的執(zhí)行順序是安裝@Order注解中的值,或者是setOrder()中值的進(jìn)行執(zhí)行順序排序的,值越小就越靠前。
攔截器則是先聲明的攔截器 preHandle() 方法先執(zhí)行,而postHandle()方法反而會后執(zhí)行。也即是:postHandle() 方法被調(diào)用的順序跟 preHandle() 居然是相反的。如果實際開發(fā)中嚴(yán)格要求執(zhí)行順序,那就需要特別注意這一點。
四、SpringBoot使用監(jiān)聽器
1、統(tǒng)計網(wǎng)站最多在線人數(shù)監(jiān)聽器的例子
/** * 上下文監(jiān)聽器,在服務(wù)器啟動時初始化onLineCount和maxOnLineCount兩個變量, * 并將其置于服務(wù)器上下文(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); } }
/** * 會話監(jiān)聽器,在用戶會話創(chuàng)建和銷毀的時候根據(jù)情況修改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監(jiān)聽器的使用(以實現(xiàn)異步Event監(jiān)聽為例子)
定義事件類 Event
創(chuàng)建一個類,繼承ApplicationEvent,并重寫構(gòu)造函數(shù)。ApplicationEvent是Spring提供的所有應(yīng)用程序事件擴(kuò)展類。
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; } }
創(chuàng)建一個用于監(jiān)聽指定事件的類,需要實現(xiàn)ApplicationListener接口,說明它是一個應(yīng)用程序事件的監(jiān)聽類。注意這里需要加上@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()); } }
事件發(fā)布
事件發(fā)布很簡單,只需要使用Spring 提供的ApplicationEventPublisher來發(fā)布自定義事件
@Autowired 注入ApplicationEventPublisher
@RequestMapping("/notice/{msg}") public void notice(@PathVariable String msg){ logger.info("begin>>>>>"); applicationEventPublisher.publishEvent(new Event(msg)); logger.info("end<<<<<<<"); }
到此這篇關(guān)于SpringBoot使用過濾器、攔截器和監(jiān)聽器(Springboot搭建java項目)的文章就介紹到這了,更多相關(guān)SpringBoot使用過濾器、攔截器和監(jiān)聽器內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Springboot利用Redis實現(xiàn)接口冪等性攔截
這篇文章主要為大家介紹了Springboot如何利用Redis實現(xiàn)接口冪等性攔截。本文將通過自定義注解+redis+攔截器+MD5?實現(xiàn),感興趣的可以了解一下2022-06-06淺談Java并發(fā) J.U.C之AQS:CLH同步隊列
AQS內(nèi)部維護(hù)著一個FIFO隊列,該隊列就是CLH同步隊列。下面小編來簡單介紹下這個隊列2019-05-05SpringBoot中自定義首頁(默認(rèn)頁)及favicon的方法
這篇文章主要介紹了SpringBoot中如何自定義首頁(默認(rèn)頁)及favicon,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-08-08