美文网首页
通过Swagger拉去所有接口,记录用户操作日志

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

作者: 纬一 | 来源:发表于2019-10-05 14:59 被阅读0次

    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<Map<String,Object>> swaggerAllMethod = new ArrayList<>();
                ObjectMapper objectMapper = new ObjectMapper();
                String swaggerJson = HttpUtils.get(SWAGGER_PATH, null, 3000, 3000, "UTF-8");
                Map<String, Object> swaggerMap = objectMapper.readValue(swaggerJson, Map.class);
                LinkedHashMap<String, Object> pathsMap = (LinkedHashMap<String, Object>) swaggerMap.get("paths");// 所有方法
                pathsMap.entrySet().stream().forEach(s -> {
                    String method = s.getKey();
                    LinkedHashMap<String, Object> methodMode = ((LinkedHashMap<String, Object>) pathsMap.get(s.getKey()));// 所有請求方式GET、POST等
                    methodMode.entrySet().stream()
                            .filter(model -> "get".equals(model.getKey()) || "post".equals(model.getKey()))
                            .forEach(m -> {
                                LinkedHashMap<String, Object> methodBody = (LinkedHashMap<String, Object>) methodMode.get(m.getKey());
                                String methodName = (String) methodBody.get("summary");
                                methodBody.entrySet().stream()
                                        .filter(tags -> "tags".equals(tags.getKey()))// tags里是模块名称
                                        .forEach(tags -> {
                                            ArrayList<Object> tagList = (ArrayList<Object>) tags.getValue();
                                            String modeName = (String) tagList.get(0);
                                            Map<String, Object> 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拉去所有接口,记录用户操作日志

          本文链接:https://www.haomeiwen.com/subject/uzoepctx.html