1. 程式人生 > 實用技巧 >【總結】攔截器

【總結】攔截器

HandlerInterceptor

1.定義攔截器

定義一個Interceptor 非常簡單方式也有幾種,我這裡簡單列舉兩種

1.1、類要實現Spring 的HandlerInterceptor 介面

1.2、類繼承實現了HandlerInterceptor 介面的類

例如 已經提供的實現了HandlerInterceptor 介面的抽象類HandlerInterceptorAdapter

2、HandlerInterceptor方法介紹

	boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception;

	void postHandle(
			HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)
			throws Exception;

	void afterCompletion(
			HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
			throws Exception;

1.preHandle:在業務處理器處理請求之前被呼叫。預處理,可以進行編碼、安全控制、許可權校驗等處理;
2.postHandle:在業務處理器處理請求執行完成後,生成檢視之前執行。後處理(呼叫了Service並返回ModelAndView,但未進行頁面渲染),有機會修改ModelAndView
3.afterCompletion:在DispatcherServlet完全處理完請求後被呼叫,可用於清理資源等。返回處理(已經渲染了頁面)

3.攔截器實現

3.1 定義攔截器


public class TestFilter extends HandlerInterceptorAdapter {
	private final Logger logger = LoggerFactory.getLogger(TestFilter.class);
	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
		logger.info("request請求地址path[{}] uri[{}]", request.getServletPath(),request.getRequestURI());
		//request.getHeader(String) 從請求頭中獲取資料
		//從請求頭中獲取使用者token(登陸憑證根據業務而定)
		Long userId= getUserId(request.getHeader("H-User-Token"));
		if (userId != null && checkAuth(userId,request.getRequestURI())){
			//新增上下文
			UserContext.setUser(userInfo);
			return true;
		}
		//這裡的異常是我自定義的異常,系統丟擲異常後框架捕獲異常然後轉為統一的格式返回給前端, 其實這裡也可以返回false
		throw new FastRuntimeException(20001,"No access");
	}



	@Override
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
						   ModelAndView modelAndView) throws Exception {}

	@Override
	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
			throws Exception {
		//刪除上下文物件
		UserContext.removeUser();
	}
}

3.2 新建WebAppConfigurer 實現WebMvcConfigurer介面

其實以前都是繼承WebMvcConfigurerAdapter類 不過springBoot2.0以上 WebMvcConfigurerAdapter 方法過時,有兩種替代方案:
(1)繼承WebMvcConfigurationSupport
(2)實現WebMvcConfigurer
但是繼承WebMvcConfigurationSupport會讓Spring-boot對mvc的自動配置失效。根據專案情況選擇。現在大多數專案是前後端分離,並沒有對靜態資源有自動配置的需求所以繼承WebMvcConfigurationSupport也未嘗不可。

@Configuration
public class WebAppConfigurer implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // 可新增多個
        registry.addInterceptor(new TestFilter()).addPathPatterns("/**");
    }

    ....
}