Spring Boot项目使用JAVA反射调用Controller接口

原创  郑建华   2020-12-26   249人阅读  0 条评论

    衔接上文《Spring Boot项目使用JAVA反射获取Controller接口列表》,在获取了本地接口的列表后,还需要进行接口调用。同样是利用JAVA反射机制。

image.png

    整体思路

    1、根据获取的接口列表的接口对象,设置参数后,将其作为本地测试接口的入参,使用分页对象作为返回结果对象。

    2、解析入参对象,获取请求接口的名称和入参,匹配当前需要执行的方法。

    3、判断入参类型是基本类型还是实体类型。

    4、根据类型转换参数值(分为基本类型的转换和实体类型的转换)

    5、根据spring工具类获取bean并执行方法

    6、解析结果对象,转换类型获取数据

    7、判断数据是集合还是实体

    8、将集合或实体转换成Map对象并添加到返回集合中

    9、进行分页处理

    10、设置到分页对象中并返回结果

    说明:

    1、method.invoke方法第一个参数为类的实例,这里是Controller直接使用newInstance()是无法执行方法的,因为其中依赖的bean没有被注入进去,需要使用Spring获取bean才能够执行。

    2、method.invoke方法的第二个参数为相应函数中的参数,这里的参数类型必须一一匹配,也就是说入参是Integer类型,就必须设置Integer类型,可以使用Object来接收,所以编写了一个转换类型的方法(有点挫,基本类型对象不能通过newInstance方法创建,因为没有无参构造方法),该转换方法仅支持部分常用的类型转换。

    3、需要执行的method方法可能有多个入参,可以使用Object[]数组来传参,只要每个位置的类型对应上即可。

    4、需要执行的method方法的入参是实体对象,则可以使用实体对象的newInstance方法创建对象,再使用field的set方法设置值即可。

@ApiOperation(value = "调用本地接口", notes = "调用本地接口")
@PostMapping("/execLocalInterfaceByDTO")
public R<Page<Map<String,Object>>> execLocalInterfaceByDTO(@RequestBody LocalInterfaceDTO localInterfaceDTO) throws URISyntaxException {
    try {
        Integer current = localInterfaceDTO.getCurrent();
        Integer size = localInterfaceDTO.getSize();
        Page<Map<String,Object>> page = getPage(current,size);
        // 解析本地接口Controller类
        Class classType=Class.forName(DataSetLocalInterfaceController.class.getName());
        // 调用接口执行
        page=sysDataSetService.execLocalInterfaceByDTO(classType,localInterfaceDTO,page);
        return success(page);
    }catch (BizException e){
        log.error("[SysDataSetInterfaceController.execLocalInterfaceByDTO()] Code exception. exception[{}-{}]" ,new Object[]{e.getMessage(), Arrays.deepToString(e.getStackTrace())});
        return fail(e.getMessage());
    }catch (Exception e){
        log.error("[SysDataSetInterfaceController.execLocalInterfaceByDTO()] Code exception. exception[{}-{}]" ,new Object[]{e.getMessage(), Arrays.deepToString(e.getStackTrace())});
        return fail("调用本地接口失败,联系系统管理员处理!");
    }
}
@Override
public Page<Map<String,Object>> execLocalInterfaceByDTO(Class classType, LocalInterfaceDTO localInterfaceDTO,Page<Map<String,Object>> page) throws IllegalAccessException, InstantiationException, InvocationTargetException {

    // 创建返回数据List
    List<Map<String, Object>> result = new ArrayList<Map<String,Object>>();

    // 创建返回对象
    Object returnObject=new Object();

    // 获取接口编码
    String interfaceCode=localInterfaceDTO.getInterfaceCode();

    // 响应参数是否是集合
    Boolean responseIsList=localInterfaceDTO.getResponseIsList();

    // 请求参数是否是实体
    Boolean requestIsEntity = localInterfaceDTO.getRequestIsEntity();
    // 类对象
    Object classObj= SpringUtils.getBean("dataSetLocalInterfaceController");
    // 获取请求参数列表
    List<InterfaceParamDTO> requestParamList=localInterfaceDTO.getRequestParam();

    // 根据参数编码生成map
    Map<String,InterfaceParamDTO> interfaceParamDTOMap=Optional.ofNullable(requestParamList).orElse(new ArrayList<InterfaceParamDTO>())
            .stream().collect(Collectors.toMap(InterfaceParamDTO::getParamCode, Function.identity(),(o1,o2)->o1));

    // 获取全部方法
    Method[] methods=classType.getDeclaredMethods();
    // 当前接口
    Method curMethod=null;
    // 匹配当前接口
    if(methods!=null && methods.length>0){
        for(int i=0;i<methods.length;i++){
            if(interfaceCode.equals(methods[i].getName())){
                curMethod = methods[i];
            }
        }
    }
    // 当前接口匹配成功
    if(curMethod!=null){
        // 获取参数列表
        Parameter[] parameters=curMethod.getParameters();
        // 参数对象数据
        Object[] paramObject=new Object[parameters.length];
        // 实体参数对象
        Object singleObject = new Object();
        if(parameters!=null && parameters.length>0){
            for(int j=0;j<parameters.length;j++){
                // 参数
                Parameter parameter = parameters[j];
                // 类型名称
                String typeName=parameter.getType().getName();
                // 参数编码
                String paramCode = parameter.getName();

                // 如果当前属于基本类型
                if(ArrayUtils.contains(baseTypes,typeName)){
                    // 创建对象
                    Object curParamObj=new Object();
                    // 根据参数编码获取值
                    InterfaceParamDTO interfaceParamDTO=interfaceParamDTOMap.get(paramCode);
                    // 不为空
                    if(interfaceParamDTO!=null){
                        // 添加值到集合
                        paramObject[j]=castValueByType(typeName,interfaceParamDTO.getParamValue(),"");
                    }
                }else{
                    // 创建对象
                    Object curParamObj=parameter.getType().newInstance();
                    // 获取全部的字段
                    Field[] fields=curParamObj.getClass().getDeclaredFields();
                    if(fields!=null && fields.length>0){
                        for(int m=0;m<fields.length;m++){
                            // 获取字段
                            Field fields1=fields[m];
                            // 获取字段名称
                            String fileCode = fields1.getName();
                            // 获取字段类型名称
                            String filedType = fields1.getType().getName();
                            // 格式化字符串
                            String format="";
                            // 判断字段存在注解
                            if(fields1.isAnnotationPresent(JsonFormat.class)){
                                // 获取注解
                                JsonFormat jsonFormatAnnotation=fields1.getAnnotation(JsonFormat.class);
                                // 判断不为空
                                if(jsonFormatAnnotation!=null){
                                    // 获取注解值
                                    format = jsonFormatAnnotation.pattern();
                                }
                            }

                            // 根据字段名称获取值
                            InterfaceParamDTO interfaceParamDTO=interfaceParamDTOMap.get(fileCode);
                            // 不为空
                            if(interfaceParamDTO!=null){
                                // 设置值
                                String tempValue = interfaceParamDTO.getParamValue();
                                fields1.setAccessible(true);
                                // 转换类型
                                fields1.set(curParamObj,castValueByType(filedType,tempValue,format));
                            }
                        }
                    }
                    singleObject = curParamObj;
                }
            }
        }
        // 一个实体参数
        if(requestIsEntity!=null && requestIsEntity){
            returnObject = curMethod.invoke(classObj,singleObject);
             // 参数列表
        }else{
            returnObject =  curMethod.invoke(classObj,paramObject);
        }

        // 判断是R类型
        if(returnObject !=null && returnObject instanceof R){
            // 获取Data
            returnObject = ((R) returnObject).getData();
            // 响应参数是集合类型
            if(responseIsList!=null && responseIsList){
                // 判断类型
                if(returnObject instanceof List){
                    // 强制类型转换
                    List<Object> objectList = (List<Object>)returnObject;
                    // 判断不为空
                    if(CollectionUtils.isNotEmpty(objectList)){
                        for(Object object:objectList){
                            // 转换map对象
                            Map<String,Object> map=objectToMap(object);
                            // 添加到result中
                            result.add(map);
                        }
                    }
                }
                // 响应参数是对象
            }else{
                // 转换map对象
                Map<String,Object> map=objectToMap(returnObject);
                // 添加到result中
                result.add(map);
            }
            int total = result.size();
            page.setTotal(result.size());
            Integer current=localInterfaceDTO.getCurrent();
            Integer size=localInterfaceDTO.getSize();
            // 截取分页
            if(current*size > total){
                List<Map<String, Object>> maps = result.subList(current * size - size, result.size());
                page.setRecords(maps);
            }else{
                List<Map<String, Object>> maps = result.subList(current * size - size, current * size);
                page.setRecords(maps);
            }
            // 返回分页对象
            return page;
        }else{
            throw new BizException("接口执行失败");
        }
    }else{
       throw new BizException("未找到匹配方法");
    }
}
/**
 * 根据类型转换值
 * @param type 类型值
 * @param string 转换值
 * @param format 转换格式
 * @return
 */
public Object castValueByType(String type,String string,String format){
    if("java.lang.String".equals(type)){
        return new String(StringUtils.isEmpty(string)?"0":string);
    }else if("java.lang.Integer".equals(type)){
        return new Integer(Integer.parseInt(StringUtils.isEmpty(string)?"0":string));
    }else if("java.lang.Double".equals(type)){
        return new Double(Double.parseDouble(StringUtils.isEmpty(string)?"0":string));
    }else if("java.lang.Float".equals(type)){
        return new Float(Float.parseFloat(StringUtils.isEmpty(string)?"0":string));
    }else if("java.lang.Long".equals(type)){
        return new Long(Long.parseLong(StringUtils.isEmpty(string)?"0":string));
    }else if("java.lang.Short".equals(type)){
        return new Short(Short.parseShort(StringUtils.isEmpty(string)?"0":string));
    }else if("java.lang.Byte".equals(type)){
        return new Byte(Byte.parseByte(StringUtils.isEmpty(string)?"0":string));
    }else if("java.lang.Boolean".equals(type)){
        return new Boolean(Boolean.parseBoolean(StringUtils.isEmpty(string)?"0":string));
    }else if("java.lang.Character".equals(type)) {
        return new Character((StringUtils.isEmpty(string) ? " " : string).charAt(0));
    }else if("java.math.BigDecimal".equals(type)){
        return new BigDecimal(StringUtils.isEmpty(string)?"0":string);
    }else if("int".equals(type)){
        return Integer.parseInt(StringUtils.isEmpty(string)?"0":string);
    }else if("double".equals(type)){
        return Double.parseDouble(StringUtils.isEmpty(string)?"0":string);
    }else if("float".equals(type)){
        return Float.parseFloat(StringUtils.isEmpty(string)?"0":string);
    }else if("long".equals(type)){
        return Long.parseLong(StringUtils.isEmpty(string)?"0":string);
    }else if("short".equals(type)){
        return Short.parseShort(StringUtils.isEmpty(string)?"0":string);
    }else if("byte".equals(type)){
        return Byte.parseByte(StringUtils.isEmpty(string)?"0":string);
    }else if("boolean".equals(type)){
        return Boolean.parseBoolean(StringUtils.isEmpty(string)?"0":string);
    }else if("char".equals(type)){
        return (StringUtils.isEmpty(string)?" ":string).charAt(0);
    }else if("java.time.localDate".equals(type)){
        return DateUtils.parseLocalDate(string,format);
    }else if("java.time.localDateTime".equals(type)){
        return DateUtils.parseToLocalDateTime(string,format);
    }else if("java.util.Date".equals(type)){
        return DateUtils.parse(string,format);
    }
    return null;
}
/**
 * 将Object对象里面的属性和值转化成Map对象
 *
 * @param obj
 * @return
 * @throws IllegalAccessException
 */
public Map<String, Object> objectToMap(Object obj) throws IllegalAccessException {
    Map<String, Object> map = new HashMap<String,Object>();
    Class<?> clazz = obj.getClass();
    for (Field field : clazz.getDeclaredFields()) {
        field.setAccessible(true);
        String fieldName = field.getName();
        Object value = StrHelper.getOrDef(field.get(obj),"");
        map.put(fieldName, value);
    }
    return map;
}

调用测试:

image.png

本文地址:https://www.zjh336.cn/?id=2017
版权声明:本文为原创文章,版权归 郑建华 所有,欢迎分享本文,转载请保留出处!

发表评论


表情

还没有留言,还不快点抢沙发?