通过Swagger拉去所有接口,记录用户操作日志

Swagger接口获取到的数据格式:
我们主要关注paths属性

{
    "swagger": "2.0",
    "info": {
        "description": "Admin-api",
        "version": "2.0",
        "title": " 接口文档"
    },
    "host": "localhost:8081",
    "basePath": "/",
    "tags": [{
        "name": "数据统计相关",
        "description": "Statistic Controller"
    }, {
        "name": "文章管理",
        "description": "Article Controller"
    }, {
        "name": "用户安全",
        "description": "Admin Controller"
    }, {
        "name": "用户管理",
        "description": "User Controller"
    }],
    "paths": {
        "/statistic/dataFinanceOverView": {
            "get": {
                "tags": ["数据统计相关"],
                "summary": "财务数据概览",
                "operationId": "dataFinanceOverViewUsingGET",
                "produces": ["*/*"],
                "parameters": [{
                    "name": "Authorization",
                    "in": "header",
                    "description": "令牌",
                    "required": false,
                    "type": "string"
                }, {
                    "name": "endDate",
                    "in": "query",
                    "description": "结束日期",
                    "required": true,
                    "type": "string"
                }, {
                    "name": "startDate",
                    "in": "query",
                    "description": "开始日期",
                    "required": true,
                    "type": "string"
                }],
                "responses": {
                    "200": {
                        "description": "OK",
                        "schema": {
                            "$ref": "#/definitions/DataFinanceOverView",
                            "originalRef": "DataFinanceOverView"
                        }
                    },
                    "401": {
                        "description": "Unauthorized"
                    },
                    "403": {
                        "description": "Forbidden"
                    },
                    "404": {
                        "description": "Not Found"
                    }
                },
                "deprecated": false
            }
        },
        "/statistic/dataOperateOverView": {
            "get": {
                "tags": ["数据统计相关"],
                "summary": "运营数据概览",
                "operationId": "dataOperateOverViewUsingGET",
                "produces": ["*/*"],
                "parameters": [{
                    "name": "Authorization",
                    "in": "header",
                    "description": "令牌",
                    "required": false,
                    "type": "string"
                }, {
                    "name": "endDate",
                    "in": "query",
                    "description": "结束日期",
                    "required": true,
                    "type": "string"
                }, {
                    "name": "startDate",
                    "in": "query",
                    "description": "开始日期",
                    "required": true,
                    "type": "string"
                }],
                "responses": {
                    "200": {
                        "description": "OK",
                        "schema": {
                            "$ref": "#/definitions/DataOperateOverView",
                            "originalRef": "DataOperateOverView"
                        }
                    },
                    "401": {
                        "description": "Unauthorized"
                    },
                    "403": {
                        "description": "Forbidden"
                    },
                    "404": {
                        "description": "Not Found"
                    }
                },
                "deprecated": false

            }
        }
    }
}

我们只需要三个值

{
    "paths": {
        "/statistic/dataFinanceOverView": {
            "get": {
                "tags": ["数据统计相关"],
                "summary": "财务数据概览"
            }
        }
    }
}

最终解析后得到的数据格式

[{
    "modelName": "数据统计相关",
    "method": "/statistic/financeStatisticInfoView",
    "methodName": "财务统计"
}, {
    "modelName": "数据统计相关",
    "method": "/statistic/operationReport",
    "methodName": "运营报表"
}, {
    "modelName": "数据统计相关",
    "method": "/statistic/userStatisticsInfoView",
    "methodName": "用户统计"
}]

Swagger工具类

import com.aliyuncs.utils.StringUtils;
import org.codehaus.jackson.map.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import vip.shuashua.repayment.utils.HttpUtils;
import vip.shuashua.repayment.utils.RedisKey;

import java.io.IOException;
import java.util.*;

/**
 * 通过Swagger获取所有接口方法,缓存至Redis
 * Created by LiuJingWei on 2019-09-26.
 */
@Component
public class AdminSwaggerAllMethod implements ApplicationRunner {

    private Logger logger = LoggerFactory.getLogger(AdminSwaggerAllMethod.class);

    @Autowired
    private StringRedisTemplate redisTemplate;

    // http://localhost:8081/v2/api-docs
    @Value("${swagger.get.all.method.url}")
    private String SWAGGER_PATH;

    @Override
    public void run(ApplicationArguments args) {
        if (redisTemplate.hasKey(RedisKey.WEB_SWAGGER_ALL_METHOD.getKey())) {
            redisTemplate.delete(RedisKey.WEB_SWAGGER_ALL_METHOD.getKey());
        }
        String swaggerAllMethodJson = getSwaggerAllMethod();
        if (StringUtils.isNotEmpty(swaggerAllMethodJson)) {
            redisTemplate.opsForValue().set(RedisKey.WEB_SWAGGER_ALL_METHOD.getKey(), swaggerAllMethodJson);
            logger.info(String.format("动态通过Swagger解析所有接口方法成功!并加入Redis缓存key:%s,value:%s", RedisKey.WEB_SWAGGER_ALL_METHOD.getKey(), swaggerAllMethodJson));
        } else {
            logger.error("动态通过Swagger解析所有接口方法失败!");
        }
    }

    /**
    * 获取Swagger所有接口方法
    * # 这里注意一点,我们只获取了GET、POST方法
    */
    public String getSwaggerAllMethod(){
        try {
            List> swaggerAllMethod = new ArrayList<>();
            ObjectMapper objectMapper = new ObjectMapper();
            String swaggerJson = HttpUtils.get(SWAGGER_PATH, null, 3000, 3000, "UTF-8");
            Map swaggerMap = objectMapper.readValue(swaggerJson, Map.class);
            LinkedHashMap pathsMap = (LinkedHashMap) swaggerMap.get("paths");// 所有方法
            pathsMap.entrySet().stream().forEach(s -> {
                String method = s.getKey();
                LinkedHashMap methodMode = ((LinkedHashMap) pathsMap.get(s.getKey()));// 所有請求方式GET、POST等
                methodMode.entrySet().stream()
                        .filter(model -> "get".equals(model.getKey()) || "post".equals(model.getKey()))
                        .forEach(m -> {
                            LinkedHashMap methodBody = (LinkedHashMap) methodMode.get(m.getKey());
                            String methodName = (String) methodBody.get("summary");
                            methodBody.entrySet().stream()
                                    .filter(tags -> "tags".equals(tags.getKey()))// tags里是模块名称
                                    .forEach(tags -> {
                                        ArrayList tagList = (ArrayList) tags.getValue();
                                        String modeName = (String) tagList.get(0);
                                        Map swaggerMethod = new HashMap<>();
                                        swaggerMethod.put("method", method);
                                        swaggerMethod.put("modelName", modeName);
                                        swaggerMethod.put("methodName", methodName);
                                        swaggerAllMethod.add(swaggerMethod);
                                    });
                        });
            });

            return objectMapper.writeValueAsString(swaggerAllMethod);
        } catch (IOException e) {
            logger.error("通过Swagger解析所有接口异常",e);
            return null;
        }
    }

}

 
 

ApplicationRunner 接口中的run方法是在项目启动成功后执行的

数据存入Redis中,然后就可以使用过滤器,拦截每次请求后,使用方法名做对比,获取接口中文描述啦。

这里推荐继承Spring的OncePerRequestFilter,重写doFilterInternal方法
可以获取到请求参数以及相应参数列表,加上方法名以及中文描述,基本满足操作日志记录的要求

后面有空会把整体代码上传至github中...

你可能感兴趣的:(通过Swagger拉去所有接口,记录用户操作日志)