一、引入AOP依賴
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
二、生成必要枚舉類和接口
(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<Integer> getIgnoreResultKeys() {
List<Integer> 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<String, Object> 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<String, Object> getNameAndValue(JoinPoint joinPoint) {
Map<String, Object> 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<Map> mapList = sysLogMapper.listForJson(new HashMap());
List<Map> 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<Map> allOldApiList = new ArrayList();
List<Map> oldApiList = (List<Map>) oldJson.get("apis");
// 遞歸擷取所有接口
getAllApiList(oldApiList, allOldApiList);
Set<String> oldApiNameList = new HashSet();
for (Map oldApi : allOldApiList) {
Map request = (Map) oldApi.get("request");
oldApiNameList.add(request.get("url").toString());
}
log.info("oldApiNameList:{}", oldApiNameList);
// 查詢資料庫
// 已經包含的接口排除掉
List<Map> newApiList = sysLogMapper.listForJson(new HashMap() {{
put("pathList", oldApiNameList);
}});
List<Map> 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<Map> extractApiJson(List<Map> mapList,boolean createRootFolder) {
List<Map> allFolderList = new ArrayList();
List<String> allFolderNameList = new ArrayList();
List<String> allApiNameList = new ArrayList();
for (int i = 0, mapListSize = mapList.size(); i < mapListSize; i++) {
Map dbMap = mapList.get(i);
List<Map> children = new ArrayList();
String title = dbMap.get("title").toString();
if (allFolderNameList.contains(title)) {
children = (List<Map>) 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<String, Object> map = new HashMap<>();
for (Map.Entry<String, Object> 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<Map> oldApiList, List<Map> allOldApiList) {
for (Map oldApiMap : oldApiList) {
if ("api".equals(oldApiMap.get("target_type"))) {
allOldApiList.add(oldApiMap);
} else {
List<Map> children = (List<Map>) oldApiMap.get("children");
getAllApiList(children, allOldApiList);
}
}
}
}
2、将生成的test.json檔案導入ApiPost中,效果展示
3、這裡隻貼出了關鍵部分代碼,如果有哪裡不清楚的歡迎留言