JAVA攔截器的三種實現方式

JAVA攔截器的三種實現方式

  • 一、java原生過濾器Filter
  • 二、springMVC攔截器
  • 三、aop切面實現攔截器

一、java原生過濾器Filter

/*** 自定義Filter* 對請求的header 過濾token** 過濾器Filter可以拿到原始的HTTP請求和響應的信息,*     但是拿不到你真正處理請求方法的信息,也就是方法的信息** @Component 注解讓攔截器注入Bean,從而讓攔截器生效* @WebFilter 配置攔截規則** 攔截順序:filter—>Interceptor-->ControllerAdvice-->@Aspect -->Controller**/
@Slf4j
@Component
@WebFilter(urlPatterns = {"/**"},filterName = "authFilter")
public class MyFilter implements Filter {@Overridepublic void init(FilterConfig filterConfig) throws ServletException {log.info("TokenFilter init {}",filterConfig.getFilterName());}@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {String param = request.getParameter("param");response.setContentType("text/html;charset=UTF-8");//獲取請求頭tokenString token = "";HttpServletRequest httpServletRequest = (HttpServletRequest) request;Enumeration<String> headerNames = httpServletRequest.getHeaderNames();while(headerNames.hasMoreElements()) {//判斷是否還有下一個元素String nextElement = headerNames.nextElement();//獲取headerNames集合中的請求頭if ("token".equals(nextElement)){token = httpServletRequest.getHeader(nextElement);log.info("請求頭key[" + nextElement + "]:" + token);}}log.info("doFilter-我攔截到了請求:"+ param);if (null != param && "pass".equals(param)){//驗證tokenif ("7758258xx".equals(token)){chain.doFilter(request,response);//到下一個鏈}else{response.getWriter().write("doFilter-請求頭token不通過");}}else{log.info("doFilter-參數param不符合條件");response.getWriter().write("doFilter-參數param不通過");}}@Overridepublic void destroy() {log.info("destroy");}
}

二、springMVC攔截器

/*** 自定義攔截器* 自定義攔截器后,需要配置進Spring** 攔截器Interceptor可以拿到原始的HTTP請求和響應的信息,*    也可以拿到你真正處理請求方法的信息,但是拿不到傳進參數的那個值。**攔截順序:filter—>Interceptor-->ControllerAdvice-->@Aspect -->Controller*/
@Slf4j
@Component
public class MyInterceptor implements HandlerInterceptor {/*** 在訪問Controller某個方法之前這個方法會被調用。* @param request* @param response* @param handler* @return false則表示不執行postHandle方法,true 表示執行postHandle方法* @throws Exception*/@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {log.info("Interceptor preHandle {}","");String token = request.getHeader("token");log.info("Interceptor preHandle token :{}",token);log.info("Interceptor preHandle uri {}",request.getRequestURL().toString());response.setContentType("text/html;charset=UTF-8");//spring boot 2.0對靜態資源也進行了攔截,當攔截器攔截到請求之后,// 但controller里并沒有對應的請求時,該請求會被當成是對靜態資源的請求。// 此時的handler就是 ResourceHttpRequestHandler,就會拋出上述錯誤。if (handler instanceof HandlerMethod){HandlerMethod handlerMethod = (HandlerMethod) handler;Method method = handlerMethod.getMethod();log.info("Token Interceptor preHandle getMethod {}",method.getName());}else if(handler instanceof ResourceHttpRequestHandler){//靜態資源ResourceHttpRequestHandler resourceHttpRequestHandler = (ResourceHttpRequestHandler) handler;log.info("Token Interceptor preHandle getMethod {}",resourceHttpRequestHandler.getMediaTypes());}if (!"7758258xx".equals(token)){response.getWriter().write("doInterceptor-請求頭token不通過");return false;}//false則表示不執行postHandle方法,不執行下一步chain鏈,直接返回responsereturn true;}/*** 請求處理之后進行調用,但是在視圖被渲染之前(Controller方法調用之后)* preHandle方法處理之后這個方法會被調用,如果控制器Controller出現了異常,則不會執行此方法* @param request* @param response* @param handler* @param modelAndView* @throws Exception*/@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {log.info("Interceptor postHandle");}/*** 不管有沒有異常,這個afterCompletion都會被調用* @param request* @param response* @param handler* @param ex* @throws Exception*/@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {log.info("Interceptor afterCompletion");}

三、aop切面實現攔截器

引入maven:

<dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId><version>1.9.4</version>
</dependency>
/*** @Description: 切面*/
@Slf4j
@Component  //表示它是一個Spring的組件
@Aspect  //表示它是一個切面
public class MyAspect {private static final Logger logger = LoggerFactory.getLogger(MyAspect.class);ThreadLocal<Long> startTime = new ThreadLocal<>();/*** 第一個*代表返回類型不限* 第二個*代表所有類* 第三個*代表所有方法* (..) 代表參數不限* com.zhangximing.springbootinterceptor.controller 測試的controller層*/@Pointcut("execution(public * com.zhangximing.springbootinterceptor.controller.*.*(..))")public void pointCut(){};@Before(value = "pointCut()")public void before(JoinPoint joinPoint){System.out.println("方法執行前執行......before");ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();HttpServletRequest request = attributes.getRequest();logger.info("<=====================================================");logger.info("請求來源: =》" + request.getRemoteAddr());logger.info("請求URL:" + request.getRequestURL().toString());logger.info("請求方式:" + request.getMethod());logger.info("響應方法:" + joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName());logger.info("請求參數:" + Arrays.toString(joinPoint.getArgs()));logger.info("連接點的方法簽名對象:"+joinPoint.getSignature());logger.info("連接點所在的目標對象:"+joinPoint.getTarget());logger.info("代理對象:"+joinPoint. getThis());logger.info("------------------------------------------------------");startTime.set(System.currentTimeMillis());}// 定義需要匹配的切點表達式,同時需要匹配參數/*** @description 要攔截修改參數的值只有使用這個方法,Around相當于before+after* @param pjp* @param arg 類型可以根據pointCut指定切點類下的方法確定,也可以使用統一的Object,也可以不寫參數* @return* @throws Throwable*/@Around("pointCut() && args(arg)")public Object around(ProceedingJoinPoint pjp, Object arg) throws Throwable{logger.info("入參:{}",arg);logger.info("方法環繞start...around");JSONObject param = JSONObject.parseObject(JSONObject.toJSONString(arg));if ("zxm".equals(param.getString("name"))){JSONObject result = new JSONObject();result.put("success",false);result.put("msg","error");return result;}param.put("exist",true);param.put("name","cml");//修改值Object[] objects = new Object[]{param};Object objectNew = pjp.proceed(objects);logger.info("方法環繞end...around");return objectNew;}@After("within(com.zhangximing.springbootinterceptor.controller.*)")public void after(){System.out.println("方法之后執行...after.");}/**** @param AjaxResult  rst 該參數類型需要與測試的Controller層的返回值類型一致,否則不生效,也就是找不到*            該測試中的AjaxResult是測試項目中封裝好的出參*/@AfterReturning(pointcut="pointCut()",returning = "rst")public void afterRunning(JSONObject rst){if(startTime.get() == null){startTime.set(System.currentTimeMillis());}System.out.println("方法執行完執行...afterRunning");logger.info("耗時(毫秒):" +  (System.currentTimeMillis() - startTime.get()));logger.info("返回數據:{}", rst);logger.info("==========================================>");}@AfterThrowing("within(com.zhangximing.springbootinterceptor.controller.*)")public void afterThrowing(){System.out.println("異常出現之后...afterThrowing");}
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/20263.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/20263.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/20263.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Java 基礎面試300題 (141- 170 )

Java 基礎面試300題 &#xff08;141- 170 &#xff09; 141. 編譯運行以下代碼時會發生什么&#xff1f; class Mammal {} class Cat extends Mammal { } List<Mammal> list new ArrayList<Cat>();上述代碼將出現編譯錯誤。這是因為為List指定了Mammal哺乳動物…

SpringSecurity6從入門到實戰之整合原生Filter鏈

SpringSecurity6從入門到實戰之整合原生Filter鏈 DelegatingFilterProxy 從官網上來進行學習可以看到第一個類就是DelegatingFilterProxy,我們首先看看官網給下的定義. Spring提供了一個名為DelegatingFilterProxy的過濾器實現&#xff0c;它允許在Servlet容器的生命周期和Spr…

Raid的全局熱備和獨立熱備

目錄 Hot Spare背景: 1.定義與功能 2.數據存儲與容量 3.配置模式 4.數量限制&#xff1a; 5.數據重建: 6.管理與維護 實操全局熱備和獨立熱備&#xff1a; 配置全局熱備: 配置獨立熱備: Hot Spare背景: 在RAID配置中&#xff0c;Hot Spare(熱備)是一個非常重要的概念…

amis源碼 Api接口調用解析:

Amis中傳入用戶自定義fetcher(基于fetcher做接口調用)&#xff1a; 1.embed渲染時可以傳入用戶定義的fetcher(接口調用)&#xff1a; import axios from "/libs/api.request"; //自定義的fetcher調用接口&#xff08;axios調用&#xff09; { fetcher: ()>{ ……

發現一個ai工具網站

網址 https://17yongai.com/ 大概看了下&#xff0c;這個網站收集的數據還挺有用的&#xff0c;有很多實用的ai教程。 懂ai工具的可以在這上面找找靈感。

善聽提醒遵循易經原則。世界大同只此一路。

如果說前路是一個大深坑&#xff0c;那必然是你之前做的事情做的不太好&#xff0c;當壞的時候&#xff0c;壞的結果來的時候&#xff0c;是因為你之前的行為&#xff0c;你也就不會再糾結了&#xff0c;會如何走出這個困境&#xff0c;是好的來了&#xff0c;不驕不躁&#xf…

事先預判事的結果事先預防從容應對防微杜漸

很多人呢&#xff0c;學習倪老師的知識&#xff0c;也都是從他的中醫方面&#xff0c;認識了他很多的東西呢&#xff0c;對于倪老師的知識性的總結的東西呢&#xff0c;不是很了解。 其實啊&#xff0c;倪老師也是一個&#xff0c;對于這種文化的傳承&#xff0c;有著很大很深刻…

一些匯編語言的總結

一、匯編語言的介紹 1、匯編語言和處理器指令集高度相關&#xff0c;不同指令集的匯編語言不兼容。 2、匯編語言是對機器語言的一種抽象&#xff0c;用英文字符來代表運算和控制指令&#xff0c;用英文字母和數字代表操作數。 二、常用的匯編語言 有 x86的匯編語言&#xff…

YOLOv10漲點改進:卷積魔改 | 分布移位卷積(DSConv),提高卷積層的內存效率和速度

??????本文改進內容: YOLOv10如何魔改卷積進一步提升檢測精度?提出了一種卷積的變體,稱為DSConv(分布偏移卷積),其可以容易地替換進標準神經網絡體系結構并且實現較低的存儲器使用和較高的計算速度。 DSConv將傳統的卷積內核分解為兩個組件:可變量化內核(VQK)和…

iOS編程入門:揭秘神秘的開發世界

iOS編程入門&#xff1a;揭秘神秘的開發世界 在數字化時代的浪潮中&#xff0c;iOS編程成為了許多開發者熱衷探索的領域。想要入門iOS編程&#xff0c;不僅需要掌握基礎知識&#xff0c;還需理解其獨特的生態系統。本文將通過四個方面、五個方面、六個方面和七個方面&#xff…

golang中通過反射獲取結構體Tag標簽定義的內容 函數和測試用例

當我們在go語言中定義結構體的時候&#xff0c; 經常需要給某些字段打上一個Tag標簽, 如 Name string json:"name" , 那這個標簽有和作用呢&#xff1f; 這個作用可大了&#xff0c;最為常用的是json序列化和反序列化&#xff0c; 還有各種ORM 的實體對象定義&…

C# yolov8 TensorRT +ByteTrack Demo

C# yolov8 TensorRT ByteTrack Demo 目錄 效果 說明 項目 代碼 Form2.cs YoloV8.cs ByteTracker.cs 下載 參考 效果 說明 環境 NVIDIA GeForce RTX 4060 Laptop GPU cuda12.1cudnn 8.8.1TensorRT-8.6.1.6 版本和我不一致的需要重新編譯TensorRtExtern.dll&…

微調醫療大模型,與通用大模型效果對比

下面是一份CT描述&#xff1a; “肝臟大小、形態未見明確異常。肝S2見一結節狀低密度影&#xff0c;大小約13x11mm&#xff0c;增強掃描呈明顯漸進性強化&#xff0c;延遲期呈等密度。余肝實質內未見異常密度影或強化灶。肝內大血管及其分支走行未見異常&#xff0c;肝門區層次…

ip地址告訴別人安全嗎?ip地址告訴別人會有什么風險

IP地址告訴別人安全嗎&#xff1f;在數字化時代&#xff0c;IP地址作為網絡連接的關鍵標識符&#xff0c;承載著重要的安全意義。然而&#xff0c;很多人可能并不清楚&#xff0c;輕易地將自己的IP地址告訴他人可能帶來一系列安全風險。那么&#xff0c;IP地址告訴別人會有什么…

文件夾損壞0字節:全面解析、恢復技巧與預防策略

在數字時代&#xff0c;數據的完整性和安全性至關重要。然而&#xff0c;我們時常會遭遇文件夾損壞并顯示為0字節的棘手問題。這種情況一旦發生&#xff0c;用戶可能會面臨數據丟失的風險。本文將詳細探討文件夾損壞0字節的現象&#xff0c;分析其背后的原因&#xff0c;并提供…

Redis-重定向

實驗環境&#xff08;3主3從的Redis-Cluster&#xff09; 一、Redis重定向基礎篇 1、MOVED重定向 Redis Custer 中&#xff0c;客戶端可以向集群中任意節點發送請求。此時當前節點先對 Key 進行 CRC 16 計算&#xff0c;然后按 16384 取模確定 Slot 槽。確定該 Slot 槽所對應的…

為什么使用短鏈系統?

短鏈接&#xff08;Short Link&#xff09;是指將一個原始的長 URL&#xff08;Uniform Resource Locator&#xff09;通過特定的算法或服務轉化為一個更短、易于記憶的 URL。短鏈接通常只包含幾個字符&#xff0c;而原始的長 URL 可能會非常長。 短鏈接的原理非常簡單&#x…

FPGA編程與PLC編程的區別:深入解析與對比

FPGA編程與PLC編程的區別&#xff1a;深入解析與對比 在工業自動化和控制系統領域&#xff0c;FPGA&#xff08;現場可編程門陣列&#xff09;編程和PLC&#xff08;可編程邏輯控制器&#xff09;編程都是關鍵的編程技術&#xff0c;但它們在應用、功能、結構和編程方法上存在…

IEEE編程語言排行榜:深度解析編程語言的四大維度、五大趨勢、六大熱門與七大挑戰

IEEE編程語言排行榜&#xff1a;深度解析編程語言的四大維度、五大趨勢、六大熱門與七大挑戰 在信息技術領域&#xff0c;編程語言排行榜一直是衡量各種編程語言流行度和影響力的重要指標。IEEE&#xff08;電氣電子工程師協會&#xff09;作為全球最具影響力的科技專業組織之…

【Java數據結構】詳解LinkedList與鏈表(二)

目錄 1.????前言~&#x1f973;&#x1f389;&#x1f389;&#x1f389; 2.反轉一個單鏈表 3. 找到鏈表的中間節點 4.輸入一個鏈表&#xff0c;輸出該鏈表中倒數第k個結點。 5.合并兩個有序鏈表 6.鏈表分割 7. 判定鏈表的回文結構 8.輸入兩個鏈表&#xff0c;找…