衔接上文《Spring Boot项目使用JAVA反射获取Controller接口列表》,在获取了本地接口的列表后,还需要进行接口调用。同样是利用JAVA反射机制。
整体思路
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; }
调用测试:
发表评论