亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

過濾器Filter和攔截器HandlerIntercepter的區別及用法

發布時間:2021-06-23 09:30:06 來源:億速云 閱讀:608 作者:chen 欄目:大數據

本篇內容介紹了“過濾器Filter和攔截器HandlerIntercepter的區別及用法”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!

        最近在代碼中,看到有同事既在用攔截器又在用過濾器做登錄校驗,就覺得很暈,似乎二者都可以實現業務需求,但是到底采用哪種方式較好呢,二者又有什么區別?

一、原理

        1. 過濾器:

        依賴于servlet容器,在實現上基于函數回調,可以對幾乎所有請求進行過濾,一個過濾器實例只能在容器初始化時調用,它是隨你的web應用啟動而啟動的,只初始化一次,以后就可以攔截相關的請求,只有當你的web應用停止或重新部署的時候才能銷毀。

        使用過濾器的目的是用來做一些過濾操作,獲取我們想要獲取的數據,比如:在過濾器中修改字符編碼;在過濾器中修改HttpServletRequest的一些參數,包括:過濾低俗文字、危險字符等。

        2.攔截器:

        依賴于web框架,在SpringMVC中就是依賴于SpringMVC框架。在實現上基于Java的反射機制,屬于面向切面編程(AOP)的一種運用。

        由于攔截器是基于web框架的調用,因此可以使用Spring的依賴注入(DI)進行一些業務操作,而不用修改handler自身的實現。但是缺點是只能對controller請求進行攔截,對其他的一些比如直接訪問靜態資源的請求則沒辦法進行攔截處理。

        3.過濾器和攔截器的區別:

    ①攔截器是基于java的反射機制的,而過濾器是基于函數回調。

    ②攔截器不依賴與servlet容器,過濾器依賴與servlet容器。

    ③攔截器只能對action請求起作用,而過濾器則可以對幾乎所有的請求起作用。

    ④攔截器可以訪問action上下文、值棧里的對象,而過濾器不能訪問。

    ⑤在action的生命周期中,攔截器可以多次被調用(這里是指攔截器里的三個方法是可以在一次action中的不同時期調用,細粒度控制),而過濾器只能一次請求過濾一次,不能在不同的生命周期里作用。

    ⑥攔截器可以獲取IOC容器中的各個bean,而過濾器就不行,這點很重要,在攔截器里注入一個service,可以調用業務邏輯。

二、 代碼說明

        1. 過濾器:

在javax.servlet.Filter接口中定義了3個方法:

void init(FilterConfig filterConfig) 用于完成過濾器的初始化

void destroy() 用于過濾器銷毀前,完成某些資源的回收

void doFilter(ServletRequest request, ServletResponse response,FilterChain chain) 實現過濾功能,該方法對每個請求增加額外的處理
public class FilterUtil implements Filter{  
 
 @SuppressWarnings("unused")  
 private FilterConfig filterConfig;  
 @Override 
 public void init(FilterConfig filterConfig) throws ServletException {  
 this.filterConfig = filterConfig;  
        System.out.println("過濾器Filter初始化");  
    }  
 
 @Override 
 public void doFilter(ServletRequest request, ServletResponse response,  
            FilterChain chain) throws IOException, ServletException {  
 if (!(request instanceof HttpServletRequest) || !(response instanceof HttpServletResponse)) {  
        throw new ServletException("FilterUtil just supports HTTP requests");  
        }  
        HttpServletRequest httpRequest = (HttpServletRequest) request;  
        HttpServletResponse httpResponse = (HttpServletResponse) response;  
        httpRequest.setCharacterEncoding(this.filterConfig.getInitParameter("encoding"));  
        httpResponse.setCharacterEncoding(this.filterConfig.getInitParameter("encoding"));  
        chain.doFilter(httpRequest, httpResponse);  
    }  
 
 @Override 
 public void destroy() {  
        System.out.println("過濾器Filter銷毀");  
    }  
 
}

    web.xml配置: 

<filter> 
 <filter-name>encodingFilter</filter-name> 
 <!-- <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> --> 
 <filter-class>com.cn.util.FilterUtil</filter-class> 
 <async-supported>true</async-supported> 
 <init-param> 
 <param-name>encoding</param-name> 
 <param-value>UTF-8</param-value> 
 </init-param> 
</filter> 
<filter-mapping> 
 <filter-name>encodingFilter</filter-name> 
 <url-pattern>/*</url-pattern> 
</filter-mapping>

    chain.doFilter(request, response)這個方法的調用作為分水嶺。事實上調用Servlet的doService()方法是在chain.doFilter(request, response)這個方法中進行的。

        2. 攔截器:

preHandle()這個方法是在過濾器的chain.doFilter(request, response)方法的前一步執行。

  postHandle()方法之后,在return ModelAndView之前進行,可以操控Controller的ModelAndView內容。

  afterCompletion()方法是在過濾器返回給前端前一步執行,也就是在[chain.doFilter(request, response)][System.out.println("after...")]之間執行。

        注意:重定向:會在當前頁面代碼執行完畢后,跳轉到指定的頁面執行其他代碼。 轉 發:在本頁面代碼執行到轉發語句后,即跳轉到指定的頁面執行其他代碼,執行完畢后返回接著執行轉發語句后的代碼。

/**
 * 用戶身份認證的攔截器
 */
public class LoginInterceptor implements HandlerInterceptor {

	@Value("${TT_TOKEN_KEY}")
	private String TT_TOKEN_KEY;
	
	@Value("${SSO_URL}")
	private String SSO_URL;
	
	@Autowired
	private UserLoginService loginservice;
	
	//在進入目標方法之前執行
	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
		
		//用戶的身份認證在此驗證
		
		//1.取cookie中的token 
		//1.從cookie中獲取用戶的token 
		String token = CookieUtils.getCookieValue(request, TT_TOKEN_KEY);
		//2.判斷token是否存在,
		if(StringUtils.isEmpty(token)){
			//3.如果不存在,說明沒登錄   ---》重定向到登錄的頁面
			//request.getRequestURL().toString():就是訪問的URL localhost:8092/order/order-cart.html
			response.sendRedirect(SSO_URL+"/page/login?redirect="+request.getRequestURL().toString());
			return false;
		}
		//4.如果token存在,調用SSO的服務 查詢用戶的信息(看是否用戶已經過期)
		TAotaoresult result = loginservice.getUserByToken(token);
		if(result.getStatus()!=200){
			//5.用戶已經過期  --》重定向到登錄的頁面
			response.sendRedirect(SSO_URL+"/page/login?redirect="+request.getRequestURL().toString());
			return false;
		}
		//6.用戶沒過期(說明登錄了)--》放行
		//設置用戶信息到request中 ,目標方法的request就可以獲取用戶的信息
		request.setAttribute("USER_INFO", result.getData());
		return true;
	}
	
	//在進入目標方法之后,在返回modelandview之前執行
	//共用變量的一些設置。
	@Override
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
			ModelAndView modelAndView) throws Exception {
		// TODO Auto-generated method stub

	}

	//返回modelandview之后,渲染到頁面之前
	//異常處理 ,清理工作
	@Override
	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
			throws Exception {
		// TODO Auto-generated method stub

	}

}

三、執行順序

      SpringMVC的機制是由同一個Servlet來分發請求給不同的Controller,其實這一步是在Servlet的service()方法中執行的。所以過濾器、攔截器、service()方法,dispatche'r()方法的執行順序如下

過濾器Filter和攔截器HandlerIntercepter的區別及用法

四、使用建議

        攔截器更加適合做細粒度的Handler控制,尤其是一些公共處理代碼,授權校驗等,過濾器更加適合請求內容和視圖內容的相關處理,比如multipart 表單,GZIP壓縮等。 回頭在看之前的疑惑,最佳的解決方案是使用攔截器做登錄校驗。

“過濾器Filter和攔截器HandlerIntercepter的區別及用法”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

六盘水市| 双柏县| 清原| 潞西市| 邛崃市| 丽江市| 涿州市| 连云港市| 钟山县| 浦县| 喜德县| 台湾省| 绥德县| 丘北县| 威海市| 金坛市| 丰镇市| 嘉黎县| 临沂市| 张家口市| 潮安县| 曲周县| 韩城市| 凌源市| 贵德县| 迁安市| 来安县| 惠水县| 旬阳县| 嵊泗县| 通海县| 云安县| 罗源县| 嫩江县| 任丘市| 鸡西市| 甘德县| 巴中市| 阳江市| 濉溪县| 怀仁县|