Java過濾器與監(jiān)聽器間區(qū)別與聯(lián)系
過濾器
過濾器可以對 Web 服務(wù)資源進(jìn)行過濾,過濾靜態(tài)資源如靜態(tài) HTML、CSS、JS、IMG 等,過濾動態(tài)資源如 JSP、Servlet 等,從而實(shí)現(xiàn)一些特殊的需求,比如 URL 訪問權(quán)限設(shè)置,過濾敏感詞匯,壓縮響應(yīng)信息。
自定義過濾器
定義一個過濾器實(shí)現(xiàn) Filter 接口,重寫三個方法
init() :該方法在容器啟動初始化過濾器時被調(diào)用,它在 Filter 的整個生命周期只會被調(diào)用一次。注意:這個方法必須執(zhí)行成功,否則過濾器會不起作用。
doFilter() :容器中的每一次請求都會調(diào)用該方法, FilterChain 用來調(diào)用下一個過濾器 Filter。
destroy(): 當(dāng)容器銷毀 過濾器實(shí)例時調(diào)用該方法,一般在方法中銷毀或關(guān)閉資源,在過濾器 Filter 的整個生命周期也只會被調(diào)用一次
@Slf4j public class WebMvcFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { String encoding = filterConfig.getInitParameter("encoding"); log.info("-1-----encoding: {} ----->", encoding); } @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { log.info("0-----doFilter----->"); filterChain.doFilter(servletRequest, servletResponse); } @Override public void destroy() { log.info("5-----destroy----->"); } }
定義一個配置類注冊過濾器并定義規(guī)則。
@Configuration public class WebFilterConfiguration { @Bean public FilterRegistrationBean getWebMvcFilter(){ FilterRegistrationBean<Filter> filterFilterRegistrationBean = new FilterRegistrationBean<>(); WebMvcFilter webMvcFilter = new WebMvcFilter(); filterFilterRegistrationBean.setFilter(webMvcFilter); filterFilterRegistrationBean.addUrlPatterns("/api/*"); filterFilterRegistrationBean.setName("WebMvcFilter"); filterFilterRegistrationBean.addInitParameter("encoding", "GBK"); filterFilterRegistrationBean.setOrder(1); return filterFilterRegistrationBean; } }
攔截器和過濾器的區(qū)別
- 過濾器依賴 Servlet 容器,攔截器不依賴 Servlet 容器。
- 過濾器基于容器的函數(shù)回調(diào),攔截器基于 Java 的反射機(jī)制。
- 過濾器幾乎可以過濾所有的請求,包括靜態(tài)和動態(tài)資源。攔截器只能攔截 Controller 層定義的路由請求,不處理靜態(tài)資源。
- 過濾器只能在容器初始化的時候調(diào)用一次,攔截器可以多次調(diào)用。
- 攔截器可以訪問 Controller 層中的方法和上下文,可以獲取 IOC 容器中的各種 Bean 并根據(jù)需求進(jìn)行處理。過濾器不支持訪問且不能獲取。
監(jiān)聽器
- 監(jiān)聽器可以監(jiān)聽 Web 中特定的事件。
- 監(jiān)聽器監(jiān)聽的是擁有作用域的對象,如 ServletContext、HttpSession 等。這些作用域?qū)ο蠓謩e都有相同的方法,如 setAttribute、getAttribute、removeAttribute,只要調(diào)用這幾個方法就會進(jìn)入到監(jiān)聽器對應(yīng)的方法中處理相應(yīng)的邏輯。
- 初始化上下文(Spring 容器的初始化,文件的解析)、會話的監(jiān)聽(在線人數(shù)),監(jiān)聽干預(yù)用戶信息(用戶資源傾斜)。
監(jiān)聽ServletContext 的 application 對象
@Component public class ServletContextListener implements ApplicationListener<ContextRefreshedEvent> { @Override public void onApplicationEvent(ContextRefreshedEvent event) { if (event.getApplicationContext().getParent() == null) { ApplicationContext applicationContext = event.getApplicationContext(); UserService userService = applicationContext.getBean(UserService.class); User user = userService.getUser(); ServletContext application = applicationContext.getBean(ServletContext.class); application.setAttribute("user", user); } } }
測試
@RestController @Slf4j public class UserController { @GetMapping("/api/getUser") public User getUser(HttpServletRequest request) { ServletContext servletContext = request.getServletContext(); User user = (User) servletContext.getAttribute("user"); log.info("user: {}", user); return user; } }
監(jiān)聽 HttpSession的 session 對象
定義一個監(jiān)聽器實(shí)現(xiàn) HttpSessionListener 接口,重寫兩個方法,獲取 session 會話對象,并將數(shù)據(jù)放到 HttpSession 的作用域?qū)ο?session 中。
@Component @Slf4j public class LoginSessionListener implements HttpSessionListener { public static Integer count = 0; @Override public void sessionCreated(HttpSessionEvent se) { log.info("新用戶上線..."); count++; se.getSession().getServletContext().setAttribute("personCount", count); } @Override public void sessionDestroyed(HttpSessionEvent se) { log.info("用戶下線了..."); count--; se.getSession().getServletContext().setAttribute("personCount", count); } }
測試
@RestController @Slf4j public class LoginController { @GetMapping("/getOnlineUser") public String getOnlineUser(HttpServletRequest request) { Integer personCount = (Integer) request.getServletContext().getAttribute("personCount"); log.info("登錄的人數(shù)是: {}", (personCount == null ? 0 : personCount)); return "登錄的人數(shù)是:" + (personCount == null ? 0 : personCount); } @GetMapping("logined") public String logined(HttpSession session) { session.setAttribute("user", new User(1L, "PlanMak1r", "123456")); log.info("登錄成功..."); return "success"; } @GetMapping("logout") public String logout(HttpSession session) { session.invalidate(); log.info("退出成功..."); return "success"; } }
到此這篇關(guān)于Java過濾器與監(jiān)聽器間區(qū)別與聯(lián)系的文章就介紹到這了,更多相關(guān)Java過濾器與監(jiān)聽器內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Mac中IntelliJ IDEA 2019.1注冊過程分享
這篇文章主要介紹了Mac中IntelliJ IDEA 2019.1注冊過程,本文給大家分享到腳本之家平臺供大家學(xué)習(xí),需要的朋友可以參考下2020-02-02Java實(shí)現(xiàn)經(jīng)典游戲黃金礦工的示例代碼
《黃金礦工》游戲是一個經(jīng)典的抓金子小游戲,它可以鍛煉人的反應(yīng)能力。本文將用Java實(shí)現(xiàn)這一經(jīng)典的游戲,感興趣的小伙伴可以了解一下2022-02-02SpringSecurity實(shí)現(xiàn)前后端分離登錄token認(rèn)證詳解
目前市面上比較流行的權(quán)限框架主要實(shí)Shiro和Spring Security,這兩個框架各自側(cè)重點(diǎn)不同,各有各的優(yōu)劣,本文將給大家詳細(xì)介紹SpringSecurity如何實(shí)現(xiàn)前后端分離登錄token認(rèn)證2023-06-06Java中System.setProperty()用法與實(shí)際應(yīng)用場景
System.setProperty是Java中用于設(shè)置系統(tǒng)屬性的方法,它允許我們在運(yùn)行時為Java虛擬機(jī)(JVM)或應(yīng)用程序設(shè)置一些全局的系統(tǒng)屬性,下面這篇文章主要給大家介紹了關(guān)于Java中System.setProperty()用法與實(shí)際應(yīng)用場景的相關(guān)資料,需要的朋友可以參考下2024-04-04JSON復(fù)雜數(shù)據(jù)處理之Json樹形結(jié)構(gòu)數(shù)據(jù)轉(zhuǎn)Java對象并存儲到數(shù)據(jù)庫的實(shí)現(xiàn)
這篇文章主要介紹了JSON復(fù)雜數(shù)據(jù)處理之Json樹形結(jié)構(gòu)數(shù)據(jù)轉(zhuǎn)Java對象并存儲到數(shù)據(jù)庫的實(shí)現(xiàn)的相關(guān)資料,需要的朋友可以參考下2016-03-03一文總結(jié)RabbitMQ中的消息確認(rèn)機(jī)制
RabbitMQ消息確認(rèn)機(jī)制指的是在消息傳遞過程中,發(fā)送方發(fā)送消息后,接收方需要對消息進(jìn)行確認(rèn),以確保消息被正確地接收和處理,本文為大家整理了RabbitMQ中的消息確認(rèn)機(jī)制,需要的可以參考一下2023-06-06Java?深入理解創(chuàng)建型設(shè)計(jì)模式之抽象工廠模式
當(dāng)系統(tǒng)所提供的工廠所需生產(chǎn)的具體產(chǎn)品并不是一個簡單的對象,而是多個位于不同產(chǎn)品等級結(jié)構(gòu)中屬于不同類型的具體產(chǎn)品時需要使用抽象工廠模式,抽象工廠模式是所有形式的工廠模式中最為抽象和最具一般性的一種形態(tài)2022-02-02創(chuàng)建并運(yùn)行一個java線程方法介紹
這篇文章主要介紹了創(chuàng)建并運(yùn)行一個java線程,涉及線程代碼示例,具有一定參考價(jià)值,需要的朋友可以了解下。2017-11-11