基于freemark、swagger自动生成confluence接口文档

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style type="text/css">
        body, table {
            color: #333;
            font-family: Arial, sans-serif;
            font-size: 14px;
            line-height: 1.42857142857143;
            color: #333;
        }

        strong, b {
            font-weight: bold;
        }

        li {
            display: list-item;
            text-align: -webkit-match-parent;
            list-style-type: disc;
        }

        table {
            display: table;
            border-collapse: separate;
            border-spacing: 2px;
            border-color: grey;
        }

        thead {
            display: table-header-group;
            vertical-align: middle;
            border-color: inherit;
        }

        tr {
            display: table-row;
            vertical-align: inherit;
            border-color: inherit;
        }

        table.tablesorter > thead > tr > th {
            background: #F0F0F0 center right no-repeat;
            padding-right: 15px;
            cursor: pointer;
        }

        .wiki-content .tablesorter-header-inner, table.confluenceTable th.confluenceTh {
            color: #333333;
        }

        .confluenceTable {
            border-collapse: collapse;
        }

        .confluenceTable:first-child {
            margin-top: 0;
        }

        .confluenceTable, .table-wrap {
            margin: 10px 0 0 0;
            overflow-x: auto;
        }

        .confluenceTh, .confluenceTd {
            border: 1px solid #ddd;
            padding: 7px 10px;
            vertical-align: top;
            text-align: left;
        }

    </style>

</head>
<body>
<ul>
    <li>
        <strong>功能描述</strong>
        <br/>
        $funcDescribe
        <br/>
        <br/>
    </li>
    <li>
        <strong>接口信息</strong>
        <br/>
        1,请求方式:$requestMethod
        <br/>
        2,服务地址:$requestUrl
        <br/>
        3,请求参数类型:Json
        <br/>
        4,返回参数类型:Json
        <br/>
        <br/>
    </li>
    <li>
        <p>
            <strong>接口参数</strong>
            <br/>
            $inInfo
        </p>
        $inTable
        <br/>
    </li>

    <li>
        <p>
            <strong>返回值</strong>
            <br/>
            $returnInfo
        </p>
        $returnTable
    </li>

</ul>
</body>
</html>

public class DocGeneratorGA {

    public static void main(String[] args) throws IOException, TemplateException {

        DocGeneratorGA docGeneratorGA = new DocGeneratorGA();
        docGeneratorGA.generate(new LetterCheckController(), "delete");
    }

    private <T> void generate(T t, String methodName) throws IOException, TemplateException {
        // first step:instance freemarker configuration
        Configuration configuration = new Configuration();

        // second step:set configuration directory
        String dir = DocGeneratorGA.class.getResource("/phalaenopsis/common/doc").getPath();
        configuration.setDirectoryForTemplateLoading(new File(dir));

        Template template = configuration.getTemplate("ApiDocTemplate.html");

        String exportDir = JOptionPane.showInputDialog("请输入文档导出目录");

        // export html
        Writer out = new FileWriter(new File(exportDir + File.separator + methodName + ".html"));

        Map map = new DocGeneratorGA().defineData(t, methodName);

        template.process(map, out);

        out.flush();
        out.close();
    }


    private <T> Map defineData(T t, String methodName) {

        DocGeneratorTools docGeneratorTools = new DocGeneratorTools();
        Map map = docGeneratorTools.returnMethodParamMap(t, methodName);
        return map;

    }

public class DocGeneratorTools {

    /**
     * 添加slf4j写日志对象
     */
    private static final Logger logger = LoggerFactory.getLogger(DocGeneratorTools.
            class);


    /**
     * 设置Map大小常量
     */
    private static final int MAP_SIZE = 6;

    /**
     * 名称
     */
    private static final String NAME = "name";

    /**
     * 说明
     */
    private static final String DESCRIBE = "describe";

    /**
     * 类型
     */
    private static final String TYPE = "type";

    /**
     * 是否必要参数
     */
    private static final String REQUIRE = "require";

    /**
     * 例子
     */
    private static final String EXAMPLE = "example";

    /**
     * Generic type
     */
    private static final String SUB_CLASS = "subClass";

    /**
     * 反射获取实体字段中,需要排除的字段。如
     */
    private static final String[] EXCLUDE_FIELDS = {"serialVersionUID"};


    /**
     * 包装类型类全名
     */
    private static String[] classes = {
            "java.lang.Byte",
            "java.lang.Short",
            "java.lang.Integer",
            "java.lang.Long",
            "java.lang.Double",
            "java.lang.Float",
            "java.lang.Boolean",
            "java.util.Date"
    };


    public <T> Map returnMethodParamMap(T t, String methodName) {

        Map<String, Object> map = new HashMap<String, Object>();

        Method[] methods = t.getClass().getMethods();
        RequestMapping clazzRequestMapper = t.getClass().getAnnotation(RequestMapping.class);


        List<Method> listMethod = Arrays.asList(methods);
        Method method = Linq.extEquals(listMethod, "name", methodName);
        RequestMapping methodRequestMapper = method.getAnnotation(RequestMapping.class);

        //0,得到方法描述
        ApiOperation apiOperation = method.getAnnotation(ApiOperation.class);
        map.put("funcDescribe", apiOperation.value());

        //1,得到完整的URL路径
        String mappingUrl = clazzRequestMapper.value()[0] + methodRequestMapper.value()[0];
        map.put("requestUrl", mappingUrl);


        //2,得到请求方法:GET、POST、PUT、Delete
        String requestMethod = methodRequestMapper.method()[0].name();
        map.put("requestMethod", requestMethod);

        // 2.1得到返回的GenericReturnType
        Type genericReturnType = null;
        Type returnType = method.getGenericReturnType();
        if (returnType instanceof ParameterizedType) {
            Type[] genericTypes = ((ParameterizedType) returnType).getActualTypeArguments();
            genericReturnType = genericTypes[0];
        }

        // 2.2得到传入参数泛型
        Type genericParameterType = null;
        Type[] parameterTypes = method.getGenericParameterTypes();
        for (Type parameterType : parameterTypes) {
            if (parameterType instanceof ParameterizedType) {
                Type[] genericTypes = ((ParameterizedType) parameterType).getActualTypeArguments();
                genericParameterType = genericTypes[0];
            }
        }


        //3,传入参数
        Parameter[] inParameters = method.getParameters();
        List<Map<String, String>> inListParam = new ArrayList<>();
        for (Parameter parameter : inParameters) {
            if (parameter.getType().isPrimitive()) {
                // 简单类型
                inListParam.add(getPrimitiveParameterMap(parameter));
            } else if (parameter.getType().isArray()) {
                // 是否为集合
            } else if (Arrays.binarySearch(classes, parameter.getType().getName()) > -1) {
                // 包装类型
                inListParam.add(getPrimitiveParameterMap(parameter));
            } else if (parameter.getType() == java.util.List.class) {

            } else {
                // 普通类
                Field[] fields = parameter.getType().getDeclaredFields();
                for (Field field : fields) {
                    if (Arrays.binarySearch(EXCLUDE_FIELDS, field.getName()) == -1) {
                        inListParam.add(getFieldMap(field, genericParameterType));
                    }
                }
            }
        }


        map.put("inList", inListParam);


        //4,得到返回参数
        Class<?> clazz = method.getReturnType();
        List<Map<String, String>> outListParam = new ArrayList<>();
        if (clazz.isPrimitive()) {
            // 简单类型
            outListParam.add(getReturnPrimitiveMap(clazz));
        } else if (clazz.isArray()) {
            // 数组
        } else if (Arrays.binarySearch(classes, clazz.getName()) > -1) {
            // 包装类型
            outListParam.add(getReturnPrimitiveMap(clazz));
        } else {
            // 实体类
            Field[] fields = clazz.getDeclaredFields();
            for (Field field : fields) {
                if (Arrays.binarySearch(EXCLUDE_FIELDS, field.getName()) == -1) {
                    outListParam.add(getFieldMap(field, genericReturnType));
                }
            }
        }
        map.put("outList", outListParam);

        return map;
    }

    /**
     * 简单类型map
     */
    private Map<String, String> returnPrimitiveMap;

    /**
     * 获取返回简单类型map
     *
     * @return
     */
    private Map getReturnPrimitiveMap(Class<?> clazz) {
        returnPrimitiveMap = new HashMap<>(MAP_SIZE);
        primitiveMap.put(TYPE, clazz.getName());
        primitiveMap.put(NAME, "");
        primitiveMap.put(DESCRIBE, "");
        primitiveMap.put(REQUIRE, "");
        primitiveMap.put(EXAMPLE, "");
        return returnPrimitiveMap;
    }

    /**
     * 包装类型map
     */
    private Map<String, String> returnWrapMap;

    /**
     * 返回包装类型map
     *
     * @param clazz
     * @return
     */
    private Map getReturnWarpMap(Class<?> clazz) {
        returnPrimitiveMap = getReturnPrimitiveMap(clazz);
        return returnPrimitiveMap;
    }


    private Map<String, String> primitiveMap;

    /**
     * 返回简单类型Map
     *
     * @param parameter
     * @return
     */
    private Map getPrimitiveParameterMap(Parameter parameter) {
        //如果为简单类型
        primitiveMap = new HashMap<>(MAP_SIZE);
        primitiveMap.put(TYPE, parameter.getType().getName());
        ApiParam apiParam = parameter.getDeclaredAnnotation(ApiParam.class);
        PathParam pathParam = parameter.getDeclaredAnnotation(PathParam.class);
        RequestParam requestParam = parameter.getDeclaredAnnotation(RequestParam.class);

        primitiveMap.put(NAME, "");
        primitiveMap.put(DESCRIBE, "");
        primitiveMap.put(REQUIRE, "");
        primitiveMap.put(EXAMPLE, "");

        if (null != pathParam) {
            primitiveMap.put(NAME, pathParam.value());
        }

        if (null != requestParam) {
            primitiveMap.put(NAME, requestParam.value());
            primitiveMap.put(REQUIRE, requestParam.required() ? "是" : "否");
        }

        if (null != apiParam) {
            primitiveMap.put(NAME, "");
            primitiveMap.put(DESCRIBE, apiParam.value());
            primitiveMap.put(REQUIRE, apiParam.required() ? "是" : "否");
            primitiveMap.put(EXAMPLE, apiParam.example());
        }

        return primitiveMap;
    }

    /**
     * 获取包装类型
     */
    private Map<String, String> warpMap;

    /**
     * 返回包装类型Map
     *
     * @return
     */
    private Map getWarpperMap(Parameter parameter) {

        warpMap = getPrimitiveParameterMap(parameter);

        return warpMap;
    }

    /**
     * 成员字段
     */
    private Map<String, Object> fieldMap;

    /**
     * 泛型成员字段
     */
    private Map<String, Object> genericFieldMap;

    private Map createFieldMap(Field field, Map map, ApiModelProperty apiModel) {
        map = new HashMap<>(MAP_SIZE);
        map.put(NAME, field.getName());
        map.put(TYPE, field.getType().getName());
        if (null != apiModel) {
            map.put(DESCRIBE, apiModel.value());
            map.put(REQUIRE, apiModel.required() ? "是" : "否");
            map.put(EXAMPLE, apiModel.example());
        } else {
            map.put(DESCRIBE, "");
            map.put(REQUIRE, "否");
            map.put(EXAMPLE, "");
        }
        return map;
    }

    /**
     * @return
     */
    private Map getGenericFieldMap(Field field) {
        ApiModelProperty apiModelProperty = field.getDeclaredAnnotation(ApiModelProperty.class);
        genericFieldMap = new HashMap<>(MAP_SIZE);
        genericFieldMap = createFieldMap(field, genericFieldMap, apiModelProperty);
        return genericFieldMap;
    }


    /**
     * 获取字段map
     *
     * @param field
     * @return
     */
    private Map getFieldMap(Field field, Type methodGenericType) {


        ApiModelProperty apiModelProperty = field.getDeclaredAnnotation(ApiModelProperty.class);
        fieldMap = new HashMap<>(MAP_SIZE);
        fieldMap = createFieldMap(field, fieldMap, apiModelProperty);

        Type genericTypeSingle = field.getGenericType();
        if (null != genericTypeSingle) {
            if (genericTypeSingle instanceof TypeVariable) {
                if (null != methodGenericType) {
                    List<Map<String, Object>> genericMapList = new ArrayList<Map<String, Object>>();
                    Field[] genericFields = new Field[0];
                    try {

                        genericFields = Class.forName(methodGenericType.getTypeName()).getDeclaredFields();

                    } catch (ClassNotFoundException e) {
                        e.printStackTrace();
                    }
                    for (Field subField : genericFields) {
                        if (Arrays.binarySearch(EXCLUDE_FIELDS, subField.getName()) == -1) {
                            genericMapList.add(getGenericFieldMap(subField));
                        }
                    }
                    fieldMap.put(SUB_CLASS, genericMapList);
                }
            }
        }


        // 如果field不是简单类型、不是包装类型、
        if (field.getType() == java.util.List.class || field.getType().isArray()) {
            //如果是List类型,得到GeneraticType
            Type genericType = field.getGenericType();
            if (null != genericType) {
                // 如果是泛型参数类型
                if (genericType instanceof ParameterizedType) {
                    ParameterizedType pt = (ParameterizedType) genericType;
                    List<Map<String, Object>> genericMapList = new ArrayList<Map<String, Object>>();
                    if (pt.getActualTypeArguments()[0] instanceof Class<?>) {
                        Class<?> genericClazz = (Class<?>) pt.getActualTypeArguments()[0];
                        Field[] genericFields = genericClazz.getDeclaredFields();

                        for (Field subField : genericFields) {
                            if (Arrays.binarySearch(EXCLUDE_FIELDS, field.getName()) == -1) {
                                genericMapList.add(getGenericFieldMap(subField));
                            }
                        }
                    } else {
                        Field[] genericFields = new Field[0];
                        try {
                            if (null != methodGenericType) {
                                genericFields = Class.forName(methodGenericType.getTypeName()).getDeclaredFields();
                            }
                        } catch (ClassNotFoundException e) {
                            e.printStackTrace();
                        }
                        for (Field subField : genericFields) {
                            if (Arrays.binarySearch(EXCLUDE_FIELDS, subField.getName()) == -1) {
                                genericMapList.add(getGenericFieldMap(subField));
                            }
                        }
                    }

                    fieldMap.put(SUB_CLASS, genericMapList);

                }
            }
        }

        return fieldMap;
    }


}

猜你喜欢

转载自blog.csdn.net/chunchunaiheliu/article/details/80613983