RESTFul api攔截順序

RESTFul api攔截順序

Filter ->Interceptor->ControllerAdvice->Aspect->controller

Filter過濾器

(通過註解)開發一個過濾器(此過濾器會對所有url進行攔截)

創建一個類,並添加component註解,使spring自動注入


import org.springframework.stereotype.Component;

import javax.servlet.*;
import java.io.IOException;

/**
* @author mjp
* @ClassName : TimeFilter
* @Date: 2019/5/30 15:41
* @Description:
* @Copyright 2019 www.videasoft.com Inc. All rights reserved.
* 注意:本內容僅限於蘇州微締軟件股份有限公司內部傳閱,禁止外泄以及用於其他的商業目的
* @Version 1.0
*/

@Component
public class TimeFilter implements Filter {
   @Override
   public void init(FilterConfig filterConfig) throws ServletException {
       System.out.println("TimeFilter init");
   }

   @Override
   public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
       System.out.println("TimeFilter start");
       long start = System.currentTimeMillis();
       chain.doFilter(request,response);
       System.out.println("TimeFilter 耗時:  "+(System.currentTimeMillis()- start));
       System.out.println("TimeFilter finish");
   }

   @Override
   public void destroy() {
       System.out.println("TimeFilter destroy");
   }
}

通過配置的方式啓動過濾器(推薦使用,可以選擇性的加載第三方過濾器)

創建攔截器類(實現Filter接口)


import javax.servlet.*;
import java.io.IOException;

/**
* @author mjp
* @ClassName : TimeFilter
* @Date: 2019/5/30 15:41
* @Description:
* @Copyright 2019 www.videasoft.com Inc. All rights reserved.
* 注意:本內容僅限於蘇州微締軟件股份有限公司內部傳閱,禁止外泄以及用於其他的商業目的
* @Version 1.0
*/

public class TimeFilter implements Filter {
   @Override
   public void init(FilterConfig filterConfig) throws ServletException {
       System.out.println("TimeFilter init");
   }

   @Override
   public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
       System.out.println("TimeFilter start");
       long start = System.currentTimeMillis();
       chain.doFilter(request,response);
       System.out.println("TimeFilter 耗時:  "+(System.currentTimeMillis()- start));
       System.out.println("TimeFilter finish");
   }

   @Override
   public void destroy() {
       System.out.println("TimeFilter destroy");
   }
}

創建配置類 (繼承WebMvcConfigurerAdapter )


import com.imooc.web.filter.TimeFilter;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

import java.util.ArrayList;
import java.util.List;

/**
 * 手動配置過濾器,加載第三方過濾器
 */
@Configuration
public class WebConfig{

    @Bean
    public FilterRegistrationBean timeFilter(){
        FilterRegistrationBean registrationBean = new FilterRegistrationBean();
        TimeFilter timeFilter = new TimeFilter();
        registrationBean.setFilter(timeFilter);
        // 設置攔截路徑
        List<String> urls = new ArrayList<>();
        urls.add("/*");
        registrationBean.setUrlPatterns(urls);


        return registrationBean;

    }
}


攔截器 Interceptor

創建攔截器類,繼承HandlerInterceptor,並添加spring註解


import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 攔截器,
 * 與過濾器不一樣的是一個component註解並不能夠是攔截器起作用還需要些配置
 */
@Component
public class TimeInterceptor implements HandlerInterceptor {
    /**
     * 方法調用前調用
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object o) throws Exception {
        System.out.println("preHandle");
        System.out.println(((HandlerMethod)o).getBean().getClass().getName());
        System.out.println(((HandlerMethod)o).getMethod().getName());
        request.setAttribute("startTime",System.currentTimeMillis());
        return true;
    }
    /**
     * 如果方法出現異常,此處可能就不會調用
     */
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("postHandle");
        Long startTime = (Long) request.getAttribute("startTime");
        System.out.println("time interceptor 耗時:" +(System.currentTimeMillis() - startTime));

    }
    /**
     * 方法調用後調用.
     * 當成功調用沒有異常的時候 e是空de
     * 當拋出的異常的時候  e是有值得
     */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object o, Exception e) throws Exception {
        System.out.println("afterCompletion");

        Long startTime = (Long) request.getAttribute("startTime");
        System.out.println("time interceptor 耗時:" +(System.currentTimeMillis() - startTime));
        /**
         * 控制器的異常處理器,會在此攔截器之前處理,所有如果異常被控制器的異常處理器處理le,
         * 此處的 異常就是空的
         *
         */
        System.out.println("ex is "+ e);


    }
}

配置攔截器,需要繼承WebMvcConfigurerAdapter 並重寫addInterceptors方法


import com.imooc.web.interceptor.TimeInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

/**
 * 手動配置過濾器,加載第三方過濾器
 */
@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {


    @Autowired
    private TimeInterceptor timeInterceptor;
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(timeInterceptor);
    }
    
}

Aspect AOP 切面



import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;

/**
 * 切片
 */
@Aspect
@Component
public class TimeAspect {
//    @Before()  在方法前
//    @After()   在方法後
//    @AfterThrowing()   在拋出異常
//    @Around()   環繞

    // 切入點
    @Around("execution(* com.imooc.web.controller.UserController.*(..))")
    // 增強
    public Object handleControllerMethod(ProceedingJoinPoint pjp) throws Throwable {
        System.out.println(" time aspect start ");
        // 獲取請求參數
        Object[] args = pjp.getArgs();
        for (Object arg : args) {
            System.out.println("arg is "+ arg);
        }
        long l = System.currentTimeMillis();
        Object proceed = pjp.proceed();
        System.out.println(" time aspect 耗時:  "+ (System.currentTimeMillis() - l));

        System.out.println(" time aspect end ");

        return proceed;

    }
}

總結

  1. Fiter 過濾器可以獲取請求的request和response,但是不能獲取該請求所對應的類和方法
  2. Inteceptor 攔截器,可以獲取請求的request和response,也能獲取到請求所對應的類和方法,但是不能獲取方法被調用的時候參數對應的值(攔截器過後,spring纔開始封裝參數)
  3. 可以獲取到請求參數的值,但是不能獲取請求的request和response
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章