您好,登錄后才能下訂單哦!
這篇文章主要介紹了SpringBoot實現(xiàn)攔截器、過濾器、監(jiān)聽器過程解析,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
過濾器
過濾器簡介
過濾器的英文名稱為 Filter, 是 Servlet 技術(shù)中最實用的技術(shù)。如同它的名字一樣,過濾器是處于客戶端和服務(wù)器資源文件之間的一道過濾網(wǎng),幫助我們過濾掉一些不符合要求的請求,通常用作 Session 校驗,判斷用戶權(quán)限,如果不符合設(shè)定條件,則會被攔截到特殊的地址或者基于特殊的響應(yīng)。
過濾器的使用
首先需要實現(xiàn) Filter接口然后重寫它的三個方法
我們先引入 Maven 依賴,其中 lombok 是用來避免每個文件創(chuàng)建 Logger 來打印日志
<dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>
我們首先實現(xiàn)接口,重寫三個方法,對包含我們要求的四個請求予以放行,將其它請求攔截重定向至/online,只要在將MyFilter實例化后即可,我們在后面整合代碼中一起給出。
import lombok.extern.log4j.Log4j2; import org.springframework.stereotype.Component; import javax.servlet.*; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponseWrapper; import java.io.IOException; @Log4j2 public class MyFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { log.info("初始化過濾器"); } @Override public void doFilter(ServletRequest servletRequest, ServletResponse response, FilterChain filterChain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest)servletRequest; HttpServletResponseWrapper wrapper = new HttpServletResponseWrapper((HttpServletResponse) response); String requestUri = request.getRequestURI(); log.info("請求地址是:"+requestUri); if (requestUri.contains("/addSession") || requestUri.contains("/removeSession") || requestUri.contains("/online") || requestUri.contains("/favicon.ico")) { filterChain.doFilter(servletRequest, response); } else { wrapper.sendRedirect("/online"); } } @Override public void destroy() { //在服務(wù)關(guān)閉時銷毀 log.info("銷毀過濾器"); } }
攔截器
攔截器介紹
Java中的攔截器是動態(tài)攔截 action 調(diào)用的對象,然后提供了可以在 action 執(zhí)行前后增加一些操作,也可以在 action 執(zhí)行前停止操作,功能與過濾器類似,但是標準和實現(xiàn)方式不同。
使用攔截器
我們需要實現(xiàn) HandlerInterceptor 類,并且重寫三個方法
import lombok.extern.log4j.Log4j2; import org.springframework.stereotype.Component; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; @Log4j2 @Component public class MyInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { log.info("【MyInterceptor】調(diào)用了:{}", request.getRequestURI()); request.setAttribute("requestTime", System.currentTimeMillis()); return true; } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { if (!request.getRequestURI().contains("/online")) { HttpSession session = request.getSession(); String sessionName = (String) session.getAttribute("name"); if ("haixiang".equals(sessionName)) { log.info("【MyInterceptor】當(dāng)前瀏覽器存在 session:{}",sessionName); } } } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { long duration = (System.currentTimeMillis() - (Long)request.getAttribute("requestTime")); log.info("【MyInterceptor】[{}]調(diào)用耗時:{}ms",request.getRequestURI(), duration); } }
監(jiān)聽器
監(jiān)聽器簡介
監(jiān)聽器通常用于監(jiān)聽 Web 應(yīng)用程序中對象的創(chuàng)建、銷毀等動作的發(fā)送,同時對監(jiān)聽的情況作出相應(yīng)的處理,最常用于統(tǒng)計網(wǎng)站的在線人數(shù)、訪問量等。
監(jiān)聽器大概分為以下幾種:
監(jiān)聽器的使用
我們通過 HttpSessionListener來統(tǒng)計當(dāng)前在線人數(shù)、ip等信息,為了避免并發(fā)問題我們使用原子int來計數(shù)。
ServletContext,是一個全局的儲存信息的空間,它的生命周期與Servlet容器也就是服務(wù)器保持一致,服務(wù)器關(guān)閉才銷毀。request,一個用戶可有多個;session,一個用戶一個;而servletContext,所有用戶共用一個。所以,為了節(jié)省空間,提高效率,ServletContext中,要放必須的、重要的、所有用戶需要共享的線程又是安全的一些信息。因此我們這里用ServletContext來存儲在線人數(shù)sessionCount最為合適。
我們下面來統(tǒng)計當(dāng)前在線人數(shù)
import lombok.extern.log4j.Log4j2; import javax.servlet.http.HttpSessionEvent; import javax.servlet.http.HttpSessionListener; import java.util.concurrent.atomic.AtomicInteger; @Log4j2 public class MyHttpSessionListener implements HttpSessionListener { public static AtomicInteger userCount = new AtomicInteger(0); @Override public synchronized void sessionCreated(HttpSessionEvent se) { userCount.getAndIncrement(); se.getSession().getServletContext().setAttribute("sessionCount", userCount.get()); log.info("【在線人數(shù)】人數(shù)增加為:{}",userCount.get()); //此處可以在ServletContext域?qū)ο笾袨樵L問量計數(shù),然后傳入過濾器的銷毀方法 //在銷毀方法中調(diào)用數(shù)據(jù)庫入庫,因為過濾器生命周期與容器一致 } @Override public synchronized void sessionDestroyed(HttpSessionEvent se) { userCount.getAndDecrement(); se.getSession().getServletContext().setAttribute("sessionCount", userCount.get()); log.info("【在線人數(shù)】人數(shù)減少為:{}",userCount.get()); } }
過濾器、攔截器、監(jiān)聽器注冊
實例化三器
import com.anqi.tool.sanqi.filter.MyFilter; import com.anqi.tool.sanqi.interceptor.MyInterceptor; import com.anqi.tool.sanqi.listener.MyHttpRequestListener; import com.anqi.tool.sanqi.listener.MyHttpSessionListener; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.boot.web.servlet.ServletListenerRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration public class WebConfig implements WebMvcConfigurer { @Autowired MyInterceptor myInterceptor; @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(myInterceptor); } /** * 注冊過濾器 * @return */ @Bean public FilterRegistrationBean filterRegistrationBean(){ FilterRegistrationBean filterRegistration = new FilterRegistrationBean(); filterRegistration.setFilter(new MyFilter()); filterRegistration.addUrlPatterns("/*"); return filterRegistration; } /** * 注冊監(jiān)聽器 * @return */ @Bean public ServletListenerRegistrationBean registrationBean(){ ServletListenerRegistrationBean registrationBean = new ServletListenerRegistrationBean(); registrationBean.setListener(new MyHttpRequestListener()); registrationBean.setListener(new MyHttpSessionListener()); return registrationBean; } }
測試
import com.anqi.tool.sanqi.listener.MyHttpSessionListener; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; @RestController public class TestController { @GetMapping("addSession") public String addSession(HttpServletRequest request) { HttpSession session = request.getSession(); session.setAttribute("name", "haixiang"); return "當(dāng)前在線人數(shù)" + session.getServletContext().getAttribute("sessionCount") + "人"; } @GetMapping("removeSession") public String removeSession(HttpServletRequest request) { HttpSession session = request.getSession(); session.invalidate(); return "當(dāng)前在線人數(shù)" + session.getServletContext().getAttribute("sessionCount") + "人"; } @GetMapping("online") public String online() { return "當(dāng)前在線人數(shù)" + MyHttpSessionListener.userCount.get() + "人"; } }
以下是監(jiān)聽請求的監(jiān)聽器
import javax.servlet.ServletRequestEvent; import javax.servlet.ServletRequestListener; import javax.servlet.http.HttpServletRequest; public class MyHttpRequestListener implements ServletRequestListener { @Override public void requestDestroyed(ServletRequestEvent sre) { System.out.println("request 監(jiān)聽器被銷毀"); } @Override public void requestInitialized(ServletRequestEvent sre) { HttpServletRequest req = (HttpServletRequest) sre.getServletRequest(); String requestURI = req.getRequestURI(); System.out.println(requestURI+"--"+"被調(diào)用"); } }
攔截器與過濾器的區(qū)別
1.參考標準
2.實現(xiàn)方式
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持億速云。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。