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

溫馨提示×

溫馨提示×

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

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

Java攔截器Interceptor實現原理是什么

發布時間:2021-12-15 11:28:17 來源:億速云 閱讀:328 作者:iii 欄目:開發技術

這篇文章主要介紹“Java攔截器Interceptor實現原理是什么”,在日常操作中,相信很多人在Java攔截器Interceptor實現原理是什么問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”Java攔截器Interceptor實現原理是什么”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!

 Java攔截器Interceptor實現原理是什么

1,攔截器的概念

java里的攔截器是動態攔截Action調用的對象,它提供了一種機制可以使開發者在一個Action執行的前后執行一段代碼,也可以在一個Action執行前阻止其執行,同時也提供了一種可以提取Action中可重用部分代碼的方式。在AOP中,攔截器用于在某個方法或者字段被訪問之前,進行攔截然后再之前或者之后加入某些操作。目前,我們需要掌握的主要是Spring的攔截器,Struts2的攔截器不用深究,知道即可。

2,攔截器的原理

大部分時候,攔截器方法都是通過代理的方式來調用的。Struts2的攔截器實現相對簡單。當請求到達Struts2的ServletDispatcher時,Struts2會查找配置文件,并根據配置實例化相對的攔截器對象,然后串成一個列表(List),最后一個一個的調用列表中的攔截器。Struts2的攔截器是可插拔的,攔截器是AOP的一個實現。Struts2攔截器棧就是將攔截器按一定的順序連接成一條鏈。在訪問被攔截的方法或者字段時,Struts2攔截器鏈中的攔截器就會按照之前定義的順序進行調用。

3,自定義攔截器的步驟

  • 第一步:自定義一個實現了Interceptor接口的類,或者繼承抽象類AbstractInterceptor。

  • 第二步:在配置文件中注冊定義的攔截器。

  • 第三步:在需要使用Action中引用上述定義的攔截器,為了方便也可以將攔截器定義為默認的攔截器,這樣在不加特殊說明的情況下,所有的Action都被這個攔截器攔截。

4,過濾器與攔截器的區別

過濾器可以簡單的理解為“取你所想取”,過濾器關注的是web請求;攔截器可以簡單的理解為“拒你所想拒”,攔截器關注的是方法調用,比如攔截敏感詞匯。

  • 4.1,攔截器是基于java反射機制來實現的,而過濾器是基于函數回調來實現的。(有人說,攔截器是基于動態代理來實現的)

  • 4.2,攔截器不依賴servlet容器,過濾器依賴于servlet容器。

  • 4.3,攔截器只對Action起作用,過濾器可以對所有請求起作用。

  • 4.4,攔截器可以訪問Action上下文和值棧中的對象,過濾器不能。

  • 4.5,在Action的生命周期中,攔截器可以多次調用,而過濾器只能在容器初始化時調用一次。

5,Spring攔截器

抽象類HandlerInterceptorAdapter

我們如果在項目中使用了Spring框架,那么,我們可以直接繼承HandlerInterceptorAdapter.java這個抽象類,來實現我們自己的攔截器。

Spring框架,對java的攔截器概念進行了包裝,這一點和Struts2很類似。HandlerInterceptorAdapter繼承了抽象接口HandlerInterceptor。

package org.springframework.web.servlet.handler;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
public abstract class HandlerInterceptorAdapter implements HandlerInterceptor{
    // 在業務處理器處理請求之前被調用
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception{
        return true;
    }
    // 在業務處理器處理請求完成之后,生成視圖之前執行
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)
      throws Exception{
    }
    // 在DispatcherServlet完全處理完請求之后被調用,可用于清理資源
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
      throws Exception{
    }
}

接下來我們看一下Spring框架實現的一個簡單的攔截器UserRoleAuthorizationInterceptor,UserRoleAuthorizationInterceptor繼承了抽象類HandlerInterceptorAdapter,實現了用戶登錄認證的攔截功能,如果當前用戶沒有通過認證,會報403錯誤。

package org.springframework.web.servlet.handler;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class UserRoleAuthorizationInterceptor extends HandlerInterceptorAdapter{
    // 字符串數組,用來存放用戶角色信息
    private String[] authorizedRoles;
    public final void setAuthorizedRoles(String[] authorizedRoles){
        this.authorizedRoles = authorizedRoles;
    }
    public final boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
      throws ServletException, IOException{
        if (this.authorizedRoles != null) {
            for (int i = 0; i < this.authorizedRoles.length; ++i) {
                if (request.isUserInRole(this.authorizedRoles[i])) {
                    return true;
                }
            }
        }
        handleNotAuthorized(request, response, handler);
        return false;
    }
    protected void handleNotAuthorized(HttpServletRequest request, HttpServletResponse response, Object handler)
      throws ServletException, IOException{
          // 403表示資源不可用。服務器理解用戶的請求,但是拒絕處理它,通常是由于權限的問題
          response.sendError(403);
    }
}

下面,我們利用Spring框架提供的HandlerInterceptorAdapter抽過類,來實現一個自定義的攔截器。我們這個攔截器叫做UserLoginInterceptorBySpring,進行登錄攔截控制。

工作流程是這樣的:如果當前用戶沒有登錄,則跳轉到登錄頁面;登錄成功后,跳轉到之前訪問的URL頁面。

import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
/**
 * @description 利用spring框架提供的HandlerInterceptorAdapter,實現自定義攔截器
 */
public class UserLoginInterceptorBySpring extends HandlerInterceptorAdapter{
    // 在業務處理器處理請求之前被調用
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception{
        // equalsIgnoreCase 與 equals的區別?
        if("GET".equalsIgnoreCase(request.getMethod())){
            //RequestUtil.saveRequest();
        }
        System.out.println("preHandle...");
        String requestUri = request.getRequestURI();
        String contextPath = request.getContextPath();
        String url = requestUri.substring(contextPath.length());
        System.out.println("requestUri" + requestUri);
        System.out.println("contextPath" + contextPath);
        System.out.println("url" + url);
        String username = (String) request.getSession().getAttribute("username");
        if(null == username){
            // 跳轉到登錄頁面
            request.getRequestDispatcher("/WEB-INF/login.jsp").forward(request, response);
            return false;
        }
        else{
            return true;
        }
    }
    // 在業務處理器處理請求完成之后,生成視圖之前執行
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception{
        System.out.println("postHandle...");
        if(modelAndView != null){
            Map<String, String> map = new HashMap<String, String>();
            modelAndView.addAllObjects(map);
        }
    }
    // 在DispatcherServlet完全處理完請求之后被調用,可用于清理資源
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception{
        System.out.println("afterCompletion...");
    }
}

攔截器是依賴Java反射機制來實現的。攔截器的實現,用到的是JDK實現的動態代理,我們都知道,JDK實現的動態代理,需要依賴接口。

攔截器是在面向切面編程中應用的,就是在你的service或者一個方法前調用一個方法,或者在方法后調用一個方法。攔截器不是在web.xml,比如struts在struts.xml中配置。

public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {  
    Object result = null;  
    System.out.println("方法調用前,可以執行一段代碼" + method.getName());  
    result = method.invoke(this.targetObj, args);  
    System.out.println("方法調用后,可以執行一段代碼 " + method.getName());  
    return result;  
}

到此,關于“Java攔截器Interceptor實現原理是什么”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!

向AI問一下細節

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

AI

科技| 玉龙| 个旧市| 金平| 钦州市| 滦平县| 江津市| 密云县| 思南县| 桃园县| 沭阳县| 阳信县| 瑞丽市| 香河县| 颍上县| 分宜县| 河源市| 禹城市| 红安县| 长岭县| 平顶山市| 乐平市| 鞍山市| 大连市| 朝阳区| 紫阳县| 绵阳市| 闸北区| 遵化市| 洪湖市| 资讯| 青河县| 遂溪县| 乌兰察布市| 宜黄县| 普洱| 肇源县| 梁平县| 泾源县| 金坛市| 常山县|