Springboot打印接口
look-word 人气:01 aop切面的方式
1.1 实现思路
- 引入aop依赖
- 自定义注解
- 定义切面,采用环绕通知
1.2 代码实现
1)引入依赖
xml
<!--aop--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency>
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<Object> 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 功能测试
在接口上添加注解即可,还有描述信息
2 过滤器的方式
这种方式简单点 但是可配置性不高
注意:一定得扫描到spring容器中
创建一个类 实现 filter接口
- init:该方法是对filter对象进行初始化的方法,仅在容器初始化filter对象结束后被调用一次,参数FilterConfig可以获得filter的初始化参数;
- doFilter:可以对request和response进行
<u>预处理</u>
。其中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); } }
结果
总结
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); } }
测试结果
加载全部内容