赞
踩
实现原理:在MyOperationBuilderPlugin类中读取controller类方法上的ApiReturnJsonArray注解和ApiReturnJsonObject注解,动态构建对应数据结构的类。
注:目前代码只实现了List<Map<String,Object>>和Map<String,Object>两种结构,如果json数据结构存在三四层及以上,则需另外定义新的注解。总的来说,差不多是一层json数据结构就要定义一个注解,因为注解不允许继承和自引用。具体实现方式参照ApiReturnJsonArray、ApiReturnJsonObject、ApiJsonProperty的关系。
swagger的代码示例,可点击此处进行下载,或在浏览器地址栏输入https://download.csdn.net/download/qq_31601531/12504190
注解ApiReturnJsonObject表示返回结果的map结构
package com.hua.demo.swagger.dto; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * 返回结果描述注解 * @author hua * */ @Target({ ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) public @interface ApiReturnJsonObject { ApiJsonProperty[] value(); //对象属性值 String name() default "ReturnMap"; //类名 }
注解ApiReturnJsonArray表示返回结果的数组结构
package com.hua.demo.swagger.dto; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * 返回结果描述注解-数组 * @author hua * */ @Target({ ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) public @interface ApiReturnJsonArray { ApiReturnJsonObject[] values(); String name() default "ReturnList"; //类名 }
注解ApiJsonProperty表示map中一个key-value的数据
package com.hua.demo.swagger.dto; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * 接口文档入参字段说明 * @author hua * */ @Target(ElementType.ANNOTATION_TYPE) @Retention(RetentionPolicy.RUNTIME) public @interface ApiJsonProperty { /** * 参数名称 * */ String name(); /** * 参数的中文含义 * */ String value() default ""; /** * 参数示例 * */ String example() default ""; /** * 支持各种基础数据类型、或包装的数据类型 * */ String dataType() default "string"; /** * 参数描述(想要在参数旁有中文解析,要给此属性赋值) * */ String description() default ""; /** * 是否必填 * */ boolean required() default false; //支持string 和 int Class type() default String.class; }
注解ApiJsonObject表示接口入参的map结构
package com.hua.demo.swagger.dto; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * 接口文档入参对象说明 * @author hua * */ @Target({ElementType.PARAMETER, ElementType.FIELD, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) public @interface ApiJsonObject { ApiJsonProperty[] value(); //对象属性值 String name() default "ParamMap"; //对象名 }
MyBaseBuildPlugin类用于动态构造一个类代表注解ApiReturnJsonArray和ApiReturnJsonObject的数据结果
注:类名不能重复,不然会报frozon class的错
package com.hua.demo.swagger.plugin; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.TypeReference; import com.fasterxml.classmate.ResolvedType; import com.fasterxml.classmate.TypeResolver; import com.hua.demo.swagger.dto.ApiJsonProperty; import javassist.*; import javassist.bytecode.AnnotationsAttribute; import javassist.bytecode.ConstPool; import javassist.bytecode.annotation.*; import org.apache.commons.collections.MapUtils; import org.apache.commons.lang.ObjectUtils; import org.apache.commons.lang.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import springfox.documentation.spi.service.contexts.DocumentationContext; import java.util.ArrayList; import java.util.List; import java.util.Map; /** * @author hua * */ @Component public class MyBaseBuildPlugin { @Autowired(required = false) protected TypeResolver typeResolver; /** * 参数的全局索引,用于动态生成类,确保类名不会重复 * */ public static int paramIndex = 0; private ClassPool pool = ClassPool.getDefault(); /** * 用于标记json结构中描述数据结构的key值 * */ private String childKey = "child"; /** * 动态生成的Class名 * */ protected final static String basePackage = "com.hua.demo.swagger.dto."; protected final String StringTypeName = "java.lang.String"; protected final String IntegerTypeName = "java.lang.Integer"; protected final String LongTypeName = "java.lang.Long"; protected final String FloatTypeName = "java.lang.Float"; protected final String DoubleTypeName = "java.lang.Double"; protected final String BooleanTypeName = "java.lang.Boolean"; protected final String ShortTypeName = "java.lang.Short"; /** * 根据propertys中的值动态生成含有Swagger注解的javaBeen * @param context * @param propertys * @param name 类名 */ protected Class createRefModel(DocumentationContext context, ApiJsonProperty[] propertys, String name) { CtClass ctClass = pool.makeClass(basePackage + name); try { this.translatePropertyToJSONObject(context,ctClass,propertys); Class clazz = ctClass.toClass(); ResolvedType resolvedType = typeResolver.resolve(clazz); context.getAdditionalModels().add(resolvedType); return clazz; } catch (Exception e) { e.printStackTrace(); return null; } } /*** * 此方法是实现了把当前方法上的所有ApiJsonProperty注解进行特定解析,解析成对应结构的json * 1、首先根据是否含有'.'来进行分组 * 2、把含有'.'的部分重新进行解析,并把解析后的结果放到不含'.'的结果之中 * 3、把解析完成的数据进行 * @param context * @param ctClass * @param propertys * */ protected void translatePropertyToJSONObject(DocumentationContext context,CtClass ctClass,ApiJsonProperty[] propertys) throws NotFoundException, CannotCompileException{ List<ApiJsonProperty> propertyList = new ArrayList<ApiJsonProperty>(); JSONObject propertyMap = new JSONObject(); for(ApiJsonProperty property : propertys){ if(property.name().contains(".")){ propertyList.add(property); }else{ JSONObject propertyObj = this.transferAnnationToJSONObject(property); propertyMap.put(property.name(),propertyObj); } } for(ApiJsonProperty property : propertyList){ JSONObject propertyObj = this.transferAnnationToJSONObject(property); String name = property.name(); String[] names = name.split("\\."); propertyObj.put("name",names[1]); if(property.name().contains("[") && property.name().contains("]")){ String paramName = names[0].substring(0,names[0].indexOf("["));
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。