Spring中的Filter、HandlerInterceptor和AOP


問題來源於我想打印請求和響應結構體,那么怎么做?
網上搜索到相關的有種方式都可以

  • Filter
  • HandlerInterceptor
  • AOP

對三個的關系不太熟,所以大概了解了一下

簡要梳理一下一個Spring應用服務處理請求的邏輯首先:

  • 客戶端請求
  • 服務器容器處理(tomcat)
  • 匹配Url的Filter依次執行
  • 匹配的Servlet(對於Spring來說,就是DispatcherServlet)
  • HandlerMapping找到對應的控制器
  • HandlerAdaptor調用匹配的控制器,在這一步執行前,會調用注冊的HandlerInterceptor
    • 注意這里調用的控制器,一般是通過Spring的DI注入的容器,如果有了AOP切面,則實際調用的可能是AOP生成的Proxy

所以這三者功能上都可以做

  • Filter在容器層,由容器調用。FIlter功能更強大,甚至可以改變Request,Response的請求內容
  • HandlerInterceptor在控制器方法執行前,可以看到有post/pre/afterCompletion方法對應處理的3個階段
  • AOP應該是可以做日志的最后一步了,下一步就到了邏輯了

Interceptor和Filter也試過了,最終選擇的是通過AOP來做,優點是這里直接可以獲取方法參數(通過ProceedingJoinPoint getArgs())。

而在Intercetpor和Filter中需要從Request/Response中直接操作流,由於流被讀取后無法再次讀取,所以一般用這種方法都要將流復制一份出來,看起來比較像hack。

這里AOP最大的限制在於Spring默認的代理模式,如果方法參數有類似@Valid的注解,會先執行校驗,如果校驗失敗,那么無法走進我們的AOP。

當然如果想要打印原始的請求參數(而不是方法的入參),那么也不能用AOP。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM