衔接上文《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;
}调用测试:



发表评论