场景
在一次自测接口的时候,因为一个入参是json格式字符串,其实就是为了实现通用。但是怎么去得到一个或多个对象的json格式的序列化字符串呢?要么直接写个Test去手动添加再转,多个就遍历一下,但每次写都很烦,网上没找到合适的就自己写了个小demo,可以按需修改一下,因为也只是自测用就没多友好了。
代码
public class ObjectGenerator {
public static List generator(Class<?> clazz, int start, int size) throws InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException {
return generator(clazz, start, size, false, 0);
}
public static List generator(Class<?> clazz, int size, boolean useSuper, int superLevel) throws InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException {
return generator(clazz, 0, size, useSuper, superLevel);
}
/**
* 生成测试对象集合
* @param clazz 类对象
* @param start 开始下标
* @param size 集合大小
* @param useSuper 是否使用父类字段
* @param superLevel 父类层级
* @return list
* @throws NoSuchMethodException
* @throws IllegalAccessException
* @throws InvocationTargetException
* @throws InstantiationException
*/
public static List generator(Class<?> clazz, int start, int size, boolean useSuper, int superLevel) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
if (size==0){
return null;
}
List list = new ArrayList(size);
//两个Set集合保存字段和set方法
Set<Field> fields = new LinkedHashSet<>();
Set<Method> methods = new LinkedHashSet<>();
//取当前类对象的构造器、字段和方法
Constructor<?> constructor = clazz.getConstructor();
Field[] declaredFields = clazz.getDeclaredFields();
fields.addAll(Arrays.asList(declaredFields));
Method[] declaredMethods = clazz.getDeclaredMethods();
methods.addAll(Stream.of(declaredMethods).filter(item -> item.getName().startsWith("set")).collect(Collectors.toSet()));
//判断是否取父类的字段信息以及向上取几级(superLevel)
if (useSuper && superLevel>0){
Class current = clazz;
for (int i=0; i<superLevel; i++){
Class<?> superclass = current.getSuperclass();
Field[] superDeclaredFields = superclass.getDeclaredFields();
fields.addAll(Arrays.asList(superDeclaredFields));
Method[] superDeclaredMethods = superclass.getDeclaredMethods();
methods.addAll(Stream.of(superDeclaredMethods).filter(item -> item.getName().startsWith("set")).collect(Collectors.toSet()));
current = superclass;
}
}
int length = size + start;
//遍历生成对象
for (int i=start; i<length; i++){
Object obj = constructor.newInstance();
//对每个字段进行赋值
for (Field field : fields){
Object fieldVal = null;
String fieldName = field.getName().toLowerCase();
//根据字段类型赋予默认值
Class<?> type = field.getType();
if (type == Integer.class || type == int.class ){
fieldVal = i;
}
if (type == Long.class || type == long.class ){
fieldVal = i;
}
if (type == String.class){
fieldVal = fieldName+i;
}
if (type == Date.class){
fieldVal = new Date();
}
//这里可以针对添加更多类对象的默认值
//也可以针对一些字典项进行默认
Method method = methods.stream().filter(item -> item.getName().toLowerCase().endsWith(fieldName)).findFirst().orElse(null);
//拿到set方法进行赋值
if (method != null){
try {
method.invoke(obj, fieldVal);
}catch (Exception e){
System.out.println(fieldName);
}
}
}
list.add(obj);
}
return list;
}
@Test
public void test(){
try {
List generator = generator(TFwdjxxb.class, 20, true, 1);
System.out.println(JSONObject.toJSONString(generator));
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
}
}
}
结束
很潦草哈,凑合用吧…