相关文章推荐
奔放的生菜  ·  Traceback (most ...·  5 月前    · 
风流的书签  ·  extends ...·  5 月前    · 

假设有个返回对象是这样的
List<Map<String, PageResult<Map<String, List>, PageResult<Map<Integer, PageResult<Set,Map<String, ? extends CreateBiV3Result>, BigDecimal>>, FileBean, Date>, Date>>>

那他的返回格式应该是什么样子呢,于是我就用swagger试了一下

代码试这样写的

    @ApiOperation("测试swagger返回数据格式")
    @GetMapping("testResult")
    public List<Map<String, Test.PageResult<Map<String, List<CompareTable>>, Test.PageResult<Map<Integer, Test.PageResult<Set<Test.TestBigDecimal>,
            Map<String, ? extends CreateBiV3Result>, BigDecimal>>, FileBean, Date>, Date>>> testResult() {
        return null;

结果swagger给我展示的是这样的

在这里插入图片描述
在这里插入图片描述
这就怪了,按说没问题啊,应该可以获取返回对象数据格式的啊,这才有了我自己的思考,swagger究竟试怎么将返回的class处理成一个json的呢?查了一遍发现swagger试通过spring的fox做的,具体我也没在研究,就想着自己能不能写一个根据返回的class生成一个默认的json格式的工具类呢?经过查阅资料,总算是完成了,下面就是我的代码

import com.google.gson.Gson; import javassist.Modifier; import java.io.File; import java.io.InputStream; import java.io.OutputStream; import java.lang.reflect.*; import java.math.BigDecimal; import java.util.*; * 根据泛型,json格式 public class ClassToDefJson { private Object object; private Map<TypeVariable<? extends Class<?>>, Type> variableTypeMap = new LinkedHashMap<>(); private List<TypeVariable<? extends Class<?>>> typeParameters = new ArrayList<>(); private List<Type> actualTypeArguments = new ArrayList<>(); private ClassToDefJson parentClassToDefJson; public static String toJson(Type type, Gson gson) throws IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException { return new ClassToDefJson(type, null).getJson(gson); public static Object toDefObject(Type type) throws IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException { return new ClassToDefJson(type, null).getObject(); * 构建泛型解析对象 * @param type * @param classToDefJson * @throws InstantiationException * @throws IllegalAccessException private ClassToDefJson(Type type, ClassToDefJson classToDefJson) throws InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException { if (type == null || Void.class == type || Void.TYPE == type) { return; parentClassToDefJson = classToDefJson; if (type instanceof Class) { object = createObj((Class<?>) type); } else if (type instanceof ParameterizedType) { initVariableTypeMap((ParameterizedType) type); object = createObj((Class<?>) ((ParameterizedType) type).getRawType()); } else if (type instanceof WildcardType) { Type[] upperBounds = ((WildcardType) type).getUpperBounds(); object = new ClassToDefJson(upperBounds[0], this).getObject(); } else if (type instanceof GenericArrayType) { Type genericComponentType = ((GenericArrayType) type).getGenericComponentType(); object = new Object[]{new ClassToDefJson(genericComponentType, this).getObject()}; } else if (type instanceof TypeVariable) { if (parentClassToDefJson == null) return; Type type1 = parentClassToDefJson.variableTypeMap.get(type); object = new ClassToDefJson(type1, this).getObject(); } else { throw new RuntimeException("无效的类型"); * 根据class初始化默认对象 * @param cls * @return * @throws IllegalAccessException * @throws InstantiationException private Object createObj(Class<?> cls) throws IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException { if (cls == null) return new Object(); if (List.class.isAssignableFrom(cls)) { return createList(); } else if (Map.class.isAssignableFrom(cls)) { return createMap(); } else if (Set.class.isAssignableFrom(cls)) { return createSet(); } else if (baseType.containsKey(cls)) { return baseType.get(cls); } else { if (cls.isInterface()) { return new Object(); Object o = newInstance(cls); if (cls.getName().contains("CellData")) { System.out.println(o.getClass()); return getObjectMap(cls, o); private Object getObjectMap(Class<?> cls, Object o) throws IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException { if (baseType.containsKey(cls)) { return baseType.get(cls); // 该map与o拥有相同的数据格式 Map<String, Object> objectMap = new LinkedHashMap<>(); List<Field> fields = new ArrayList<>(); addAllDeclaredFields(fields, cls); addField(o, objectMap, fields); return objectMap; * 通过反射创建对象,处理非静态内部类的情况 * @param cls * @return * @throws InstantiationException * @throws IllegalAccessException * @throws NoSuchMethodException * @throws InvocationTargetException private Object newInstance(Class<?> cls) throws InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException { if (cls.isMemberClass()) { // 判断是否是内部类 if (!Modifier.isStatic(cls.getModifiers())) { // 如果不是静态内部类,初始化方式不一样 Class<?> declaringClass = cls.getDeclaringClass(); Object declaringObj = newInstance(declaringClass); Constructor<?> declaredConstructor = cls.getDeclaredConstructor(declaringClass); Object newInstance = declaredConstructor.newInstance(declaringObj); return newInstance; return cls.newInstance(); * 创建set对象 * @return * @throws InstantiationException * @throws IllegalAccessException private Object createSet() throws InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException { HashSet<Object> objects = new HashSet<>(); if (actualTypeArguments.size() != 1) return objects; objects.add(createCollection(actualTypeArguments.get(0))); return objects; * 创建map对象 * @return * @throws InstantiationException * @throws IllegalAccessException private Object createMap() throws InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException { HashMap objects = new HashMap<>(); if (actualTypeArguments.size() != 2) return objects; Object key = createCollection(actualTypeArguments.get(0)); Object val = createCollection(actualTypeArguments.get(1)); objects.put(key, val); return objects; * 创建list对象 * @return * @throws InstantiationException * @throws IllegalAccessException private Object createList() throws InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException { ArrayList<Object> objects = new ArrayList<>(); if (actualTypeArguments.size() != 1) return objects; objects.add(createCollection(actualTypeArguments.get(0))); return objects; * 创建集合 * @param type * @return * @throws InstantiationException * @throws IllegalAccessException private Object createCollection(Type type) throws InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException { if (type instanceof TypeVariable && this.parentClassToDefJson != null) { type = this.parentClassToDefJson.variableTypeMap.get(type); return new ClassToDefJson(type, this).getObject(); * 组装对象的字段 * @param bean * @param objectMap * @param fields * @throws IllegalAccessException * @throws InstantiationException private void addField(Object bean, Map<String, Object> objectMap, List<Field> fields) throws IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException { for (Field field : fields) { String name = field.getName(); if (Modifier.isFinal(field.getModifiers())) { continue; field.setAccessible(true); Type genericType = field.getGenericType(); Object val = field.get(bean); if (val != null) { // 有默认值,直接赋默认值 if (val instanceof Collection || val instanceof Map) { int size = val instanceof Collection ? ((Collection) val).size() : ((Map) val).size(); if (size == 0) { initFieldVal(objectMap, name, genericType); } else { objectMap.put(name, val); } else { // System.out.println("name:" + name + ",object:" + bean.getClass()); Object objectFieldVal = getObjectMap(val.getClass(), val); objectMap.put(name, objectFieldVal); } else {// 没有默认值,创建对象 initFieldVal(objectMap, name, genericType); private void initFieldVal(Map<String, Object> objectMap, String name, Type genericType) throws InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException { ClassToDefJson classToDefJson = new ClassToDefJson(genericType, this); Object object = classToDefJson.getObject(); objectMap.put(name, object); // field.set(bean, object); * 循环获取改对象的父类字段 * @param fields * @param cls private void addAllDeclaredFields(List<Field> fields, Class<?> cls) { if (Object.class == cls) return; Field[] declaredFields = cls.getDeclaredFields(); fields.addAll(Arrays.asList(declaredFields)); addAllDeclaredFields(fields, cls.getSuperclass()); * 初始化泛型对应的数据类型 * @param type private void initVariableTypeMap(ParameterizedType type) { Class<?> cls = (Class<?>) type.getRawType(); typeParameters.addAll(Arrays.asList(cls.getTypeParameters())); actualTypeArguments.addAll(Arrays.asList(type.getActualTypeArguments())); if (typeParameters.size() != actualTypeArguments.size()) throw new RuntimeException("数据异常"); for (int i = 0; i < typeParameters.size(); i++) { variableTypeMap.put(typeParameters.get(i), actualTypeArguments.get(i)); private Object getObject() { return object; public String getJson() { return getJson(new Gson()); public String getJson(Gson gson) { if (gson == null) return getJson(); return gson.toJson(object); private static final Map<Class<?>, Object> baseType = new HashMap<>(); * 内置一些基础类型的默认值 static { baseType.put(String.class, "string"); baseType.put(Integer.class, "int"); baseType.put(Double.class, "double"); baseType.put(Float.class, "float"); baseType.put(Character.class, "char"); baseType.put(Long.class, "long"); baseType.put(Byte.class, "byte"); baseType.put(BigDecimal.class, "bigDecimal"); baseType.put(Date.class, "date"); baseType.put(Boolean.class, "boolean"); baseType.put(Short.class, "short"); Map<Class<?>, Object> esMap = new HashMap<>(); baseType.forEach((aClass, o) -> { try { Class<?> cls = Class.forName("[L" + aClass.getName() + ";"); esMap.put(cls, new Object[]{o}); } catch (ClassNotFoundException e) { e.printStackTrace(); }); baseType.putAll(esMap); baseType.put(Integer.TYPE, "int"); baseType.put(new int[1].getClass(), new Object[]{"int"}); baseType.put(Double.TYPE, "double"); baseType.put(new double[1].getClass(), new Object[]{"double"}); baseType.put(Float.TYPE, "float"); baseType.put(new float[1].getClass(), new Object[]{"float"}); baseType.put(Character.TYPE, "char"); baseType.put(new char[1].getClass(), new Object[]{"char"}); baseType.put(Long.TYPE, "long"); baseType.put(new long[1].getClass(), new Object[]{"long"}); baseType.put(Byte.TYPE, "byte"); baseType.put(new byte[1].getClass(), new Object[]{"byte"}); baseType.put(Boolean.TYPE, "boolean"); baseType.put(new boolean[1].getClass(), new Object[]{"boolean"}); baseType.put(Short.TYPE, "short"); baseType.put(new short[1].getClass(), new Object[]{"short"}); baseType.put(File.class, "file"); baseType.put(InputStream.class, "inputStream"); baseType.put(OutputStream.class, "outputStream");

测试一下结果怎么样,还是用那个老长的返回结果对象:

Class<?> cls = Test.class;
Method test = cls.getMethod("testResult");
ResolvableType resolvableType = ResolvableType.forMethodReturnType(test);
Object object = ClassToDefJson.toDefObject(resolvableType.getType());
String json = gson.toJson(object);
System.out.println(json);

下面是结果:

"string": { "msg": "string", "code": "string", "t": [ "string": [ "schemaPattern1": "string", "schemaPattern2": "string", "dbName1": "string", "dbName2": "string", "tableName": "string", "dbUserName1": "string", "dbUserName2": "string", "dbHost2": "string", "isDba2": false, "isDba1": false, "password2": "string", "password1": "string", "dbHost1": "string" "t3s": [ "date" "t2": { "msg": "string", "code": "string", "t": [ "int": { "msg": "string", "code": "string", "t": [ "bigDecimal": "bigDecimal", "baseField": "string" "t3s": [ "bigDecimal" "t2": { "string": { "pageData": { "pageNum": 1, "pageSize": 10, "sumTotal": 0, "resultData": [], "colDes": [] "resultList": [], "tableBean": { "queryId": null, "tableId": null, "htmlHeader": null, "searchList": [], "tableHeader": [] "t3s": [ "date" "t2": { "fileName": "string", "isFile": 0, "parentPath": "string" Disconnected from the target VM, address: '127.0.0.1:60107', transport: 'socket' Process finished with exit code 0

不错不错,味道好极了。
其实这里主要涉及的就是java反射的东西,以及对于java.lang.reflect.Type及其几个子类的应用

java.lang.Class
java.lang.reflect.ParameterizedType
java.lang.reflect.WildcardType
java.lang.reflect.GenericArrayType
java.lang.reflect.TypeVariable

Swagger模式验证器 该库针对Swagger 2规范的definitions部分中definitions模型验证JSON对象。 InputStream spec = getClass() . getResourceAsStream( " mySpec.yaml " ); SwaggerValidator validator = SwaggerValidator . forYamlSchema(spec); ProcessingReport report = validator . validate( " { \" name \" : \" Bob \" } " , " /definitions/User " ); if (report . isSuccess()) { doStuff(); 该库在Maven Central上可用: < dependency> 如果请求参数为某个对象,还需要在swagger里显示出注释 第一步:在对象的类上加注解@ApiModel,类的字段上加注解@ApiModelProperty(value = "id或者姓名等注释") 第二步:controller类里直接使用@RequestBody OrderModel orderModel,json接收(如果是想表单提交,则用@ModelAttribute OrderMode... 首先,需要考虑的是,swagger会不会很申请,能在没有任何json数据的情况下,读取到数据的key,从而生成文档。把想要被swagger识别到的类型直接使用ResultBean,T为pojo类型,即可被swagger扫描到类型,生成T类型的文档信息。这里只是要了一下boolean,自定义类型也是一样的操作,到此已经能处理很多问题了,但是还是不能处理json的文档。上面的代码当然只是简单的统一了返回类型,其中data字段不能显示更加细节的信息,于是需要使用泛型。成功生成了json的信息。.......... 关于snmp的开发,netsnmp目前的最新版本是5.7.3。 为了支持python的开发,网上的文章看了不少,走了不少弯路,所以总结一下,和大家共享。第一部分: 安装snmp程序以及服务。在Ubuntu中安装snmp的支持,有两种方法,第一种是直接通过apt-get进行安装。第二种是从netsnmp官网下载源码net-snmp-5.7.3.tar.gz,进行编译安装。本人对于第二种方法,查阅了网... spring boot 处理 swagger 嵌套数据展示在开发的过程中,我们会常常使用swagger做我们的在线文档.我们会在对象的属性上使用@ApiModelProperty 等api注解,但是遇到对象嵌套的时候,如何返回一个嵌套的json文档就需要我们做一些简单的处理如果只在对象某个属性上使用 @ApiModelProperty 并不会起作用1234567891011121314151617... 目前使用Swagger2形成接口文档时,当系统设计的接口返回的类型不是实体对象时,Swagger2无法在接口文档页面中显示返回结果字段说明,比如返回json、map等可以存储key-val形式的类型;均无法在接口文档页面上显示返回的字段备注说明,所以怎么才能像实体对象一样显示正常的model字段说明是我们这次需要解决的问题; 首先告诉Swagger2该接口需要返回的字段具体有哪些 定义两个...