springboot 启动项目打印接口列表的实现

目录
  • springboot 启动项目打印接口列表
    • 环境
    • 修改配置文件
  • Springboot项目添加接口入参统一打印
    • 新建注解,用于实现参数打印功能的增强
    • 自定义序列化规则
    • 写参数打印增强,这里选择环绕增强

springboot 启动项目打印接口列表

环境

  • springboot 2.3.2.RELEASE

修改配置文件

logging:
  level:
    org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping: trace

结果:

Springboot项目添加接口入参统一打印

需求:要求接口被调用时要打印被调用方法名,以及入参情况,参数格式化时选择fastjson

注:使用fastjson序列化时脱敏,建议入参统一使用自定义的对象类型作为入参

如果不需要参数脱敏,直接使用增强中相关代码,并去除参数脱敏相关代码即可

新建注解,用于实现参数打印功能的增强

@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ParamInfo {
    /**
     * 取消统一打印参数
     * 默认为false统一打印
     * 如需自定义参数打印 请赋值为true
     */
    boolean unPrint() default false;
    /**
     * 需要脱敏的字段,如密码等
     */
    String[] fields() default {};
}

自定义序列化规则

/**
 * 序列化过滤器:值替换
 *
 */
public class ReplaceFieldFilter implements ValueFilter {
    /**
     * 需要进行替换的属性名和替换值
     * key:属性名
     * value:替换值
     */
    private Map<String, Object> fieldMap;
    public ReplaceFieldFilter() {
    }
    public ReplaceFieldFilter(Map<String, Object> fieldMap) {
        this.fieldMap = fieldMap;
    }
    @Override
    public Object process(Object o, String name, Object value) {
        if(!CollectionUtils.isEmpty(fieldMap)){
            Iterator<Map.Entry<String, Object>> iterator = fieldMap.entrySet().iterator();
            while (iterator.hasNext()){
                Map.Entry<String, Object> next = iterator.next();
                if(next.getKey().equalsIgnoreCase(name)){
                    return next.getValue();
                }
            }
        }
        return value;
    }
    public Map<String, Object> getFieldMap() {
        return fieldMap;
    }
    public void setFieldMap(Map<String, Object> fieldMap) {
        this.fieldMap = fieldMap;
    }
    /**
     * 传入需要脱敏的字段名,序列化时格式化为 * 号
     */
    public ReplaceFieldFilter(String... fields) {
        String str = "******";
        fieldMap = new HashMap<>(4);
        for (String field : fields) {
            fieldMap.put(field, str);
        }
    }
}

写参数打印增强,这里选择环绕增强

@Component
@Aspect
//表示增强的执行顺序,如果多个增强,数值小的先被执行
@Order(0)
public class ParamInfoAspect {
    private static final Logger LOGGER = LoggerFactory.getLogger(ParamInfoAspect.class);
    @Around("execution(* com.service.impl.*.*(..))")
    public Object printParam(ProceedingJoinPoint joinPoint) throws Throwable {
        long startTime = System.currentTimeMillis();
        String requestId = RandomStringUtils.randomAlphanumeric(16);
        Object returnValue = null;
        try {
            Object[] args = joinPoint.getArgs();
            // 获取方法对象
            MethodSignature signature = (MethodSignature) joinPoint.getSignature();
            Method method = signature.getMethod();
            //通过注解获取脱敏字段,之后初始化fieldMap,完成字段脱敏
            ParamInfo annotation = method.getAnnotation(ParamInfo.class);
            Map<String, Object> fieldMap = new HashMap<>(4);
            fieldMap.put("password", "******");
            if (annotation != null) {
                //获取需要脱敏的字段名数组
                String[] fields = annotation.fields();
                for (String field : fields) {
                    fieldMap.put(field, "******");
                }
            }
            String param;
            //参数整合,多字段入参整合为对象,单个对象入参格式不变
            if (args.length > 1 || (args.length == 1 && args[0].getClass() == String.class)) {
                Map<String, Object> paramMap = new LinkedHashMap<>();
                String[] parameterNames = signature.getParameterNames();
                for (int i = 0; i < parameterNames.length; i++) {
                    paramMap.put(parameterNames[i], args[i]);
                }
                param = "[" + JSON.toJSONString(paramMap, new ReplaceFieldFilter(fieldMap)) + "]";
            } else {
                param = JSON.toJSONString(args, new ReplaceFieldFilter(fieldMap));
            }
            String methodName = method.getName();
            LOGGER.info("method:[{}], parameter:{}, requestId:[{}]", methodName, param, requestId);
            returnValue = joinPoint.proceed();
            return returnValue;
        } catch (Exception e) {
            LOGGER.error("system is error:", e);
   //可在这里定义程序异常时的错误返回值
            returnValue = ErrorCode.SYSTEM_ERROR;
            return returnValue;
        } finally {
            LOGGER.info("request cost:{}ms, requestId:[{}]", System.currentTimeMillis() - startTime, requestId);
            LOGGER.info("returnValue:[{}], requestId:[{}]", returnValue, requestId);
        }
    }
}

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • SpringBoot中使用AOP打印接口日志的方法

    前言 AOP 是 Aspect Oriented Program (面向切面)的编程的缩写.他是和面向对象编程相对的一个概念.在面向对象的编程中,我们倾向于采用封装.继承.多态等概念,将一个个的功能在对象中来实现.但是,我们在实际情况中也发现,会有另外一种需求就是一类功能在很多对象的很多方法中都有需要.例如有一些对数据库访问的方法有事务管理的需求,有很多方法中要求打印日志.按照面向对象的方式,那么这些相同的功能要在很多地方来实现或者在很多地方来调用.这就非常繁琐并且和这些和业务不相关的需求耦合太

  • SpringBoot之自定义启动异常堆栈信息打印方式

    在SpringBoot项目启动过程中,当一些配置或者其他错误信息会有一些的规范的提示信息 *************************** APPLICATION FAILED TO START *************************** Description: Web server failed to start. Port 8080 was already in use. Action: Identify and stop the process that's liste

  • SpringBoot打印详细启动异常信息

    SpringBoot在项目启动时如果遇到异常并不能友好的打印出具体的堆栈错误信息,我们只能查看到简单的错误消息,以致于并不能及时解决发生的问题,针对这个问题SpringBoot提供了故障分析仪的概念(failure-analyzer),内部根据不同类型的异常提供了一些实现,我们如果想自定义该怎么去做? FailureAnalyzer SpringBoot提供了启动异常分析接口FailureAnalyzer,该接口位于org.springframework.boot.diagnosticspack

  • SpringBoot后端接口的实现(看这一篇就够了)

    摘要:本文演示如何构建起一个优秀的后端接口体系,体系构建好了自然就有了规范,同时再构建新的后端接口也会十分轻松. 一个后端接口大致分为四个部分组成:接口地址(url).接口请求方式(get.post等).请求数据(request).响应数据(response).如何构建这几个部分每个公司要求都不同,没有什么"一定是最好的"标准,但一个优秀的后端接口和一个糟糕的后端接口对比起来差异还是蛮大的,其中最重要的关键点就是看是否规范! 本文就一步一步演示如何构建起一个优秀的后端接口体系,体系构建

  • springboot 启动项目打印接口列表的实现

    目录 springboot 启动项目打印接口列表 环境 修改配置文件 Springboot项目添加接口入参统一打印 新建注解,用于实现参数打印功能的增强 自定义序列化规则 写参数打印增强,这里选择环绕增强 springboot 启动项目打印接口列表 环境 springboot 2.3.2.RELEASE 修改配置文件 logging: level: org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandle

  • springBoot启动输出三行日志控制台自动停止操作

    springBoot启动输出三行日志控制台自动停止 在https://start.spring.io/(官网)快速创建的springBoot工程,导入到myeclipse中后,启动后自动结束了. pom.xml: <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="htt

  • SpringBoot 如何自定义项目启动信息打印

    目录 1. 修改 Banner 1.1. 字符 Banner 1.2. 图片 Banner 1.3. Banner 配置 2. 添加访问地址 自定义springboot启动图案输出 直接上内容 1. 修改 Banner 默认情况下,在启动SpringBoot项目的时候能在日志中看到如下所示的Banner,这个Banner是支持自定义的. . ____ _ __ _ _ /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \ ( ( )\___ | '_ | '_| | '_

  • springboot vue项目后端列表接口分页模糊查询

    目录 基于 springboot+vue 的测试平台开发 一.分页插件 二.实现接口 1. 编写 Service 层 2. 编写 Controller 层 三.测试接口 1. 测试分页 2. 测试条件查询 基于 springboot+vue 的测试平台开发 继续更新 打开项目管理,就需要看到列表里展示项目数据,比如这样(截图是这个前端框架的demo,仅作示意): 那么对应到我们平台的项目管理功能,就需要有: 列表展示添加的项目数据 可以通过项目名称查询指定的项目 新增项目 编辑项目 其他功能..

  • springboot启动feign项目报错:Service id not legal hostnam的解决

    目录 springboot启动feign项目报错:Service id not legal hostnam 在feign项目中,定义接口调用服务 启动时报出异常信息 度娘后发现问题所在 配置文件服务名做同样修改 Service id not legal hostname (pin_user) 错误信息 出现原因 解决方案 springboot启动feign项目报错:Service id not legal hostnam 在feign项目中,定义接口调用服务 @FeignClient(name=

  • SpringBoot+jsp项目启动出现404的解决方法

    通过maven创建springboot项目启动出现404 application.properties配置 spring.mvc.view.prefix=/WEB-INF/jsp/ spring.mvc.view.suffix=.jsp 项目结构 控制器方法 package com.example.demo.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bi

  • SpringBoot项目中接口防刷的完整代码

    一.自定义注解 import java.lang.annotation.Retention; import java.lang.annotation.Target; import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.RetentionPolicy.RUNTIME; /** * @author Yang * @version 1.0 * @date 2021/2/22

  • 解决SpringBoot web项目启动后立即关闭的问题

    SpringBoot web项目启动后立即关闭 我们在写spring boot web项目时,有时会遇到启动后立即关闭的情况,或者是无法加载某些类,这是什么呢原因呢? 仔细排查pom文件,发现已经添加了web的依赖,而且对照过网上的springBoot web项目,并没有什么出入,此时就可以怀疑是不是项目中所依赖的jar包发生了冲突呢? 于是可以尝试下面的方法来解决: 使用Maven的命令依赖性:清除本地存储库    清理本地仓库,注意该命令仅仅是清理该项目所依赖的本地仓库中的JAR包 具体用法

  • springboot启动时如何获取端口和项目名

    目录 springboot启动获取端口和项目名 背景 踩坑 使用 效果 springboot配置项目运行端口号 这个方法极其简洁 springboot启动获取端口和项目名 背景 项目启动每次都要手动输url在浏览器中访问,就想能和vue项目一样启动能直接在控制台打印出url 踩坑 在项目中获取配置文件的方法为@Value,但是在启动类中无法使用,获取到的全都为null 使用 Environment public static void main(String[] args) { Configur

  • webservice实现springboot项目间接口调用与对象传递示例

    目录 一.百度百科 二.webservice的技术支持 1.XML和XSD 2.SOAP 3.WSDL 4.UDDI 5.调用RPC与消息传递 三.webservice的应用场景和弊端 1.webservice的应用场景 2.webservice的弊端 四.webservice代码实例 服务端项目代码 客户端项目代码: 一.百度百科 Web Service是一个平台独立的,低耦合的,自包含的.基于可编程的web的应用程序,可使用开放的XML(标准通用标记语言下的一个子集)标准来描述.发布.发现.

随机推荐