Spring Security(一):RESTful API的攔截之過濾器、攔截器、切片介紹

Spring Security框架使用過程中會有很多Restful API的攔截操作,像各種過濾器攔截器以及Spring AOP的使用,所以在學習Spring Security之前很有必要對他們進行一個簡單介紹。

過濾器(Filter)

簡介

  • JavaWeb三大組件(Servlet、Filter、Listener)之一,Web開發人員通過Filter技術,對web服務器管理的所有web資源(例如Jsp、Servlet、靜態圖片文件或靜態html文件等)進行攔截,從而實現一些特殊的功能。

使用場景

  • 主要用於對用戶請求進行預處理,也可以對HttpServletResponse進行後處理
  • 使用Filter的完整流程:Filter對用戶請求進行預處理,接着將請求交給Servlet進行處理並生成響應,最後Filter再對服務器響應進行後處理。

簡單演示

/**
 * 過濾器演示:直接定義一個類實現Filter接口,記得需要配置該過濾器,或者直接加@Component自動配置
 *
 * @author HuaDong
 * @date 2020/4/11 18:38
 */
@Component
public class TimeFilter implements Filter {

    /**
     * 容器銷燬的時候調用
     */
    @Override
    public void destroy() {
        System.out.println("time filter destroy");
    }

    /**
     * Web服務器每次在調用Web資源之前,都會先調用filter的doFilter方法
     */
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        System.out.println("time filter start");
        long start = System.currentTimeMillis();
        chain.doFilter(request, response);
        System.out.println("time filter 耗時:" + (System.currentTimeMillis() - start));
        System.out.println("time filter finish");
    }

    /**
     * 容器啓動時候調用
     */
    @Override
    public void init(FilterConfig arg0) throws ServletException {
        System.out.println("time filter init");
    }
}

攔截器(Interceptor)

簡介

  • Java 裏的攔截器是動態攔截 action 調用的對象,它提供了一種機制可以使開發者可以定義在一個 action 執行的前後執行的代碼,也可以在一個 action 執行前阻止其執行,同時也提供了一種可以提取 action 中可重用部分的方式。通俗來說就是可以攔截一個請求,對請求進行Controller方法的調用之前之後或者拋出異常時的一個自定義的操作。

使用場景

  • 可以對請求進行一個登錄憑證的校驗
  • 可以對請求響應之後加上一些統一的響應字段等。

簡單演示

  • 聲明攔截器
/**
 * 攔截器演示:定義一個類實現HandlerInterceptor接口
 *
 * @author HuaDong
 * @date 2020/4/11 19:21
 */
@Component
public class TimeInterceptor implements HandlerInterceptor {

    /**
     * 請求Controller方法之前:返回false表示被攔截不再往下執行,即不再調用Controller方法
     */
	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
		System.out.println("preHandle");
		
		System.out.println(((HandlerMethod)handler).getBean().getClass().getName());
		System.out.println(((HandlerMethod)handler).getMethod().getName());
		
		request.setAttribute("startTime", System.currentTimeMillis());
		return true;
	}

    /**
     * 請求Controller方法之後
     */
	@Override
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
			ModelAndView modelAndView) throws Exception {
		System.out.println("postHandle");
		Long start = (Long) request.getAttribute("startTime");
		System.out.println("time interceptor 耗時:"+ (System.currentTimeMillis() - start));
	}

	/**
     * 拋出異常之後 postHandle 方法不會被調用,無論是否拋出異常 afterCompletion 方法都會被調用
     */
	@Override
	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
			throws Exception {
		System.out.println("afterCompletion");
		Long start = (Long) request.getAttribute("startTime");
		System.out.println("time interceptor 耗時:"+ (System.currentTimeMillis() - start));
		System.out.println("ex is "+ex);
	}
}
  • 註冊攔截器
/**
 * 註冊攔截器:創建一個config類,繼承WebMvcConfigurerAdapter,將我們上面定義的攔截器註冊到InterceptorRegistry中
 * 
 * @author HuaDong
 * @date 2020/4/11 19:32
 */
@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {
	
	@Autowired
	private TimeInterceptor timeInterceptor;
	
	@Override
	public void addInterceptors(InterceptorRegistry registry) {
		registry.addInterceptor(timeInterceptor);
	}
}

缺點

  • preHandle方法無法通過handler拿到一些封裝之後的請求參數,因爲封裝參數的方法是在preHandle之後進行的。
  • 查看源碼:org.springframework.web.servlet.DispatcherServlet#doService --> doDispatch
	// 實際 preHandler 的調用
	if (!mappedHandler.applyPreHandle(processedRequest, response)) {
	    return;
	}
	
	// 參數封裝處理邏輯
	mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
	if (asyncManager.isConcurrentHandlingStarted()) {
	    return;
	}

切片(Aspect)

簡介

  • AOP,面向切面編程,採用一種稱爲“橫切”的技術,將涉及多業務流程的通用功能抽取並單獨封裝,形成獨立的切面,在合適的時機將這些切面橫向切入到業務流程指定的位置中。

使用場景

  • 權限控制
  • 緩存控制
  • 事務控制
  • 審計日誌
  • 性能監控
  • 分佈式追蹤
  • 異常處理

簡單演示


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章