日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

SpringBoot拦截器与过滤器

發布時間:2025/3/15 javascript 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 SpringBoot拦截器与过滤器 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、攔截器與過濾器

在講Spring boot之前,我們先了解一下過濾器和攔截器。這兩者在功能方面很類似,但是在具體技術實現方面,差距還是比較大的。在分析兩者的區別之前,我們先理解一下AOP的概念,AOP不是一種具體的技術,而是一種編程思想。在面向對象編程的過程中,我們很容易通過繼承、多態來解決縱向擴展。但是對于橫向的功能,比如,在所有的service方法中開啟事務,或者統一記錄日志等功能,面向對象的是無法解決的。所以AOP——面向切面編程其實是面向對象編程思想的一個補充。而我們今天講的過濾器和攔截器都屬于面向切面編程的具體實現。而兩者的主要區別包括以下幾個方面:

  • Filter是依賴于Servlet容器,屬于Servlet規范的一部分,而攔截器則是獨立存在的,可以在任何情況下使用。

  • Filter的執行由Servlet容器回調完成,而攔截器通常通過動態代理的方式來執行。

  • Filter的生命周期由Servlet容器管理,而攔截器則可以通過IoC容器來管理,因此可以通過注入等方式來獲取其他Bean的實例,因此使用會更方便。

二、過濾器的配置

現在我們通過過濾器來實現記錄請求執行時間的功能,其實現如下:

public class LogCostFilter implements Filter {@Overridepublic void init(FilterConfig filterConfig) throws ServletException {}@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {long start = System.currentTimeMillis();filterChain.doFilter(servletRequest,servletResponse);System.out.println("Execute cost="+(System.currentTimeMillis()-start));}@Overridepublic void destroy() {} }

這段代碼的邏輯比較簡單,就是在方法執行前先記錄時間戳,然后通過過濾器鏈完成請求的執行,在返回結果之間計算執行的時間。這里需要主要,這個類必須繼承Filter類,這個是Servlet的規范,這個跟以前的Web項目沒區別。但是,有了過濾器類以后,以前的web項目可以在web.xml中進行配置,但是spring boot項目并沒有web.xml這個文件,那怎么配置?在Spring boot中,我們需要FilterRegistrationBean來完成配置。其實現過程如下:

@Configuration public class FilterConfig {@Beanpublic FilterRegistrationBean registFilter() {FilterRegistrationBean registration = new FilterRegistrationBean();registration.setFilter(new LogCostFilter());registration.addUrlPatterns("/*");registration.setName("LogCostFilter");registration.setOrder(1);return registration;}}

這樣配置就完成了,需要配置的選項主要包括實例化Filter類,然后指定url的匹配模式,設置過濾器名稱和執行順序,這個過程和在web.xml中配置其實沒什么區別,只是形式不同而已。現在我們可以啟動服務器訪問任意URL:
可以看到上面的配置已經生效了。除了通過 FilterRegistrationBean 來配置以外,還有一種更直接的辦法,直接通過注解就可以完成了:

@WebFilter(urlPatterns = "/*", filterName = "logFilter2") public class LogCostFilter2 implements Filter {@Overridepublic void init(FilterConfig filterConfig) throws ServletException {}@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {long start = System.currentTimeMillis();filterChain.doFilter(servletRequest, servletResponse);System.out.println("LogFilter2 Execute cost=" + (System.currentTimeMillis() - start));}@Overridepublic void destroy() {} }

這里直接用@WebFilter就可以進行配置,同樣,可以設置url匹配模式,過濾器名稱等。這里需要注意一點的是@WebFilter這個注解是Servlet3.0的規范,并不是Spring boot提供的。除了這個注解以外,我們還需在配置類中加另外一個注解:@ServletComponetScan,指定掃描的包。

@SpringBootApplication @MapperScan("com.pandy.blog.dao") @ServletComponentScan("com.pandy.blog.filters") public class Application {public static void main(String[] args) throws Exception {SpringApplication.run(Application.class, args);} }


現在,我們再來訪問一下任意URL:

可以看到,我們配置的兩個過濾器都生效了。細心的讀者會發現,第二個Filter我們并沒有指定執行的順序,但是卻在第一個Filter之前執行。這里需要解釋一下,@WebFilter這個注解并沒有指定執行順序的屬性,其執行順序依賴于Filter的名稱,是根據Filter類名(注意不是配置的filter的名字)的字母順序倒序排列,并且@WebFilter指定的過濾器優先級都高于FilterRegistrationBean配置的過濾器。

三、springboot攔截器的配置

上面我們已經介紹了過濾器的配置方法,接下來我們再來看看如何配置一個攔截器。其實spring boot攔截器的配置方式和springMVC差不多,只有一些小的改變需要注意下就ok了。下面主要介紹兩種常用的攔截器:

  • 基于URL實現的攔截器:
  • public class LoginInterceptor extends HandlerInterceptorAdapter{/*** 在請求處理之前進行調用(Controller方法調用之前)* 基于URL實現的攔截器* @param request* @param response* @param handler* @return* @throws Exception*/@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {String path = request.getServletPath();if (path.matches(Const.NO_INTERCEPTOR_PATH)) {//不需要的攔截直接過return true;} else {// 這寫你攔截需要干的事兒,比如取緩存,SESSION,權限判斷等System.out.println("====================================");return true;}} }

    關鍵代碼:path.matches(Const.NO_INTERCEPTOR_PATH 就是基于正則匹配的url。

    /*** @author BianP* @explain 常量類*/ public class Const {public static final String SUCCESS = "SUCCESS";public static final String ERROR = "ERROR";public static final String FIALL = "FIALL";/**********************對象和個體****************************/public static final String SESSION_USER = "loginedAgent"; // 用戶對象public static final String SESSION_LOGINID = "sessionLoginID"; // 登錄IDpublic static final String SESSION_USERID = "sessionUserID"; // 當前用戶對象ID編號public static final String SESSION_USERNAME = "sessionUserName"; // 當前用戶對象ID編號public static final Integer PAGE = 10; // 默認分頁數public static final String SESSION_URL = "sessionUrl"; // 被記錄的urlpublic static final String SESSION_SECURITY_CODE = "sessionVerifyCode"; // 登錄頁驗證碼// 時間 緩存時間public static final int TIMEOUT = 1800;// 秒public static final String ON_LOGIN = "/logout.htm";public static final String LOGIN_OUT = "/toLogout";// 不驗證URL anon:不驗證/authc:受控制的public static final String NO_INTERCEPTOR_PATH =".*/((.css)|(.js)|(images)|(login)|(anon)).*"; }
  • 基于注解的攔截器
    ①創建注解:
  • /*** 在需要登錄驗證的Controller的方法上使用此注解*/ @Target({ElementType.METHOD})// 可用在方法名上 @Retention(RetentionPolicy.RUNTIME)// 運行時有效 public @interface LoginRequired {}

    ②創建攔截器:

    public class AuthorityInterceptor extends HandlerInterceptorAdapter{@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {// 如果不是映射到方法直接通過if (!(handler instanceof HandlerMethod)) {return true;}// ①:START 方法注解級攔截器HandlerMethod handlerMethod = (HandlerMethod) handler;Method method = handlerMethod.getMethod();// 判斷接口是否需要登錄LoginRequired methodAnnotation = method.getAnnotation(LoginRequired.class);// 有 @LoginRequired 注解,需要認證if (methodAnnotation != null) {// 這寫你攔截需要干的事兒,比如取緩存,SESSION,權限判斷等System.out.println("====================================");return true;}return true;} }
  • 把攔截器添加到配置中,相當于SpringMVC時的配置文件干的事兒:
  • /*** 和springmvc的webmvc攔截配置一樣* @author BIANP*/ @Configuration public class WebConfigurer implements WebMvcConfigurer {@Overridepublic void addInterceptors(InterceptorRegistry registry) {// 攔截所有請求,通過判斷是否有 @LoginRequired 注解 決定是否需要登錄registry.addInterceptor(LoginInterceptor()).addPathPatterns("/**");registry.addInterceptor(AuthorityInterceptor()).addPathPatterns("/**");}@Beanpublic LoginInterceptor LoginInterceptor() {return new LoginInterceptor();}@Beanpublic AuthorityInterceptor AuthorityInterceptor() {return new AuthorityInterceptor();} }
  • 注意:
    • 一定要加@Configuration 這個注解,在啟動的時候在會被加載。

    • 有一些教程是用的“WebMvcConfigurerAdapter”,不過在spring5.0版本后這個類被丟棄了WebMvcConfigurerAdapter ,雖然還可以用,但是看起來不好。

    • 也有一些教程使用的WebMvcConfigurationSupport,我使用后發現,classpath:/META/resources/,classpath:/resources/,classpath:/static/,classpath:/public/)不生效。具體可以原因,大家可以看下源碼因為:WebMvcAutoConfiguration上有個條件注解: @ConditionalOnMissingBean(WebMvcConfigurationSupport.class)
      所以還是建議使用WebMvcConfigurer。

    其實springMVC很多東西,都可以搬到springboot中來使用,只需要把配置文件的模式,改成 對應@Configuration 類就好了。

    文章轉自
    文章轉自

    總結

    以上是生活随笔為你收集整理的SpringBoot拦截器与过滤器的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。