All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.yanyun.go.utils.MethodUtils Maven / Gradle / Ivy

There is a newer version: 1.0.6
Show newest version
package com.yanyun.go.utils;

import com.google.common.base.Optional;
import org.springframework.http.HttpMethod;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestBody;
import springfox.documentation.service.Parameter;
import springfox.documentation.service.ResolvedMethodParameter;
import springfox.documentation.spi.service.contexts.OperationContext;

import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Arrays;
import java.util.List;
import java.util.Stack;
import java.util.stream.Collectors;

/**
 * 根据请求方法返回请求方式的工具类
 */
public class MethodUtils {

    public static String getMethodApi(OperationContext context) {
        //获取请求的类型
        String methodType = context.httpMethod().name();
        //获取请求地址
        String requestMappingPattern = context.requestMappingPattern();
        //获取请求参数列表
        List parameters = context.getParameters();
        //如果是Get请求
        if (HttpMethod.GET.matches(methodType)) {
            return dealGetAndDeleteMethod(requestMappingPattern, parameters, "Get");
        }
        //如果是Delete请求
        if (HttpMethod.DELETE.matches(methodType)) {
            return dealGetAndDeleteMethod(requestMappingPattern, parameters, "Delete");
        }
        //如果是Post请求
        if (HttpMethod.POST.matches(methodType)) {

            return dealPostAndPutMethod(context, "Post");
        }
        //如果是Put请求
        if (HttpMethod.PUT.matches(methodType)) {
            return dealPostAndPutMethod(context, "Put");
        }
        return "该[" + methodType + "]请求方式暂未收录,请自行编写Go测试";
    }

    /**
     * 处理TypeB类型的URI
     * 将原来类型 /{a}/{b}类型 转化为   /A/B
     *
     * @param typeB
     * @return
     */
    private static String dealTypeBURI(String typeB) {
        //压栈
        Stack firstStack = new Stack<>();

        StringBuffer result = new StringBuffer();

        for (int i = 0; i < typeB.length(); i++) {
            String singleStr = typeB.substring(i, i + 1);
            if (singleStr.equals("}")) {
                //弹栈
                StringBuffer temp = new StringBuffer();
                boolean flag = true;
                while (flag) {
                    String pop = firstStack.pop();
                    if (!pop.equals("{")) {
                        temp.append(pop);
                    } else {
                        flag = false;
                    }
                }
                //弹出的数据
                String upperCase = temp.reverse().toString().toUpperCase();
                for (int j = 0; j 0; i--) {
            result.append(firstStack.pop());
        }
        return result.reverse().toString();
    }



    /**
     * 处理Get或者Delete的返回
     *
     * @param requestMappingPattern 如果是GET,进行匹配Get的请求:目前分为 A    B  两种方式:
     *                              A 为 ?xx=xx&xxx=xxx
     *                              B 为 /a/b/c
     * @return
     */
    private static String dealGetAndDeleteMethod(String requestMappingPattern, List parameters, String methodType) {
        int size = parameters.size();
        if (size == 0) {
            //如果没有参数,那么默认使用A方式
            return methodType + "A(\"" + requestMappingPattern + "\",\"\")";
        } else {
            //否则需要传递参数
            //传递参数
            if (requestMappingPattern.contains("{")) {
                //如果是path参数,直接返回B的方式
                return methodType + "B(\"" + dealTypeBURI(requestMappingPattern) + "\",\"\")";
            } else {
                //否则不是,需要返回A的方式
                StringBuffer suffix = new StringBuffer();
                parameters.forEach(p -> {
                    suffix.append("&" + p.defaultName().get() + "=");
                });
                //进行处理
                suffix.delete(0, 1);
                return methodType + "A(\"" + requestMappingPattern + "\",\"?" + suffix.toString() + "\")";
            }
        }
    }


    /**
     * 处理Post或者Put请求
     * 目前请求分为3类    A   B   C
     * A: 为 ?xx=xxx
     * B: 为 /a/b/c
     * C: 为 请求体中传递JSON数据
     *
     * @return
     */
    private static String dealPostAndPutMethod(OperationContext context, String methodType) {
        //获取参数集合
        List parameters = context.getParameters();
        //获取请求路径
        String requestMappingPattern = context.requestMappingPattern();
        int size = parameters.size();
        if (size == 0) {
            //如果没有参数,那么默认使用A方式
            return methodType + "A(\"" + requestMappingPattern + "\",\"\")";
        } else {
            //如果有参数,那么需要判断参数类型
            if (requestMappingPattern.contains("{")) {
                //如果是path参数,直接返回B的方式
                return methodType + "B(\"" + dealTypeBURI(requestMappingPattern) + "\",\"\")";
            } else {
                //判断参数 是否包含注解 @RequestBody,如果没有则使用A方式,如果有则使用C方式
                boolean flag = false;
                for (int i = 0; i < parameters.size(); i++) {
                    Optional annotation = parameters.get(i).findAnnotation(RequestBody.class);
                    if (annotation.isPresent()) {
                        //如果存在该注解,那么证明传递的是JSON数据
                        flag = true;
                    }
                }
                if (!flag) {
                    //如果是普通?传参
                    StringBuffer pathParams = new StringBuffer();
                    context.operationBuilder().build().getParameters().forEach(p -> {
                        if (!"header".equalsIgnoreCase(p.getParamType())) {
                            //排除头参数
                            pathParams.append("&" + p.getName() + "=");
                        }
                    });
                    pathParams.delete(0, 1);
                    return methodType + "A(\"" + requestMappingPattern + "\",\"?" + pathParams.toString() + "\")";
                } else {
                    //否则为PostC的方式进行调用,并且目前只分析参数列表中只有一种 requestBody的测试
                    List params = context.operationBuilder().build().getParameters();
                    List paramList = params.stream().filter(p -> !"header".equalsIgnoreCase(p.getParamType())).collect(Collectors.toList());
                    //接收参数 @requestBody 只有一个
                    Parameter param = paramList.get(0);
                    //最终封装的结果
                    StringBuffer result = new StringBuffer();
                    //获得头
                    result.append(toCamelName(param.getName()) + "{ \n");
                    //增加中间请求体
                    StringBuffer paramBody = converterParamToBody(param);
                    result.append(paramBody);
                    //封装尾部
                    result.append("}");
                    return methodType + "C(\"" + requestMappingPattern + "\"," + result.toString() + ")";

                }
            }
        }
    }

    /**
     * 将参数列表转换为Body类型
     *
     * @param parameter
     * @return
     */
    private static StringBuffer converterParamToBody(Parameter parameter) {
        StringBuffer params = new StringBuffer();
        //得到实体类型
        String paramType = parameter.getType().get().getTypeName();
        //反射实体
        try {
            Class rootClass = Class.forName(paramType);
            //得到声明的字段
            Field[] declaredFields = rootClass.getDeclaredFields();
            //循环遍历字段
            Arrays.asList(declaredFields).forEach(field -> {
                //递归调用拼接字符串到params中
                recursionParams(field, params, paramType);
            });
        } catch (ClassNotFoundException e) {
          //  e.printStackTrace();
        }
        if (!StringUtils.isEmpty(params.toString())) {
            //去掉最后一个逗号
            params.deleteCharAt(params.lastIndexOf(","));
        }
        return params;
    }

    /**
     * 递归字段,将数据回写到params中
     *
     * @param field
     * @param params
     */
    private static void recursionParams(Field field, StringBuffer params, String paramType) {
        //获取字段类型
        Class type = field.getType();
        //获取字段的简单类名
        String simpleName = type.getSimpleName();
        //获取全类名
        String typeName = type.getName();
        //1.基本类型
        if (isSimpleType(simpleName)) {
            //如果是简单类型
            params.append("\n" + toCamelName(field.getName()) + " : " + JavaTypeToGoType(simpleName) + ",");
            return;
        }
        //2.数组类型
        if (isArrayType(typeName)) {
            //a、数组中放置的是简单类型
            if (isSimpleArrayType(simpleName)) {
                //直接拼接
                String goType = JavaTypeToGoType(simpleName.substring(0, simpleName.lastIndexOf("[")));
                params.append("\n" + toCamelName(field.getName()) + " : []" + goType + "{" + goType + "},");
                return;
            } else {
                //b、不是简单类型数组,按照是DTO的数组进行分析
                //进行再次反射
                try {
                    if (!typeName.equalsIgnoreCase(paramType)) {
                        Class aClass = Class.forName(typeName);
                        StringBuffer fieldParams = new StringBuffer();
                        Arrays.asList(aClass.getDeclaredFields()).forEach(f -> {
                            recursionParams(f, fieldParams, f.getType().getName());
                        });
                        params.append("\n" + toCamelName(field.getName()) + " : []" + simpleName.substring(0, simpleName.indexOf("[")) + "{" + fieldParams + "},");
                        return;
                    }
                    params.append("\n" + toCamelName(field.getName()) + " : []" + simpleName.substring(0, simpleName.indexOf("[")) + "{" + simpleName.substring(0, simpleName.indexOf("[")) + "},");
                    return;
                    //不能去掉数组种最后一个逗号
                    // fieldParams.deleteCharAt(fieldParams.lastIndexOf(","));

                    // String goType = JavaTypeToGoType(simpleName.substring(0, simpleName.lastIndexOf("[")));

                } catch (ClassNotFoundException e) {
                    e.printStackTrace();
                }
            }
        }
        //3.普通List、Set集合类型
        if (isCollectionType(typeName)) {
            //获取集合中的泛型
            Type genericType = field.getGenericType();
            if (genericType != null && genericType instanceof ParameterizedType) {
                //如果有泛型,那么按照泛型进行分析
                ParameterizedType pType = (ParameterizedType) genericType;
                Type[] actualTypeArguments = pType.getActualTypeArguments();
                if (actualTypeArguments != null && actualTypeArguments.length > 0) {
                    //取第一个泛型类
                    Type actualTypeArgument = actualTypeArguments[0];
                    //获取类型
                    String argumentType = actualTypeArgument.getTypeName();
                    if (argumentType.contains("java.util") && (argumentType.contains("List") || argumentType.contains("Set"))) {
                        //如果泛型中依旧包含集合,此处只允许二级集合
                        String substring = argumentType.substring(argumentType.indexOf("<") + 1);
                        String truthStr = substring.substring(0, substring.indexOf(">"));
                        String truthSimpleName = truthStr.substring(truthStr.lastIndexOf(".") + 1);
                        if (isSimpleType(truthSimpleName)) {
                            String goType = JavaTypeToGoType(truthSimpleName);
                            params.append("\n" + toCamelName(field.getName()) + " : [][]" + goType + "{[" + goType + "]},");
                        } else {
                            try {
                                Class aClass = Class.forName(truthStr);
                                if (truthStr.equalsIgnoreCase(paramType)) {
                                    //如果是本身的类型
                                    params.append("\n" + toCamelName(field.getName()) + " : [][]" + truthSimpleName + "{[" + truthSimpleName + "]},");
                                } else {
                                    StringBuffer fieldParams = new StringBuffer();
                                    Arrays.asList(aClass.getDeclaredFields()).forEach(f -> {
                                        recursionParams(f, fieldParams, f.getType().getName());
                                    });
                                    params.append("\n" + toCamelName(field.getName()) + " : [][]" + truthSimpleName + "{[" + truthSimpleName + "]},");
                                }

                            } catch (ClassNotFoundException e) {
                                e.printStackTrace();
                                //出现异常的话,将swagger长类型写上去
                                params.append("\n" + toCamelName(field.getName()) + " : [][]" + argumentType + "{[" + argumentType + "]},");
                            }
                        }
                        return;
                    }
                    Class aClass = (Class) actualTypeArgument;
                    if (isSimpleType(aClass.getSimpleName())) {
                        //如果是普通类型
                        String goType = JavaTypeToGoType(aClass.getSimpleName());
                        params.append("\n" + toCamelName(field.getName()) + " : []" + goType + "{" + goType + "},");
                        return;
                    }
                    if (aClass.getName().equalsIgnoreCase(paramType)) {
                        //如果是本身的类型
                        params.append("\n" + toCamelName(field.getName()) + " : []" + aClass.getSimpleName() + "{[" + aClass.getSimpleName() + "]},");
                        return;
                    }
                    //泛型承载的参数
                    StringBuffer fieldParams = new StringBuffer();
                    Arrays.asList(aClass.getDeclaredFields()).forEach(f -> {
                        recursionParams(f, fieldParams, f.getType().getName());
                    });
                    //不能去掉最后一个逗号
                    //fieldParams.deleteCharAt(fieldParams.lastIndexOf(","));

                    String simplePName = aClass.getSimpleName();
                    String goType = JavaTypeToGoType(simplePName);
                    if ("unknown".equalsIgnoreCase(goType)) {
                        goType = simplePName;
                    }
                    params.append("\n" + toCamelName(field.getName()) + " : []" + goType + "{" + fieldParams + "},");
                    return;
                }
            } else {
                //如果没有泛型,按照Object类型进行分析
                params.append("\n" + toCamelName(field.getName()) + " : []interface{},");
                return;
            }
        }
        //4.Map类型
        if (isMapCollection(typeName)) {
            //获取泛型
            Type genericType = field.getGenericType();
            if (genericType != null && genericType instanceof ParameterizedType) {
                //如果有泛型,那么按照泛型进行分析
                ParameterizedType pType = (ParameterizedType) genericType;
                Type[] actualTypeArguments = pType.getActualTypeArguments();
                if (actualTypeArguments != null && actualTypeArguments.length > 0) {
                    //Map一般有2种泛型
                    //取第一个泛型类,并进行转换
                    Class aClass = (Class) actualTypeArguments[0];
                    String aName = JavaTypeToGoType(aClass.getSimpleName());
                    if ("unknown".equalsIgnoreCase(aName)) {
                        aName = aClass.getSimpleName();
                    }
                    //第二个泛型
                    Class bClass = (Class) actualTypeArguments[1];
                    String bName = JavaTypeToGoType(bClass.getSimpleName());
                    if ("unknown".equalsIgnoreCase(bName)) {
                        bName = bClass.getSimpleName();
                    }
                    //参数拼接
                    params.append("\n" + toCamelName(field.getName()) + " : map[" + aName + "]" + bName + "{},");
                    return;
                }
            }
        }
        //5、自定义DTO类型
        try {
            Class aClass = Class.forName(typeName);
            if (aClass.equals(Object.class)) {
                //如果是Object,拼接
                params.append("\n" + toCamelName(field.getName()) + " : interface{},");
                return;
            } else {
                if (aClass.getName().equalsIgnoreCase(paramType)) {
                    //如果是本身的类型
                    params.append("\n" + toCamelName(field.getName()) + " : []" + aClass.getSimpleName() + "{" + aClass.getSimpleName() + "},");
                    return;
                }
                StringBuffer fieldParams = new StringBuffer();
                Arrays.asList(aClass.getDeclaredFields()).forEach(f -> {
                    recursionParams(f, fieldParams, f.getType().getName());
                });
                //不能去掉最后一个逗号
                // fieldParams.deleteCharAt(fieldParams.lastIndexOf(","));
                params.append("\n" + toCamelName(field.getName()) + " : {" + fieldParams + "},");
                return;
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

    }


    /**
     * 将传递的字符串进行首字母大写
     *
     * @param originName
     * @return
     */
    private static String toCamelName(String originName) {
        if (!StringUtils.isEmpty(originName)) {
            String upperCase = originName.substring(0, 1).toUpperCase();
            originName = upperCase + originName.substring(1);
        }
        return originName;
    }

    /**
     * 判断类型 是否为普通类型
     *
     * @return
     */
    public static boolean isSimpleType(String typeName) {
        boolean flag = false;
        if (typeName.equalsIgnoreCase("int")
                || typeName.equalsIgnoreCase("Integer")
                || typeName.equalsIgnoreCase("byte")
                || typeName.equalsIgnoreCase("Byte")
                || typeName.equalsIgnoreCase("long")
                || typeName.equalsIgnoreCase("Long")
                || typeName.equalsIgnoreCase("double")
                || typeName.equalsIgnoreCase("Double")
                || typeName.equalsIgnoreCase("float")
                || typeName.equalsIgnoreCase("Float")
                || typeName.equalsIgnoreCase("char")
                || typeName.equalsIgnoreCase("Character")
                || typeName.equalsIgnoreCase("short")
                || typeName.equalsIgnoreCase("Short")
                || typeName.equalsIgnoreCase("boolean")
                || typeName.equalsIgnoreCase("Boolean")
                || typeName.equalsIgnoreCase("String") //增加String类型
                || typeName.equalsIgnoreCase("Date")
        ) {
            //如果是基本类型,那么返回true
            flag = true;
        }
        return flag;
    }

    /**
     * 判断是否是数组
     *
     * @param typeName
     * @return
     */
    public static boolean isArrayType(String typeName) {
        boolean flag = false;
        if (typeName.contains("[")) {
            //如果包含数组括号,那么认定为数组
            flag = true;
        }
        return flag;
    }

    /**
     * 判断是否为普通数组类型
     *
     * @param typeName
     * @return
     */
    public static boolean isSimpleArrayType(String typeName) {
        boolean flag = false;
        if (typeName.equalsIgnoreCase("int[]")
                || typeName.equalsIgnoreCase("Integer[]")
                || typeName.equalsIgnoreCase("byte[]")
                || typeName.equalsIgnoreCase("Byte[]")
                || typeName.equalsIgnoreCase("long[]")
                || typeName.equalsIgnoreCase("Long[]")
                || typeName.equalsIgnoreCase("double[]")
                || typeName.equalsIgnoreCase("Double[]")
                || typeName.equalsIgnoreCase("float[]")
                || typeName.equalsIgnoreCase("Float[]")
                || typeName.equalsIgnoreCase("char[]")
                || typeName.equalsIgnoreCase("Character[]")
                || typeName.equalsIgnoreCase("short[]")
                || typeName.equalsIgnoreCase("Short[]")
                || typeName.equalsIgnoreCase("boolean[]")
                || typeName.equalsIgnoreCase("Boolean[]")
                || typeName.equalsIgnoreCase("String[]") //增加String类型
        ) {
            //如果是基本类型,那么返回true
            flag = true;
        }
        return flag;
    }


    /**
     * 判断是否是为普通集合类型
     *
     * @param typeName
     * @return
     */
    public static boolean isCollectionType(String typeName) {
        boolean flag = false;
        //判断是否是 java.util包下,名称中是否包含List、Set关键字
        if (typeName.contains("java.util")) {
            if (typeName.contains("Set") || typeName.contains("List")) {
                flag = true;
            }
        }
        return flag;
    }

    /**
     * 判断是否为普通 Map
     *
     * @param typeName
     * @return
     */
    public static boolean isMapCollection(String typeName) {
        boolean flag = false;
        //判断是否是 java.util包下,名称中是否包含List、Set关键字
        if (typeName.contains("java.util")) {
            if (typeName.contains("Map")) {
                flag = true;
            }
        }
        return flag;
    }

    /**
     * 普通Java类型转换为Go的普通类型
     *
     * @param javaType
     * @return
     */
    public static String JavaTypeToGoType(String javaType) {
        //int类型转换
        if ("int".equalsIgnoreCase(javaType) || "Integer".equalsIgnoreCase(javaType)) {
            return "int32";
        }
        if ("byte".equalsIgnoreCase(javaType) || "Byte".equalsIgnoreCase(javaType)) {
            return "int8";
        }
        if ("short".equalsIgnoreCase(javaType) || "Short".equalsIgnoreCase(javaType)) {
            return "int16";
        }
        if ("long".equalsIgnoreCase(javaType) || "Long".equalsIgnoreCase(javaType)) {
            return "int64";
        }
        if ("char".equalsIgnoreCase(javaType) || "Character".equalsIgnoreCase(javaType)) {
            return "uint16";
        }
        if ("float".equalsIgnoreCase(javaType) || "Float".equalsIgnoreCase(javaType)) {
            return "float32";
        }
        if ("double".equalsIgnoreCase(javaType) || "Double".equalsIgnoreCase(javaType)) {
            return "float64";
        }
        if ("boolean".equalsIgnoreCase(javaType) || "Boolean".equalsIgnoreCase(javaType)) {
            return "bool";
        }

        if ("String".equalsIgnoreCase(javaType)) {
            return "string";
        }
        if ("Date".equals(javaType)){
            //日期返回时间格式
            return "time.Time";
        }
        if ("BigDecimal".equalsIgnoreCase(javaType)) {
            return "string";
        }
        //其他情况,未知
        return "unknown";
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy