【原创】Java反射自动生成POSTMAN测试接口文档

通过pb文件生成的Java接口,转成postman说需要的json格式字符串,直接上代码:

 /**
 * @param path
 * @description 具体解析path路径
 */
 public Map<String, Object> doGeneratePostManCollections(String path) {
    String[] params = path.split("/");
    String clsName = "";
    int port = 8000;
    if (params.length == 2) return null;
    else if (params.length == 3) {
        if (!params[2].matches("[0-9]+"))
            clsName = params[2];
        else return null;
    } else if (params.length == 4) {
        if (!params[2].matches("[0-9]+")) {
            clsName = params[2];
            if (params[3].matches("[0-9]+")) port = Integer.valueOf(params[3]);
        } else if (!params[3].matches("[0-9]+")) {
            clsName = params[3];
            if (params[2].matches("[0-9]+")) port = Integer.valueOf(params[2]);
        }
    } else return null;
    System.out.print(clsName + ":" + port);
    return generatePostManCollections(clsName, port);

}


/**
 * @param clsName
 * @param port
 * @description 获取当前服务所有接口,构造postman服务,这里可以选择当前所有服务的接口所在接口名,或者单独某个接口的类名
 */
private Map<String, Object> generatePostManCollections(String clsName, int port) {
    if (StringUtils.isEmpty(clsName)) return null;
    int a = clsName.lastIndexOf(".");
    String serviceName = clsName.substring(a + 1);
    Map<String, Object> map = new HashMap<>();
    map.put("id", UUID.randomUUID().toString());
    map.put("name", serviceName);
    try {
        Class<?> cls = Class.forName(clsName);
        //获取对象中的所有方法
        Method[] methods = cls.getDeclaredMethods();
        List<Map<String, Object>> params = new ArrayList<>();
        //解析方法参数
        analysisMethodParam(port, methods, serviceName, params);
        map.put("requests", params);
        return map;
    } catch (
            ClassNotFoundException e) {
        e.printStackTrace();
    }
    return null;
}

/**
 * @param methods
 * @param port
 * @param serviceName
 * @param params
 * @description 查找方法的参数
 */
private void analysisMethodParam(int port, Method[] methods, String serviceName, List<Map<String, Object>> params) {
    for (int i = 0; i < methods.length; i++) {
        Map<String, Object> param = new HashMap<>();
        //基本参数设值
        createBaseParam(methods[i], i, param, port, serviceName);
        //获取本方法所有参数类型,存入数组
        Class<?>[] parameterTypes = methods[i].getParameterTypes();
        //标签rawModeData代表真正的入参
        Map<String, Object> rawMap = new HashMap<>();
        getParameters(parameterTypes, rawMap);
        //postman解析的时候,入参先转json字符串
        param.put("rawModeData", Json.toJson(rawMap));
        params.add(param);
    }
}

/**
 * @param method
 * @param i
 * @param param
 * @param port
 * @param serviceName
 * @description 设置基本参数
 */
private void createBaseParam(Method method, int i, Map<String, Object> param, int port, String serviceName) {
    //获取方法名字
    String methodName = method.getName();
    param.put("id", UUID.randomUUID().toString() + i);
    param.put("name", methodName);
    param.put("url", "http://127.0.0.1:" + port + "/" + serviceName + "/" + methodName);
    param.put("dataMode", "raw");
    param.put("method", "POST");
    param.put("headers", "Content-Type:application/json");
}

/**
 * @param parameterTypes
 * @param rawMap
 * @description 获取接口参数
 */
private void getParameters(Class<?>[] parameterTypes, Map<String, Object> rawMap) {
    for (int j = 0; j < parameterTypes.length; j++) {
        String parameterName = parameterTypes[j].getName();
        Class<?> clazz = null;
        try {
            clazz = Class.forName(parameterName);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        Field[] fields = clazz.getDeclaredFields();
        //具体的参数
        createParam(fields, rawMap);
    }
}


/**
 * @param fields
 * @param param
 * @description 设置接口的入参
 */
private void createParam(Field[] fields, Map<String, Object> param) {
    for (Field f : fields) {
        int k = f.getModifiers();
        String decorate = Modifier.toString(k);
        //找到被private修饰的方法,是我们想要的真正入参
        if (!f.isAccessible() && !decorate.contains("final")) {
            Class<?> T = f.getType();
            //依据pb定义来的Arrays.asList(classes).contains(T)
            if (T.getClass() instanceof Object) {
                String paramName = f.getName().substring(0, f.getName().length() - 1);
                if (paramName.contains("bitField0") || paramName.contains("memoizedIsInitialize")) continue;
                //获取并判断选择参数类型
                chooseParamType(T, param, paramName, f);
            }
        }
    }
}

//过滤条件
private static Class<?>[] classes = new Class<?>[]{int.class, Integer.class, Object.class,
        List.class, long.class, Long.class, double.class, Double.class, LazyStringList.class};

/**
 * @param T
 * @param param
 * @param f
 * @description 判断并选择参数
 */
private void chooseParamType(Class<?> T, Map<String, Object> param, String paramName, Field f) {
    //从具体的类到对象类
    if (T == String.class || T == Object.class) {
        param.put(paramName, paramName);
    } else if (T == int.class || T == Integer.class || T == double.class || T == Double.class || T == Long.class || T == long.class) {
        param.put(paramName, 1);
    } else if (T == List.class) {
        //继续深挖List对象里的类
        // 如果是List类型,得到其Generic的类型
        Type genericType = f.getGenericType();
        createListParam(genericType, paramName, param);
    } else if (T == LazyStringList.class) {
        //List<String>格式
        List<String> listParam = new ArrayList<>();
        listParam.add(paramName);
        param.put(paramName, listParam);
    } else if (T.getClass() instanceof Object) {
        Field[] listFields = T.getDeclaredFields();
        //List的内部对象
        Map<String, Object> innerParam = new HashMap<>();
        //递归获取参数
        createParam(listFields, innerParam);
        param.put(paramName, innerParam);
    }
}

/**
 * @param paramName
 * @param genericType
 * @param param
 * @description 构造List参数
 */
private void createListParam(Type genericType, String paramName, Map<String, Object> param) {
    if (genericType == null) return;
    // 如果是泛型参数的类型
    if (genericType instanceof ParameterizedType) {
        ParameterizedType pt = (ParameterizedType) genericType;
        //得到泛型里的class类型对象
        Class<?> genericClazz = (Class<?>) pt.getActualTypeArguments()[0];
        Field[] listFields = genericClazz.getDeclaredFields();
        //参数格式是List的
        List<Map<String, Object>> listParam = new ArrayList<>();
        //List的内部对象
        Map<String, Object> innerParam = new HashMap<>();
        //递归获取参数
        createParam(listFields, innerParam);
        listParam.add(innerParam);
        param.put(paramName, listParam);
    }
}

示例:
在这里插入图片描述
生成的json字符串放入json文件,然后导入postman:
在这里插入图片描述
当前微服务所有接口已经成功导入,你只要改值测试即可:
在这里插入图片描述

在这里插入图片描述

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值