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