在swagger上生成关于json数据类型返回结果的描述

在swagger上生成关于json数据类型返回结果的描述注解ApiReturnJsonObject表示返回结果的map结构package com.test.swagger2;import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.Re...
摘要由CSDN通过智能技术生成

在swagger上生成关于json数据类型返回结果的描述

实现原理:在MyOperationBuilderPlugin类中读取controller类方法上的ApiReturnJsonArray注解和ApiReturnJsonObject注解,动态构建对应数据结构的类。

  1. ApiReturnJsonArray表示的是list数据结构(用于接口返回值类型声明)
  2. ApiReturnJsonObject表示map数据结构(用于接口返回值类型声明)
  3. ApiJsonProperty表示key-value数据结构
  4. ApiJsonObject表示map数据结构(用于接口入参声明)

注:目前代码只实现了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("["));
                
  • 3
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值