Java反射实现阿里云分页数据合并处理

~留存笔记

场景:通过阿里云获取(例如:镜像)数据,默认会分每页展示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);
    }
}

猜你喜欢

转载自blog.csdn.net/Peacock__/article/details/88824039