背景:
由于项目需要生成doc文档,项目本身使用sdk 接口,有许多自定义注解,且需要生成特定格式在指定文档平台上传。目前已根据方法生成出入参表格markdown格式文档。json示例为新增
实现
基于fastjson,tojson 。 fastjson在tojson时实体,基本数据类型不存在值会默认为null。引用数据不存在值,无法递归打印完整json。
结果示例:
public class JsonTest {
@Test
public void test() {
Class<?> clazz = ServiceDemo.class;
for (Method method : clazz.getMethods()) {
System.out.println("方法名称:" + method.getName());
System.out.println("入参json:" + JsonUtil.getReqJson(method));
System.out.println("返回参数json:" + JsonUtil.getRespJson(method));
}
}
}
代码主要根据反射,为出入参为引用属性,时设置默认值。最后由fastjson 转为json字符串。
代码初稿
package cn.silence.utils;
import cn.hutool.core.util.ClassUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.TypeUtil;
import cn.hutool.json.JSONObject;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import sun.reflect.generics.reflectiveObjects.TypeVariableImpl;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.*;
public class JsonUtil {
public static String getReqJson(Method method) {
Type[] types = method.getGenericParameterTypes();
String json = "";
for (Type type : types) {
try {
String result = parseTypeToJson(type);
if (StrUtil.isNotBlank(json) && StrUtil.isNotBlank(result)) {
throw new RuntimeException("暂未处理多方法入参对象");
}
json = result;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
return json;
}
public static String getRespJson(Method method) {
try {
return parseTypeToJson(method.getGenericReturnType());
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* 设置泛型参数默认值
*
* @param type 类型
* @param cls cls
* @param o o
* @throws Exception 异常
*/
private static void setGenericDefault(Type type, Class<?> cls, Object o) throws Exception {
if (type instanceof ParameterizedType) {
Type actualTypeArgument = ((ParameterizedType) type).getActualTypeArguments()[0];
Class<?> aClass = TypeUtil.getClass(actualTypeArgument);
//基本数据类型,枚举属性
if (aClass.isPrimitive() || aClass.getName().startsWith("java.lang") || aClass.isEnum()) {
return;
}
//实例化泛型对象
Object obj1 = null;
if (Collection.class.isAssignableFrom(aClass)) {
obj1 = new ArrayList<>();
} else if (Map.class.isAssignableFrom(aClass)) {
obj1 = new HashMap<>();
} else {
obj1 = aClass.newInstance();
setFieldDefault(obj1);
}
//设置单列集合的值
if (Collection.class.isAssignableFrom(cls)) {
if (o instanceof List) {
((List<Object>) o).add(obj1);
}
} else if (Map.class.isAssignableFrom(aClass)) {
Map<Object, Object> map = (Map<Object, Object>) obj1;
if (actualTypeArgument instanceof ParameterizedType) {
Type[] typs = ((ParameterizedType) actualTypeArgument).getActualTypeArguments();
Class<?> cls1 = TypeUtil.getClass(typs[0]);
Class<?> cls2 = TypeUtil.getClass(typs[1]);
//cls1
Object o1 = "";
if (!cls1.isPrimitive() && !cls1.getName().startsWith("java.lang")) {
o1 = cls1.newInstance();
setFieldDefault(o1);
}
//cls2
Object o2 = null;
if (!cls2.isPrimitive() && !cls2.getName().startsWith("java.lang")) {
o2 = cls2.newInstance();
setFieldDefault(o2);
}
if (o1 != "" || o2 != null) {
map.put(o1, o2);
}
setGenericFieldValue(o, map);
return;
} else {
setGenericFieldValue(o, map);
}
}
//设置泛型属性
setGenericFieldValue(o, obj1);
//泛型嵌套
if (actualTypeArgument instanceof ParameterizedType) {
setGenericDefault(actualTypeArgument, aClass, obj1);
}
}
}
private static void setGenericFieldValue(Object obj, Object obj1) throws IllegalAccessException {
for (Field field : obj.getClass().getDeclaredFields()) {
Type fieType = field.getGenericType();
//泛型参数
if (fieType instanceof TypeVariableImpl || fieType instanceof ParameterizedType) {
field.setAccessible(true);
Class<?> fieldClazz = TypeUtil.getClass(fieType);
//集合属性,唯一属性
if (Collection.class.isAssignableFrom(fieldClazz)) {
field.set(obj, Collections.singletonList(obj1));
} else {
field.set(obj, obj1);
}
}
}
}
/**
* 设置字段默认值
*
* @param obj obj
* @throws Exception 异常
*/
private static void setFieldDefault(Object obj) throws Exception {
Class<?> clazz = obj.getClass();
if (clazz.getName().startsWith("java.")) {
return;
}
for (Field field : clazz.getDeclaredFields()) {
Class<?> fieldClazz = field.getType();
Type fieldType = field.getGenericType();
//跳过私有化属性权限校验进行赋值
field.setAccessible(true);
//基本数据类型,枚举属性
if (fieldClazz.isPrimitive() || fieldClazz.getName().startsWith("java.lang") || fieldClazz.isEnum()) {
continue;
}
//数组
if (fieldClazz.isArray()) {
//基本数组
if (ClassUtil.isSimpleValueType(fieldClazz.getComponentType())) {
continue;
}
//实例化属性
Object fieldObj = fieldClazz.newInstance();
field.set(obj, fieldObj);
//引用数组
continue;
}
//是否为单列集合
if (Collection.class.isAssignableFrom(fieldClazz)) {
if (fieldType instanceof ParameterizedType) {
Type ts = ((ParameterizedType) fieldType).getActualTypeArguments()[0];
Class<?> aClass = TypeUtil.getClass(ts);
//基本数据类型
if (aClass.isPrimitive() || aClass.getName().startsWith("java.lang") || aClass.isEnum()) {
field.set(obj, Collections.emptyList());
continue;
}
Object o = aClass.newInstance();
if (aClass != clazz) {
setFieldDefault(o);
}
field.set(obj, Collections.singletonList(o));
}
continue;
}
//双列集合
if (Map.class.isAssignableFrom(fieldClazz)) {
if (fieldType instanceof ParameterizedType) {
Type[] typs = ((ParameterizedType) fieldType).getActualTypeArguments();
Class<?> cls1 = TypeUtil.getClass(typs[0]);
Class<?> cls2 = TypeUtil.getClass(typs[1]);
//cls1
Object o1 = "";
if (!cls1.isPrimitive() && !cls1.getName().startsWith("java.lang")) {
o1 = cls1.newInstance();
setFieldDefault(o1);
}
//cls2
Object o2 = null;
if (!cls2.isPrimitive() && !cls2.getName().startsWith("java.lang")) {
o2 = cls2.newInstance();
setFieldDefault(o2);
}
HashMap<Object, Object> map = new HashMap<>();
if (o1 != "" || o2 != null) {
map.put(o1, o2);
}
field.set(obj, map);
} else {
field.set(obj, new JSONObject());
}
continue;
}
//自定义对象
Object fieldObj = fieldClazz.newInstance();
setFieldDefault(fieldObj);
field.set(obj, fieldObj);
}
}
/**
* 获取 Json 字符串
*
* @param obj obj
* @return {@link String}
*/
private static String getJsonString(Object obj) {
return JSON.toJSONString(obj,
SerializerFeature.PrettyFormat,
SerializerFeature.WriteMapNullValue,
SerializerFeature.WriteNullStringAsEmpty,
SerializerFeature.WriteNullNumberAsZero,
SerializerFeature.IgnoreNonFieldGetter);
}
/**
* 根据方法出入参生成解析json类型
*
* @param type 类型
* @return {@link String}
* @throws Exception 异常
*/
private static String parseTypeToJson(Type type) throws Exception {
Class<?> cls = TypeUtil.getClass(type);
//基本数据类型,枚举属性
if (cls.isPrimitive() || cls.getName().startsWith("java.lang") || cls.isEnum()) {
return "";
}
//是否为单列集合
if (Collection.class.isAssignableFrom(cls)) {
if (type instanceof ParameterizedType) {
Class<?> aClass = TypeUtil.getClass(((ParameterizedType) type).getActualTypeArguments()[0]);
//基本数据类型
if (aClass.isPrimitive() || aClass.getName().startsWith("java.lang") && !aClass.isEnum()) {
return "[]";
}
//引用集合
Object o = aClass.newInstance();
setFieldDefault(o);
return getJsonString(Collections.singletonList(o));
}
return "[]";
}
//双列集合
if (Map.class.isAssignableFrom(cls)) {
if (type instanceof ParameterizedType) {
Type[] typs = ((ParameterizedType) type).getActualTypeArguments();
Class<?> cls1 = TypeUtil.getClass(typs[0]);
Class<?> cls2 = TypeUtil.getClass(typs[1]);
//cls1
Object o1 = "";
if (!cls1.isPrimitive() && !cls1.getName().startsWith("java.lang") && !cls2.isEnum()) {
o1 = cls1.newInstance();
setFieldDefault(o1);
}
//cls2
Object o2 = null;
if (!cls2.isPrimitive() && !cls2.getName().startsWith("java.lang") && !cls2.isEnum()) {
o2 = cls2.newInstance();
setFieldDefault(o2);
}
HashMap<Object, Object> map = new HashMap<>();
if (o1 != "" || o2 != null) {
map.put(o1, o2);
}
return getJsonString(map);
}
return "{}";
}
//非自定义对象
if (cls.getName().startsWith("java.")) {
return "";
}
//实例化对象
Object o = cls.newInstance();
setFieldDefault(o);
//自定义泛型对象设置值
setGenericDefault(type, cls, o);
//普通自定义对象
return getJsonString(o);
}
}