Springboot打印接口的三种方式分享

1 aop切面的方式 

1.1 实现思路

  • 引入aop依赖
  • 自定义注解
  • 定义切面,采用环绕通知

1.2 代码实现

1)引入依赖

xml

        
            org.springframework.boot
            spring-boot-starter-aop
        

2)自定义注解LogAnnotation

java
/**
 * 日志注解
 * METHOD 方法上 type 类上
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface LogAnnotation {

    /**
     * 模块
     */
    String module() default "";

    /**
     * 简单描述接口的作用
     */
    String operation() default "";
}

3)定义切面

简单分析一下切面实现的功能:

java
/**
 * @author : look-word
 * 2022-07-27 16:03
 **/
@Slf4j
@Aspect
@Component
public class LogAspect {

    /**
     * 切入点
     */
    @Pointcut("@annotation(look.word.reggie.common.aop.LogAnnotation)")
    public void logPointCut() {
    }

    /**
     * 环绕通知
     *
     * @param point 连接点
     */
    @Around("logPointCut()")
    public Object around(ProceedingJoinPoint point) throws Throwable {
        long beginTime = System.currentTimeMillis();
        //执行方法
        Object result = point.proceed();
        //执行时长(毫秒)
        long time = System.currentTimeMillis() - beginTime;
        //保存日志
        recordLog(point, time);
        return result;
    }

    private void recordLog(ProceedingJoinPoint joinPoint, long time) {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        // 获取当前方法
        Method method = signature.getMethod();
        LogAnnotation logAnnotation = method.getAnnotation(LogAnnotation.class);
        log.info("=====================log start================================");
        log.info("module:{}", logAnnotation.module());
        log.info("operation:{}", logAnnotation.operation());

        //请求的方法名
        String className = joinPoint.getTarget().getClass().getName();
        String methodName = signature.getName();
        log.info("request method:{}", className + "." + methodName + "()");

        //请求的参数
        Object[] args = joinPoint.getArgs();
        Stream stream = ArrayUtils.isEmpty(args) ? Stream.empty() : Arrays.stream(args);
        List logArgs =
                stream.filter(arg -> (!(arg instanceof HttpServletRequest) && !(arg instanceof HttpServletResponse))).collect(Collectors.toList());
        String params = JSON.toJSONString(logArgs);
        log.info("params:{}", params);

        //获取request 设置IP地址
        HttpServletRequest request = HttpContextUtils.getHttpServletRequest();
        log.info("ip:{}", IpUtils.getIpAddr(request));
        
        log.info("execute time : {} ms", time);
        log.info("=====================log end================================");
    }
} 
  
 

1.3 功能测试

在接口上添加注解即可,还有描述信息

Springboot打印接口的三种方式分享_第1张图片

2 过滤器的方式

这种方式简单点 但是可配置性不高

注意:一定得扫描到spring容器中

创建一个类 实现 filter接口

  • init:该方法是对filter对象进行初始化的方法,仅在容器初始化filter对象结束后被调用一次,参数FilterConfig可以获得filter的初始化参数;
  • doFilter:可以对request和response进行预处理其中FilterChain可以将处理后的request和response对象传递到过滤链上的下一个资源。
  • destroy():该方法在容器销毁对象前被调用。
java
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

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

@Component
public class LogFilter implements Filter {

    private static final Logger LOG = LoggerFactory.getLogger(LogFilter.class);

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        // 打印请求信息
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        LOG.info("------------- LogFilter 开始 -------------");
        LOG.info("请求地址: {} {}", request.getRequestURL().toString(), request.getMethod());
        LOG.info("远程地址: {}", request.getRemoteAddr());

        long startTime = System.currentTimeMillis();
        filterChain.doFilter(servletRequest, servletResponse);
        LOG.info("------------- LogFilter 结束 耗时:{} ms -------------", System.currentTimeMillis() - startTime);
    }
}

结果

Springboot打印接口的三种方式分享_第2张图片

总结

1.过滤器用来实现通用的功能,减少代码冗余,提高可维护性;

2.一个过滤器可以配置给多个资源使用(编码过滤器);

3.一个资源也可以配置多个过滤器,按照配置顺序调用。

3 拦截器的方式

如果不懂 请先看了 介绍再来

拦截器的介绍

话不说多 直接上代码

创建拦截器

java
/**
 * 拦截器:Spring框架特有的,常用于登录校验,权限校验,请求日志打印 /login
 * @author : look-word
 * 2022-06-26 13:55
 **/
@Component
public class LogInterceptor implements HandlerInterceptor {
    private static final Logger LOG = LoggerFactory.getLogger(LogInterceptor.class);

        
    @Override
     public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
         // 打印请求信息
         LOG.info("------------- LogInterceptor 开始 -------------");
         LOG.info("请求地址: {} {}", request.getRequestURL().toString(), request.getMethod());
         LOG.info("远程地址: {}", request.getRemoteAddr());

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

     @Override
     public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
         long startTime = (Long) request.getAttribute("requestStartTime");
         LOG.info("------------- LogInterceptor 结束 耗时:{} ms -------------", System.currentTimeMillis() - startTime);
     }
}

注册拦截器

把我们的拦截器 注册到 拦截器链中

java
/**
 * @author : look-word
 * 2022-06-26 14:03
 **/
@Configuration
public class SpringMvcConfig implements WebMvcConfigurer {

    @Resource
    private LogInterceptor logInterceptor;
    /**
     * 注册拦截器
     * @param registry
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry
                .addInterceptor(logInterceptor)
                .addPathPatterns("/**")// 对那些接口拦截
                .excludePathPatterns("/login");// 对哪些接机口放行
        WebMvcConfigurer.super.addInterceptors(registry);
    }
}

测试结果

Springboot打印接口的三种方式分享_第3张图片

到此这篇关于Springboot打印接口的三种方式分享的文章就介绍到这了,更多相关Springboot打印接口内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

你可能感兴趣的:(Springboot打印接口的三种方式分享)