web开发的三种拦截方式

第一种 filter 此方法不会拿到类名和方法名

@Component
public class TimeFilter implements Filter {



        public void init(FilterConfig filterConfig) throws ServletException {
                System.out.println("time filter init");

        }

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

        public void destroy() {
                System.out.println("time filter destroy");

        }
}

第二种 基于spring的拦截器 此方法不会拿到请求的参数的值

@Component
public class TimeInterceptor implements HandlerInterceptor {

        /**
         * 执行前触发
         * @param request
         * @param response
         * @param handler
         * @return
         * @throws Exception
         */
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
                        throws Exception {
                System.out.println("preHandle");

                System.out.println(((HandlerMethod)handler).getBean().getClass().getName());
                System.out.println(((HandlerMethod)handler).getMethod().getName());

                request.setAttribute("startTime", System.currentTimeMillis());
                return true;
        }


        /**
         * 执行后触发 但如果报异常则不会进入此方法
         * @param request
         * @param response
         * @param handler
         * @param modelAndView
         * @throws Exception
         */
        public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
                               ModelAndView modelAndView) throws Exception {
                System.out.println("postHandle");
                Long start = (Long) request.getAttribute("startTime");
                System.out.println("time interceptor 耗时:"+ (System.currentTimeMillis() - start));

        }

        /**
         * 执行后触发 无论是否发生异常都会进入此方法
         * @param request
         * @param response
         * @param handler
         * @param ex
         * @throws Exception
         */
        public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
                        throws Exception {
                System.out.println("afterCompletion");
                Long start = (Long) request.getAttribute("startTime");
                System.out.println("time interceptor 耗时:"+ (System.currentTimeMillis() - start));
                System.out.println("ex is "+ex);

        }

}

另外还需要在配置类中注册此组件

@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {
    
    @Autowired
    private TimeInterceptor timeInterceptor;
    
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(timeInterceptor);
    }

}

第三种 切面

/**
 *  nice
 *
 * @author gaogao
 * @date 2018/12/12 18:30.
 */
@Aspect
@Component
public class WebLog implements BaseLogger {

    /**
     * 任意公共方法的执行:
     * execution(public * *(..))
     * 任何一个以“set”开始的方法的执行:
     * execution(* set*(..))
     * AccountService 接口的任意方法的执行:
     * execution(* com.xyz.service.AccountService.*(..))
     * 定义在service包里的任意方法的执行:
     * execution(* com.xyz.service.*.*(..))
     * 定义在service包和所有子包里的任意类的任意方法的执行:
     * execution(* com.xyz.service..*.*(..))
     * 定义在pointcutexp包和所有子包里的JoinPointObjP2类的任意方法的执行:
     * execution(* com.test.spring.aop.pointcutexp..JoinPointObjP2.*(..))")
     * ***> 最靠近(..)的为方法名,靠近.*(..))的为类名或者接口名,如上例的JoinPointObjP2.*(..))
     * 

* pointcutexp包里的任意类. * within(com.test.spring.aop.pointcutexp.*) * pointcutexp包和所有子包里的任意类. * within(com.test.spring.aop.pointcutexp..*) * 实现了MyInterface接口的所有类,如果MyInterface不是接口,限定MyInterface单个类. * this(com.test.spring.aop.pointcutexp.MyInterface) * ***> 当一个实现了接口的类被AOP的时候,用getBean方法必须cast为接口类型,不能为该类的类型. *

* 带有@MyTypeAnnotation标注的所有类的任意方法. * * @within(com.elong.annotation.MyTypeAnnotation) * @target(com.elong.annotation.MyTypeAnnotation) 带有@MyTypeAnnotation标注的任意方法. * @annotation(com.elong.annotation.MyTypeAnnotation) ***> @within和@target针对类的注解,@annotation是针对方法的注解 *

* 参数带有@MyMethodAnnotation标注的方法. * @args(com.elong.annotation.MyMethodAnnotation) 参数为String类型(运行是决定)的方法. * args(String) */ //@Pointcut("execution(public * com.e9cloud.aivoice.rest.controller..*.*(..)) && @annotation(com.e9cloud.aivoice.common.log.Loggable)") @Pointcut("execution(public * com.e9cloud.checkphone.modules.*.controller..*.*(..))") public void log() { } @AfterReturning(value = "log()", returning = "returnVal") public void log(JoinPoint point, Object returnVal) { // 获取参数 Object[] params = point.getArgs(); List paramList = Arrays.asList(params); Object collect = paramList.stream().map(x -> { if (x != null) { return x.toString(); } else { return "null"; } }).collect(Collectors.toList()); logger.info(StringUtils.join("前端请求参数-----------> ", collect.toString())); // 获取方法名 String name = point.getSignature().getDeclaringTypeName(); String methodName = point.getSignature().getName(); logger.info(StringUtils.join("调用的控制器-----------> ", name)); logger.info(StringUtils.join("调用的方法名-----------> ", methodName)); // Class targetClass = point.getTarget().getClass();// 获取目标对象的类名 // Method method = null; // for (Method mt : targetClass.getMethods()) { // if (methodName.equals(mt.getName())) { // method = mt; // break; // } // } Rsp rsp = (Rsp) returnVal; if(rsp!=null){ if (rsp.getCode() == 0) { logger.info(StringUtils.join("后端返回数据-----------> ", rsp.toString())); } else { logger.error(StringUtils.join("后端返回数据-----------> ", rsp.toString())); } } } }

你可能感兴趣的:(web开发的三种拦截方式)