SpringBoot+AOP实现系统日志模块

发布于 2023-02-13 | 作者: 玩屎的猪 | 来源: CSDN博客 | 转载于: CSDN博客

一、引入AOP依赖


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

二、生成必要枚举类和接口

(1)OpType.java (操作类型)

package com.plat.sysLog.logEnum;
 
/**
 * @author xxs
 * @date 2022年08月10日 16:44
 */
public interface OpType {
 
    /**
     * 新增
     */
    public static final int ADD = 1;
 
    /**
     * 修改
     */
    public static final int UPDATE = 2;
    /**
     * 删除
     */
    public static final int DELETE = 3;
    /**
     * 查询-分页
     */
    public static final int QUERY_PAGE = 4;
    /**
     * 其他
     */
    public static final int OTHER = 5;
    /**
     * 登录
     */
    public static final int LOGIN = 6;
    /**
     * 登出
     */
    public static final int LOGOUT = 7;
    /**
     * 导出
     */
    public static final int EXPORT = 8;
    /**
     * 导入
     */
    public static final int IMPORT = 9;
    /**
     * 保存
     */
    public static final int SAVE = 10;
    /**
     * 发送邮件
     */
    public static final int SEND_EMAIL = 11;
    /**
     * 发送短信
     */
    public static final int SMS = 12;
    /**
     * 查询-不分页
     */
    public static final int QUERY_NO_PAGE = 13;
    /**
     * 查询明细
     */
    public static final int QUERY_DETAIL = 14;
    /**
     * 审核
     */
    public static final int AUDIT = 15;
    /**
     * 反审核
     */
    public static final int UN_AUDIT = 16;
    /**
     * 下载
     */
    public static final int DOWNLOAD = 17;
    /**
     * 上传
     */
    public static final int UPLOAD = 18;
    /**
     * 校验
     */
    public static final int CHECK = 19;
    /**
     * 安装
     */
    public static final int INSTALL = 20;
    /**
     * 卸载
     */
    public static final int UN_INSTALL = 21;
    /**
     * 启动
     */
    public static final int START = 22;
    /**
     * 停止
     */
    public static final int STOP = 23;
    /**
     * 重启
     */
    public static final int RESTART = 24;
    /**
     * 暂停
     */
    public static final int PAUSE = 25;
    /**
     * 恢复
     */
    public static final int RESUME = 26;
    /**
     * 刷新
     */
    public static final int REFRESH = 27;
    /**
     * 生成
     */
    public static final int GENERATE = 28;
    /**
     * 统计
     */
    public static final int STATISTICS = 29;
 
    /**
     * 同步
     */
    public static final int SYNC = 30;
    /**
     * 定时调度
     */
    public static final int SCHEDULE = 31;
} 

(2)OpTypeEnum.java (操作类型枚举)

package com.plat.sysLog.logEnum;
 
import java.util.ArrayList;
import java.util.List;
 
/**
 * @author hz
 */
public enum OpTypeEnum {
    /*
        1. 增加
        2. 删除
        3. 修改
        4. 查询
        5. 其他
     */
    ADD(OpType.ADD, "新增"),
 
    UPDATE(OpType.UPDATE, "修改"),
 
    DELETE(OpType.DELETE, "删除"),
 
    QUERY_PAGE(OpType.QUERY_PAGE, "查询-分页", true),
 
    OTHER(OpType.OTHER, "其他"),
 
    LOGIN(OpType.LOGIN, "登录"),
 
    LOGOUT(OpType.LOGOUT, "登出"),
 
    EXPORT(OpType.EXPORT, "导出"),
 
    IMPORT(OpType.IMPORT, "导入"),
 
    SAVE(OpType.SAVE, "保存"),
 
    SEND_EMAIL(OpType.SEND_EMAIL, "发送邮件"),
 
    SMS(OpType.SMS, "发送短信"),
 
    QUERY_NO_PAGE(OpType.QUERY_NO_PAGE, "查询-不分页", true),
 
    QUERY_DETAIL(OpType.QUERY_DETAIL, "查询明细", true),
 
    AUDIT(OpType.AUDIT, "审核"),
 
    UN_AUDIT(OpType.UN_AUDIT, "反审核"),
 
    DOWNLOAD(OpType.DOWNLOAD, "下载"),
 
    UPLOAD(OpType.UPLOAD, "上传"),
 
    CHECK(OpType.CHECK, "校验"),
 
    INSTALL(OpType.INSTALL, "安装"),
 
    UN_INSTALL(OpType.UN_INSTALL, "卸载"),
 
    START(OpType.START, "启动"),
 
    STOP(OpType.STOP, "停止"),
 
    RESTART(OpType.RESTART, "重启"),
 
    PAUSE(OpType.PAUSE, "暂停"),
 
    RESUME(OpType.RESUME, "恢复"),
 
    REFRESH(OpType.REFRESH, "刷新"),
 
    GENERATE(OpType.GENERATE, "生成"),
 
    STATISTICS(OpType.STATISTICS, "统计"),
 
    SYNC(OpType.SYNC, "同步"),
 
    SCHEDULE(OpType.SCHEDULE, "定时调度"),
 
    last(0, "最后一个");
    final int key;
    final String desc;
    //是否忽略返回结果
    final boolean ignoreResult;
 
    OpTypeEnum(int key, String desc) {
        this.key = key;
        this.desc = desc;
        this.ignoreResult = false;
    }
 
    OpTypeEnum(int key, String desc, boolean ignoreResult) {
        this.key = key;
        this.desc = desc;
        this.ignoreResult = ignoreResult;
    }
 
    /**
     * 根据key获取desc
     */
    public static String getDesc(Integer key) {
        for (OpTypeEnum opTypeEnum : OpTypeEnum.values()) {
            if (opTypeEnum.getKey() == key) {
                return opTypeEnum.getDesc();
            }
        }
        return "";
    }
 
    /**
     * 获取所有忽略返回结果的Key集合
     */
    public static List getIgnoreResultKeys() {
        List keys = new ArrayList<>();
        for (OpTypeEnum opTypeEnum : OpTypeEnum.values()) {
            if (opTypeEnum.isIgnoreResult()) {
                keys.add(opTypeEnum.getKey());
            }
        }
        return keys;
    }
 
    public int getKey() {
        return key;
    }
 
    public String getDesc() {
        return desc;
    }
 
    public boolean isIgnoreResult() {
        return ignoreResult;
    } 
} 

(3)SysType.java (面向调用服务类型)

package com.plat.sysLog.logEnum;
 
/**
 * @author xxs
 * @date 2022年08月10日 16:50
 */
public interface SysType {
    /**
     * WEB服务
     */
    public static final int WEB = 1;
} 

(4)SysLog.java(系统日志实体类)

package com.plat.sysLog.model;
 
import lombok.Data;
import lombok.experimental.Accessors;
 
@Data
@Accessors(chain = true)
public class SysLog {
 
    private static final long serialVersionUID = 1L;
    /**
     *
     */
    private Long id;
 
    /**
     * 操作人
     */
    private String operationUser;
 
    /**
     * 请求路径
     */
    private String path;
 
    /**
     * 开始时间
     */
    private String startTime;
    /**
     * 结束时间
     */
    private String endTime;
 
 
    /**
     * 方法入参
     */
    private String parameter;
 
    /**
     * 返回参数
     */
    private String result;
 
    /**
     * 操作方法
     */
    private String title;
 
    /**
     * 方法描述
     */
    private String action;
 
    /**
     * 系统类型
     */
    private Integer sysType;
 
    /**
     * 操作类型
     */
    private Integer opType;
 
    /**
     * 请求ip
     */
    private String sourceIp;
 
    /**
     * 方法名称
     */
    private String method;
 
    /**
     * 请求方式
     */
    private String requestMethod;
 
    /**
     * 操作状态(0正常 1异常)
     */
    private Integer status;
 
    /**
     * 错误信息
     */
    private String errorMsg;
 
 
    public SysLog() {
 
    }
} 

三、创建注解类 OperationLog.java

package com.plat.sysLog.config;
 
import com.plat.sysLog.logEnum.OpType;
import com.plat.sysLog.logEnum.SysType;
 
import java.lang.annotation.*;
 
/**
 * @author xxs
 * @date 2022年08月10日 16:01
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Documented
public @interface OperationLog {
    //功能模块
    String title() default "";
    //详情
    String desc() default "";
    //操作类型
    int opType() default OpType.OTHER;
    //接口调用方系统类型
    int sysType() default SysType.WEB;
    //是否忽略返回结果,0跟随默认,1忽略,2不忽略
    int ignoreResult() default 0;
    //是否忽略请求参数
    boolean ignoreParam() default false;
    //是否来源于定时任务
    boolean fromTask() default false;
} 

四、创建切面处理类(重要!) SystemLogAspect.java

package com.hz.plat.sysLog.logAspect;
 
import com.alibaba.fastjson.JSONObject;
import com.plat.common.util.DateUtil;
import com.plat.common.util.IpAddressUtil;
import com.plat.shiro.TokenManager;
import com.plat.sysLog.config.OperationLog;
import com.plat.sysLog.dao.SysLogMapper;
import com.plat.sysLog.logEnum.OpTypeEnum;
import com.plat.sysLog.model.SysLog;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.CodeSignature;
import org.springframework.core.annotation.Order;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.multipart.MultipartFile;
 
import javax.annotation.Resource;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
 
/**
 * @author xxs
 * @date 2022年08月10日 16:01
 * @description 操作日志切面
 */
@Aspect
@Component
@EnableAsync
@Order(-1)
@Slf4j
public class SystemLogAspect {
    SysLog sysLog = null;
    //日志 mapper
    @Resource
    private SysLogMapper logMapper;
    //请求
    private HttpServletRequest request = null;
    //是否忽略返回结果
    private int ignoreResult = 0;
    //是否来源定时任务
    private boolean isScheduledTask = false;
 
    /**
     * 注解的位置
     */
    @Pointcut("@annotation(com.plat.sysLog.config.OperationLog)")
    public void logPointCut() {
    }
 
 
    @Around(value = "logPointCut()")
    public Object around(ProceedingJoinPoint pjp) throws Throwable {
        try {
            sysLog = new SysLog();
            sysLog.setStartTime(DateUtil.getCurrentDateString("yyyy-MM-dd HH:mm:ss.SSS"));
            //通过uuid关联请求参数和返回参数
//            String uuid = UUID.randomUUID().toString().replaceAll("-", "");
            String user = null;
            try {
                user = TokenManager.getNickname();
            } catch (Exception e) {
                user = "未登录用户";
            }
//            sysLog.setId(uuid);
            sysLog.setOperationUser(user);
            methodBefore(pjp);
 
            Object proceed = pjp.proceed();
            methodAfter(proceed);
            sysLog.setStatus(0);
            return proceed;
        } catch (Exception e) {
            sysLog.setStatus(1);
            sysLog.setErrorMsg(sysLog.getErrorMsg() + "errMsg:" + e.getMessage() + "\n" + "errStackTrace:" + e.getStackTrace()[0].toString() + "\n");
            log.error("【AOP日志管理】=========》", e);
            throw e;
        } finally {
            sysLog.setEndTime(DateUtil.getCurrentDateString("yyyy-MM-dd HH:mm:ss.SSS"));
            if (isScheduledTask) {
                sysLog.setRequestMethod("定时任务");
                sysLog.setSourceIp("定时任务");
                sysLog.setPath("定时任务");
            } else {
                String requestMethod = null;
                String requestPath = null;
                String ipAddress = null;
                try {
                    request = getHttpServletRequest();
                    requestMethod = request.getMethod();
                    requestPath = request.getServletPath();
                    ipAddress = IpAddressUtil.getIpAddress(request);
                } catch (Exception e) {
                    sysLog.setErrorMsg(sysLog.getErrorMsg() + "errMsg:" + e.getMessage() + "\n" + "errStackTrace:" + e.getStackTrace()[0].toString() + "\n");
                    log.error("【AOP日志管理】=========》", e);
                }
                sysLog.setSourceIp(ipAddress);
                sysLog.setRequestMethod(requestMethod);
                sysLog.setPath(requestPath);
            }
            logMapper.insert(sysLog);
        }
    }
 
    /**
     * 处理返回结果
     * @param proceed
     */
    private void methodAfter(Object proceed) {
        if (ObjectUtils.nullSafeEquals(ignoreResult, 0)) {
            if (proceed != null) {
                String resultParamJsonStr = JSONObject.toJSONString(proceed);
                if (OpTypeEnum.getIgnoreResultKeys().contains(sysLog.getOpType())) {
                    sysLog.setResult("忽略返回结果");
                } else {
                    sysLog.setResult(resultParamJsonStr);
                }
            }
        } else if (ObjectUtils.nullSafeEquals(ignoreResult, 1)) {
            sysLog.setResult("忽略返回结果");
        }else if (ObjectUtils.nullSafeEquals(ignoreResult, 2)) {
            if (proceed != null) {
                String resultParamJsonStr = JSONObject.toJSONString(proceed);
                sysLog.setResult(resultParamJsonStr);
            }
        }
    }
 
    public void methodBefore(JoinPoint joinPoint) {
        // 打印请求内容
        try {
            String targetName = joinPoint.getTarget().getClass().getName();
            String methodName = joinPoint.getSignature().getName();
            Object[] arguments = joinPoint.getArgs();
            Class targetClass = null;
            try {
                targetClass = Class.forName(targetName);
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
            Method[] methods = new Method[0];
            if (targetClass != null) {
                methods = targetClass.getMethods();
            }
            Class[] clazzs;
            for (Method method : methods) {
                if (method.getName().equals(methodName)) {
                    clazzs = method.getParameterTypes();
                    if (clazzs.length == arguments.length && method.getAnnotation(OperationLog.class) != null) {
                        String title = method.getAnnotation(OperationLog.class).title();
                        int sysType = method.getAnnotation(OperationLog.class).sysType();
                        int opType = method.getAnnotation(OperationLog.class).opType();
                        String action = method.getAnnotation(OperationLog.class).desc();
                        ignoreResult = method.getAnnotation(OperationLog.class).ignoreResult();
                        isScheduledTask = method.getAnnotation(OperationLog.class).fromTask();
                        boolean ignoreParam = method.getAnnotation(OperationLog.class).ignoreParam();
                        if (!ignoreParam) {
                            Map nameAndValue = getNameAndValue(joinPoint);
                            String paramJsonStr = JSONObject.toJSONString(nameAndValue);
                            sysLog.setParameter(paramJsonStr);
                        } else {
                            sysLog.setParameter("忽略请求参数");
                        }
                        String thisMethodName = targetName + "." + methodName;
                        sysLog.setTitle(title);
                        sysLog.setSysType(sysType);
                        sysLog.setOpType(opType);
                        sysLog.setAction(action);
                        sysLog.setMethod(thisMethodName);
                    }
                }
            }
        } catch (Exception e) {
            sysLog.setErrorMsg(sysLog.getErrorMsg() + "errMsg:" + e.getMessage() + "\n" + "errStackTrace:" + e.getStackTrace()[0].toString() + "\n");
        }
    }
 
    /**
     * @param joinPoint
     * @return
     * @Description 获取入参方法参数
     */
    public Map getNameAndValue(JoinPoint joinPoint) {
        Map param = new HashMap<>();
        Object[] paramValues = joinPoint.getArgs();
        String[] paramNames = ((CodeSignature) joinPoint.getSignature()).getParameterNames();
        for (int i = 0; i < paramNames.length; i++) {
            if (paramValues[i] instanceof MultipartFile || paramValues[i] instanceof HttpSession || paramValues[i] instanceof ServletRequest || paramValues[i] instanceof ServletResponse) {
                param.put(paramNames[i], "忽略请求参数:" + paramValues[i].getClass().getTypeName());
            } else {
                param.put(paramNames[i], paramValues[i]);
            }
        }
        return param;
    }
 
 
    /**
     * @Description: 获取request
     */
    public HttpServletRequest getHttpServletRequest() {
        RequestAttributes ra = RequestContextHolder.getRequestAttributes();
        ServletRequestAttributes sra = (ServletRequestAttributes) ra;
        HttpServletRequest request = null;
        if (sra != null) {
            request = sra.getRequest();
        }
        return request;
    }
} 

五、数据库SQL

CREATE TABLE `plat_sys_log` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `title` varchar(50) DEFAULT NULL COMMENT '操作方法',
  `action` varchar(50) DEFAULT NULL COMMENT '方法描述',
  `opType` int(2) DEFAULT NULL COMMENT '操作类型',
  `operationUser` varchar(50) DEFAULT NULL COMMENT '操作人',
  `path` varchar(255) DEFAULT NULL COMMENT '请求路径',
  `startTime` varchar(50) DEFAULT NULL COMMENT '方法执行耗时',
  `endTime` varchar(50) DEFAULT NULL COMMENT '操作时间',
  `parameter` varchar(2000) DEFAULT NULL COMMENT '方法入参',
  `result` text COMMENT '返回参数',
  `status` int(1) DEFAULT NULL COMMENT '操作状态(0正常 1异常)',
  `sourceIp` varchar(128) DEFAULT NULL COMMENT '请求ip',
  `errorMsg` varchar(2000) DEFAULT NULL COMMENT '错误信息',
  `requestMethod` varchar(10) DEFAULT '' COMMENT '请求方式',
  `method` varchar(100) DEFAULT NULL COMMENT '方法名称',
  `sysType` int(2) DEFAULT NULL COMMENT '系统类型',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=170 DEFAULT CHARSET=utf8; 

六、其他 

至于mapper和dao层代码我就不赘述了。给大家看一下效果图

调用方式:

@OperationLog(title = "看板统计", opType = OpType.STATISTICS,desc = "获取看板统计信息") 

效果展示

七、生成apiPost.json接口文档

      1、因为项目接口基本使用的Map进行前后端传参,所以无法适用Swagger等主流API文档生成插件。所以另辟蹊径...

import com.alibaba.fastjson.JSONObject;
import com.hz.MubanApplication;
import com.hz.plat.common.util.DateUtil;
import com.hz.plat.sysLog.dao.SysLogMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.stereotype.Component;
import org.springframework.test.context.junit4.SpringRunner;
 
import javax.annotation.Resource;
import java.io.File;
import java.io.IOException;
import java.util.*;
 
/**
 * @author xxs
 * @date 2022年11月04日 09:27
 */
@Component
@RunWith(SpringRunner.class)
@SpringBootTest(classes = MubanApplication.class)
@Slf4j
public class PostApiTest {
 
    @Resource
    SysLogMapper sysLogMapper;
 
    @Test
    public void getJsonFile() {
        String path = "C:\\Users\\xxs\\Desktop\\test.json";
        try {
            creteJsonFile(path);
            // File file = new File(path);
            // creteJsonFile(file);
        } catch (IOException e) {
            log.error("生成文件失败", e);
        }
    }
 
    /**
     * 直接生成json文件
     *
     * @throws IOException
     */
    public void creteJsonFile(String filePath) throws IOException {
        List mapList = sysLogMapper.listForJson(new HashMap());
        List allFolderList = extractApiJson(mapList, true);
        // 补全json
        Map jsonMap = new HashMap();
        jsonMap.put("project", new HashMap() {{
            put("name", "Api-" + DateUtil.getCurrentDateString("yyyyMMddHHmmss"));
            put("description", "");
            put("details", new HashMap() {{
                put("variable", new ArrayList() {
                    {
                        add(new HashMap() {{
                            put("key", "userName");
                            put("description", "用户名");
                        }});
                        add(new HashMap() {{
                            put("key", "password");
                            put("description", "密码");
                        }});
                        add(new HashMap() {{
                            put("key", "loginName");
                            put("description", "登录名");
                        }});
                    }
                });
                put("markList", new ArrayList() {
                    {
                        add(new HashMap() {{
                            put("key", "developing");
                            put("name", "开发中");
                            put("color", "#3A86FF");
                            put("is_default", true);
                        }});
                        add(new HashMap() {{
                            put("key", "POST");
                            put("name", "POST请求");
                            put("color", "#2BA58F");
                            put("is_default", true);
                        }});
                        add(new HashMap() {{
                            put("key", "GET");
                            put("name", "GET请求");
                            put("color", "#EC4646");
                            put("is_default", true);
                        }});
                    }
                });
                put("script", new HashMap() {{
                    put("pre_script", "");
                    put("test", "");
                }});
                put("request", new HashMap() {{
                    put("query", new ArrayList());
                    put("header", new ArrayList());
                    put("body", new ArrayList());
                }});
            }});
        }});
        jsonMap.put("apis", allFolderList);
        jsonMap.put("envs", new ArrayList() {{
            add(new HashMap() {{
                put("env_id", "f69e93ad-67bc-4bcf-82ac-d3ddc844ff21");
                put("list", new HashMap());
                put("name", "接口文档");
                put("pre_url", "http://192.168.0.188:8082");
            }});
            add(new HashMap() {{
                put("env_id", "-1");
                put("list", new HashMap());
                put("name", "默认环境");
                put("pre_url", "");
            }});
            add(new HashMap() {{
                put("env_id", "-2");
                put("list", new HashMap());
                put("name", "Mock环境");
                put("pre_url", "");
            }});
        }});
        String json = JSONObject.toJSONString(jsonMap);
        FileUtils.writeStringToFile(new File(filePath), json, "UTF-8");
    }
 
 
    /**
     * 生成json文件
     * 根据原json文件生成新的json文件
     *
     * @param jsonFile
     * @throws IOException
     */
    public void creteJsonFile(File jsonFile) throws IOException {
        // 读取apiJson.json文件
        String oldJsonString = FileUtils.readFileToString(jsonFile, "UTF-8");
        JSONObject oldJson = JSONObject.parseObject(oldJsonString);
        // 过滤掉已经存在的接口
        List allOldApiList = new ArrayList();
        List oldApiList = (List) oldJson.get("apis");
        // 递归获取所有接口
        getAllApiList(oldApiList, allOldApiList);
 
        Set oldApiNameList = new HashSet();
        for (Map oldApi : allOldApiList) {
            Map request = (Map) oldApi.get("request");
            oldApiNameList.add(request.get("url").toString());
        }
        log.info("oldApiNameList:{}", oldApiNameList);
        // 查询数据库
        // 已经包含的接口排除掉
        List newApiList = sysLogMapper.listForJson(new HashMap() {{
            put("pathList", oldApiNameList);
        }});
        List apiJson = extractApiJson(newApiList,true);
        // 合并json
        oldApiList.addAll(apiJson);
        // 写入新文件
        // 在源文件名后面加上new
        String newFileName = jsonFile.getAbsolutePath().replace(".json", "-new.json");
        FileUtils.writeStringToFile(new File(newFileName), oldJson.toJSONString(), "UTF-8");
    }
 
    /**
     * 提取接口json
     *
     * @param mapList
     * @return
     */
    public static List extractApiJson(List mapList,boolean createRootFolder) {
        List allFolderList = new ArrayList();
        List allFolderNameList = new ArrayList();
        List allApiNameList = new ArrayList();
        for (int i = 0, mapListSize = mapList.size(); i < mapListSize; i++) {
            Map dbMap = mapList.get(i);
            List children = new ArrayList();
            String title = dbMap.get("title").toString();
            if (allFolderNameList.contains(title)) {
                children = (List) allFolderList.get(allFolderNameList.indexOf(title)).get("children");
            } else {
                Map folderMap = new HashMap();
                folderMap.put("target_type", "folder");
                folderMap.put("name", title);
                folderMap.put("mark", "developing");
                folderMap.put("sort", 2 + i);
                folderMap.put("request", new HashMap() {{
                    put("description", "");
                }});
                folderMap.put("children", children);
                allFolderList.add(folderMap);
                allFolderNameList.add(title);
            }
            String path = dbMap.getOrDefault("path","").toString();
            if (allApiNameList.contains(path)) {
                continue;
            }
            //过滤参数
 
            Object parameter = getMyParameter(dbMap.get("parameter"));
 
            allApiNameList.add(path);
            Map apiMap = new HashMap();
            apiMap.put("target_type", "api");
            apiMap.put("name", dbMap.get("action"));
            apiMap.put("mark", dbMap.get("requestMethod"));
            apiMap.put("sort", 1 + i);
            apiMap.put("method", dbMap.get("requestMethod"));
            apiMap.put("mock", "{}");
            apiMap.put("mock_url", "");
            apiMap.put("request", new HashMap() {{
                put("url", dbMap.get("path"));
                put("description", "");
                put("event", new HashMap() {{
                    put("pre_script", "");
                    put("test", "");
                }});
                put("body", new HashMap() {{
                    put("mode", "json");
                    put("parameter", new ArrayList());
                    put("raw", parameter);
                    put("raw_para", new ArrayList());
                }});
            }});
            apiMap.put("response", new HashMap() {{
                put("success", new HashMap() {{
                    put("raw", dbMap.get("result"));
                    put("parameter", new ArrayList());
                    put("expect", new HashMap() {{
                        put("mock", "{}");
                    }});
                }});
                put("error", new HashMap() {{
                    put("raw", "");
                    put("parameter", new ArrayList());
                }});
            }});
            apiMap.put("children", new ArrayList());
            children.add(apiMap);
        }
        log.info("本次新增接口数量:{},文件夹数量:{},接口名称:{}", allApiNameList.size(), allFolderNameList.size(), allApiNameList);
        if(createRootFolder){
            Map rootFolder = new HashMap();
            rootFolder.put("target_type", "folder");
            rootFolder.put("name", "接口文档");
            rootFolder.put("mark", "developing");
            rootFolder.put("sort", 1);
            rootFolder.put("request", new HashMap() {{
                put("description", "");
            }});
            rootFolder.put("children", allFolderList);
            allFolderList = new ArrayList() {{
                add(rootFolder);
            }};
        }
        return allFolderList;
    }
 
    private static Object getMyParameter(Object parameter) {
        if (parameter == null) {
            return null;
        }
        String parameterString = parameter.toString();
        //如果是json对象,提取除其中的Map
        if (parameterString.startsWith("{") && parameterString.endsWith("}")) {
            JSONObject jsonObject = JSONObject.parseObject(parameterString);
            Map map = new HashMap<>();
            for (Map.Entry entry : jsonObject.entrySet()) {
                Object value = entry.getValue();
                //不包含”忽略请求参数“
                if (value instanceof Map ){
                    return JSONObject.toJSONString(value);
                }
                if (value.toString().contains("忽略请求参数")) {
                    continue;
                }
                map.put(entry.getKey(), value);
            }
            return JSONObject.toJSONString(map);
        }
        return parameterString;
    }
 
    /**
     * 递归获取所有接口
     * @param oldApiList
     * @param allOldApiList
     */
    private void getAllApiList(List oldApiList, List allOldApiList) {
        for (Map oldApiMap : oldApiList) {
            if ("api".equals(oldApiMap.get("target_type"))) {
                allOldApiList.add(oldApiMap);
            } else {
                List children = (List) oldApiMap.get("children");
                getAllApiList(children, allOldApiList);
            }
        }
    }
} 

2、将生成的test.json文件导入ApiPost中,效果展示

 3、这里只贴出了关键部分代码,如果有哪里不清楚的欢迎留言