美文网首页spring boot 技术干货
web开发的三种拦截方式

web开发的三种拦截方式

作者: 一只啃楠木的鱼 | 来源:发表于2019-02-28 17:10 被阅读0次

第一种 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.*(..))
     * <p>
     * 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为接口类型,不能为该类的类型.
     * <p>
     * 带有@MyTypeAnnotation标注的所有类的任意方法.
     *
     * @within(com.elong.annotation.MyTypeAnnotation)
     * @target(com.elong.annotation.MyTypeAnnotation) 带有@MyTypeAnnotation标注的任意方法.
     * @annotation(com.elong.annotation.MyTypeAnnotation) ***> @within和@target针对类的注解,@annotation是针对方法的注解
     * <p>
     * 参数带有@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开发的三种拦截方式

    本文链接:https://www.haomeiwen.com/subject/oikkuqtx.html