~留存笔记
场景:通过阿里云获取(例如:镜像)数据,默认会分每页展示20条(例如:共38个镜像信息,我们查询的时候,接口会告诉我们共有38条,当前页:1,当前页大小:20),也就是意味着返回给我们的数据都是第一页的20条数据而后的18条数据没有直接给我们,如果我们想要将每页的数据都拼装后返回前台,就需要在后台手动进行拼装数据。但是相似的需要拼装数据接口有很多,所以就利用泛型、反射技术、递归算法实现了最终效果。
package cn.com.common.utils;
import com.aliyuncs.AcsRequest;
import com.aliyuncs.IAcsClient;
import java.lang.reflect.Method;
import java.util.List;
/**
* @Author: lijian
* @Date: 2019/3/25 18:28
* 用于某云分页数据合并处理
*/
public class PagesUtil {
/**
* 计算页数(向上取整)= 总数 / 每页数量
* @param totalCount 总数
* @param pageSize 每页数量
* @return 总页数
*/
public static int countPages(int totalCount, int pageSize) {
String s = String.valueOf(Math.ceil((float) totalCount / pageSize));
return Integer.parseInt(s.substring(0, s.length() - 2));
}
/**
* 递归调用,实现每页数据拼装
* @param iAcsClient 认证对象
* @param list 已经存放了第一页数据的List对象
* @param current 当前页数
* @param total 总页数
* @param request 调用某云接口的request对象
* @param requestClass 调用某云接口的request对象类型
* @param responseClass 调用某云接口的响应对象类型
* @param dataProperty 调用某云接口的响应对象里用于存放数据的属性
* @param <T>
* @return 总数据
* @throws Exception
*/
public static <T> List<T> recursion(IAcsClient iAcsClient, List<T> list,
int current, int total,
Object request, Class requestClass, Class responseClass,
String dataProperty) throws Exception{
//1.判断request类型是否一致
if(requestClass.isInstance(request)){
if (current > total) {
//2.当前页数大于总页数时,直接返回
return list;
} else {
//3.获取request的setPageNumber方法,为其赋值为current
reflectMethod(request,requestClass,"pageNumber",true,Integer.class).invoke(request,current);
//4.调用阿里云接口获取当前PageNumber的数据
T acsResponse = (T) iAcsClient.getAcsResponse((AcsRequest)request);
//5.获取接口返回值的数据添加到list
list.addAll((List)reflectMethod(acsResponse, responseClass, dataProperty, false,null).invoke(acsResponse));
//8.递归调用
return recursion(iAcsClient, list, ++current, total,request,requestClass,responseClass,dataProperty);
}
}else{
throw new RuntimeException("请求分页数据合并处理时请传入正确的对象类型参数!");
}
}
/**
*
* @param o 对象
* @param oClass 对象类型
* @param fieldName 属性名
* @param setOrNot 是否为set方法
* @param clz 反射获取的方法参数类型
* @param <T>
* @return
* @throws ClassNotFoundException
* @throws NoSuchMethodException
*/
private static <T> Method reflectMethod(Object o, Class<T> oClass,String fieldName,boolean setOrNot,Class clz) throws ClassNotFoundException, NoSuchMethodException {
if(setOrNot){
//通过反射获取指定方法
return reflect(o, oClass).getMethod("set"+upperFirst(fieldName),clz);
}else{
//通过反射获取指定方法
return reflect(o, oClass).getMethod("get"+upperFirst(fieldName));
}
}
/**
* 反射获取对象信息
* @param o 请求对象
* @param oClass 对象类型
* @param <T>
* @return
* @throws ClassNotFoundException
*/
private static <T> Class reflect(Object o, Class<T> oClass) throws ClassNotFoundException {
//将request转换为requestClass类型,并通过反射加载类数据
T cast = oClass.cast(o);
String typeName = cast.getClass().getTypeName();
return Class.forName(typeName);
}
/**
* 将字符串首字符大写
* @param name
* @return
*/
private static String upperFirst(String name){
return name.substring(0, 1).toUpperCase() + name.substring(1);
}
}