springboot中的过滤器、拦截器、监听器整合使用
文章目錄
- controller層
- 過濾器
- 攔截器
- 攔截器介紹
- 使用攔截器
- 監(jiān)聽器
- 監(jiān)聽器介紹
- 使用監(jiān)聽器
- 修改啟動類
controller層
用于測試
@RestController public class TestController {@GetMapping("/addSession")public String addSession(HttpServletRequest request) {HttpSession session = request.getSession();session.setAttribute("name", "dalaoyang");return "當(dāng)前在線人數(shù)" + MyHttpSessionListener.online;}@GetMapping("/removeSession")public String removeSession(HttpServletRequest request) {HttpSession session = request.getSession();session.invalidate();return "當(dāng)前在線人數(shù)" + MyHttpSessionListener.online;}@GetMapping("/online")public String online() {return "當(dāng)前在線人數(shù):" + MyHttpSessionListener.online + "人";} }過濾器
過濾器的英文名稱為Filter,是Servlet技術(shù)中最實用的技術(shù)。如同它的名字一樣,過濾器是處于客戶端與服務(wù)器資源文件之間的一道過濾網(wǎng),幫助我們過濾一些不符合要求的請求。通常它被用作Session校驗,判斷用戶權(quán)限,如果不符合設(shè)定條件,就會被攔截到特殊的地址或者給予特殊的響應(yīng)。 2. 使用過濾器 使用過濾器很簡單,只需要實現(xiàn)Filter類,然后重寫它的3個方法即可。 · init方法:在容器中創(chuàng)建當(dāng)前過濾器的時候自動調(diào)用這個方法。 · destory方法:在容器中銷毀當(dāng)前過濾器的時候自動調(diào)用這個方法。 · doFilter方法:這個方法有3個參數(shù),分別是ServletRequest、ServletResponse和FilterChain。可以從參數(shù)中獲取HttpServletRequest和HttpServletResponse對象進行相應(yīng)的處理操作。 接下來,我們直接創(chuàng)建一個過濾器MyFilter。這里做一些URL的攔截,如果符合條件,就正常跳轉(zhuǎn),如果不符合條件,就攔截到/online請求中。
public class MyFilter implements Filter {@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {System.out.println("MyFilter被調(diào)用");HttpServletRequest httpServletRequest = (HttpServletRequest) request;HttpServletResponseWrapper wrapper = new HttpServletResponseWrapper((HttpServletResponse) response);//只有符合條件的可以直接請求,不符合的跳轉(zhuǎn)到/online請求去String requestUri = httpServletRequest.getRequestURI();System.out.println("請求地址是:"+requestUri);if (requestUri.indexOf("/addSession") != -1|| requestUri.indexOf("/removeSession") != -1|| requestUri.indexOf("/online") != -1|| requestUri.indexOf("/favicon.ico") != -1) {chain.doFilter(request, response);} else {wrapper.sendRedirect("/online");}}@Overridepublic void init(FilterConfig filterConfig) throws ServletException {//在服務(wù)啟動時初始化System.out.println("初始化攔截器");}@Overridepublic void destroy() {//在服務(wù)關(guān)閉是銷毀System.out.println("銷毀攔截器");} }攔截器
攔截器介紹
Java中的攔截器是動態(tài)攔截action調(diào)用的對象,然后提供了可以在action執(zhí)行前后增加一些操作,也可以在action執(zhí)行前停止操作。其實攔截器也可以做和過濾器同樣的操作,以下是攔截器的常用場景。
登錄認證:在一些簡單應(yīng)用中,可能會通過攔截器來驗證用戶的登錄狀態(tài),如果沒有登錄或者登錄失效,就會給用戶一個友好的提示或者返回登錄頁面。
記錄系統(tǒng)日志:在Web應(yīng)用中,通常需要記錄用戶的請求信息,比如請求的IP、方法執(zhí)行時常等,通過這些記錄可以監(jiān)控系統(tǒng)的狀況,以便于對系統(tǒng)進行信息監(jiān)控、信息統(tǒng)計、計算PV(Page View)和性能調(diào)優(yōu)等。 ·
通用處理:在應(yīng)用程序中可能存在所有方法都要返回的信息,這時可以使用攔截器來實現(xiàn),省去每個方法冗余重復(fù)的代碼實現(xiàn)。
使用攔截器
這里以使用Spring攔截器為例,在類上需要實現(xiàn)HandlerInterceptor類,并且重寫類中的3個方法,分別是: ·
???preHandle 在業(yè)務(wù)處理器處理請求之前被調(diào)用,返回值是boolean值,如果返回true,就進行下一步操作;若返回false,則證明不符合攔截條件。在失敗的時候不會包含任何響應(yīng),此時需要調(diào)用對應(yīng)的response返回對應(yīng)響應(yīng)。 ·
???postHandle 在業(yè)務(wù)處理器處理請求執(zhí)行完成后、生成視圖前執(zhí)行。這個方法可以通過方法參數(shù)ModelAndView對視圖進行處理,當(dāng)然ModelAndView也可以設(shè)置為null。 ·
???afterCompletion 在DispatcherServlet完全處理請求后被調(diào)用,通常用于記錄消耗時間,也可以進行一些資源處理操作。 接下來,創(chuàng)建一個自定義攔截器MyInterceptor,我們用這個攔截器打印請求的耗時,并且判斷當(dāng)前的瀏覽器是否存在Session。
@Component public class MyInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {System.out.println("preHandle被調(diào)用");request.setAttribute("startTime", System.currentTimeMillis());//request.setAttribute將值添加到了http請求頭上//request.getAttribute表示從request范圍取得設(shè)置的屬性,必須要先setAttribute設(shè)置屬性,才能通過getAttribute來取得,設(shè)置與取得的為Object對象類型 。 //request.setAttribute (“curruser”, curruser)這個方法是將curruser這個對象保存在request作用域中,然后在轉(zhuǎn)發(fā)進入的頁面就可以獲取到你的值,return true;}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {System.out.println("postHandle被調(diào)用");HttpSession session = request.getSession();String name = (String) session.getAttribute("name");if("dalao".equals(name)){System.out.println("--------------------當(dāng)前瀏覽器存在session");}}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {System.out.println("afterCompletion被調(diào)用");long startTime = (Long) request.getAttribute("startTime");System.out.println("--------------------請求耗時:" + (System.currentTimeMillis() - startTime));} }監(jiān)聽器
監(jiān)聽器介紹
???ServletContextListener:用來監(jiān)聽ServletContext屬性的操作,比如新增、修改、刪除。 ·
???HttpSessionListener:用來監(jiān)聽Web應(yīng)用中的Session對象,通常用于統(tǒng)計在線情況。 ·
???ServletRequestListener:用來監(jiān)聽Request對象的屬性操作。
使用監(jiān)聽器
使用監(jiān)聽器的話,只需要在類中實現(xiàn)對應(yīng)功能的監(jiān)聽器對象,如本文使用的HttpSessionListener。下面以監(jiān)聽Session信息為例統(tǒng)計在線人數(shù)。新建一個MyHttpSessionListener類,實現(xiàn)HttpSessionListener類,在類中定義一個全局變量online,當(dāng)創(chuàng)建Session時,online的數(shù)量加1;當(dāng)銷毀Session時,online的數(shù)量減1
MyHttpSessionListener完整內(nèi)容:
修改啟動類
過濾器、監(jiān)聽器和攔截器我們已經(jīng)創(chuàng)建好了,但是還不能引用。接下來我們修改Spring Boot啟動類,在類中通過注入Bean的方式引用三者。啟動類完整內(nèi)容如代碼清單11-16所示(也可以使用其他方法引用,比如創(chuàng)建一個配置類統(tǒng)一管理)。
@SpringBootApplication public class Chapter114Application implements WebMvcConfigurer {public static void main(String[] args) {SpringApplication.run(Chapter114Application.class, args);}@Autowiredprivate MyInterceptor myInterceptor;@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(myInterceptor);}@Beanpublic FilterRegistrationBean filterRegist() {FilterRegistrationBean frBean = new FilterRegistrationBean();frBean.setFilter(new MyFilter());frBean.addUrlPatterns("/*");return frBean;}@Beanpublic ServletListenerRegistrationBean listenerRegist() {ServletListenerRegistrationBean srb = new ServletListenerRegistrationBean();srb.setListener(new MyHttpSessionListener());return srb;} }測試:
換一個瀏覽器:
在瀏覽器輸入非online addsession removesession等的其他地址,會自動跳轉(zhuǎn)到online:
總結(jié)
以上是生活随笔為你收集整理的springboot中的过滤器、拦截器、监听器整合使用的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 案例代码:springboot+shir
- 下一篇: 【学习笔记】cookie、session