swagger项目下载以及swagger生成带注释的请求体和响应体

一、简单的方法

1、直接定义请求DTO

package com.xiaoduye0814.t3.pojo;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;

@ApiModel("請求DTO")
public class RequestDTO {

        /**
         * 姓名
         */
        @JsonProperty
        @ApiModelProperty(value = "用戶名",example = "xiaoduye")
        private String CName;

        /**
         * 年龄
         */
        @JsonProperty
        @ApiModelProperty(value = "年龄",example = "18")
        private Integer NAge;

        @JsonIgnore
        public String getCName() {
            return CName;
        }

        @JsonIgnore
        public void setCName(String CName) {
            this.CName = CName;
        }

        @JsonIgnore
        public Integer getNAge() {
            return NAge;
        }

        @JsonIgnore
        public void setNAge(Integer NAge) {
            this.NAge = NAge;
        }
    }

2、定义返回VO

package com.xiaoduye0814.t3.pojo;

import java.util.Date;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;

/**
 * @Description 响应返回值
 * @Author xiaoduye
 * @Date 2019-03-29
 *
 */
@ApiModel(value = "响应返回值", description = "用户接口的响应返回数据")
public class ResponseVo {

    /**
     * 姓名
     */
    @JsonProperty
    @ApiModelProperty(value = "姓名")
    private String CName;

    /**
     * 年龄
     */
    @JsonProperty
    @ApiModelProperty(value = "年龄")
    private Integer NAge;

    @JsonIgnore
    public String getCName() {
        return CName;
    }

    @JsonIgnore
    public void setCName(String CName) {
        this.CName = CName;
    }

    @JsonIgnore
    public Integer getNAge() {
        return NAge;
    }

    @JsonIgnore
    public void setNAge(Integer NAge) {
        this.NAge = NAge;
    }
}

二、麻烦的方法

1、创建ApiJsonObject 类

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ElementType.PARAMETER, ElementType.FIELD, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface ApiJsonObject {

    ApiJsonProperty[] value(); //对象属性值

    String name();  //对象名称

}

2、创建接口ApiJsonProperty

    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    
    @Target(ElementType.ANNOTATION_TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    public @interface ApiJsonProperty {
    
        String key();  //key
    
        String example() default "";
    
        String type() default "string";  //支持string 和 int
    
        String description() default "";
    }

3、创建MapApiReader类

import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import com.fasterxml.classmate.TypeResolver;
import com.google.common.base.Optional;

import javassist.CannotCompileException;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtField;
import javassist.Modifier;
import javassist.NotFoundException;
import javassist.bytecode.AnnotationsAttribute;
import javassist.bytecode.ConstPool;
import javassist.bytecode.annotation.Annotation;
import javassist.bytecode.annotation.IntegerMemberValue;
import javassist.bytecode.annotation.StringMemberValue;
import springfox.documentation.schema.ModelRef;
import springfox.documentation.service.ResolvedMethodParameter;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spi.service.ParameterBuilderPlugin;
import springfox.documentation.spi.service.contexts.ParameterContext;

@Component
@Order   //plugin加载顺序,默认是最后加载
public class MapApiReader implements ParameterBuilderPlugin {
    @Autowired
    private TypeResolver typeResolver;

    @Override
    public void apply(ParameterContext parameterContext) {
        ResolvedMethodParameter methodParameter = parameterContext.resolvedMethodParameter();

        if (methodParameter.getParameterType().canCreateSubtype(Map.class) || methodParameter.getParameterType().canCreateSubtype(String.class)) { //判断是否需要修改对象ModelRef,这里我判断的是Map类型和String类型需要重新修改ModelRef对象
            Optional optional = methodParameter.findAnnotation(ApiJsonObject.class);  //根据参数上的ApiJsonObject注解中的参数动态生成Class
            if (optional.isPresent()) {
                String name = optional.get().name();  //model 名称
                ApiJsonProperty[] properties = optional.get().value();

                parameterContext.getDocumentationContext().getAdditionalModels().add(typeResolver.resolve(createRefModel(properties, name)));  //像documentContext的Models中添加我们新生成的Class

                parameterContext.parameterBuilder()  //修改Map参数的ModelRef为我们动态生成的class
                        .parameterType("body")
                        .modelRef(new ModelRef(name))
                        .name(name);
            }
        }

    }

    private final static String basePackage = "com.xx.xxx.in.swagger.model.";  //动态生成的Class名

    /**
     * 根据propertys中的值动态生成含有Swagger注解的javaBeen
     */
    private Class createRefModel(ApiJsonProperty[] propertys, String name) {
        ClassPool pool = ClassPool.getDefault();
        CtClass ctClass = pool.makeClass(basePackage + name);

        try {
            for (ApiJsonProperty property : propertys) {
                ctClass.addField(createField(property, ctClass));
            }
            return ctClass.toClass();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 根据property的值生成含有swagger apiModelProperty注解的属性
     */
    private CtField createField(ApiJsonProperty property, CtClass ctClass) throws NotFoundException, CannotCompileException {
        CtField ctField = new CtField(getFieldType(property.type()), property.key(), ctClass);
        ctField.setModifiers(Modifier.PUBLIC);

        ConstPool constPool = ctClass.getClassFile().getConstPool();

        AnnotationsAttribute attr = new AnnotationsAttribute(constPool, AnnotationsAttribute.visibleTag);
        Annotation ann = new Annotation("io.swagger.annotations.ApiModelProperty", constPool);
        ann.addMemberValue("value", new StringMemberValue(property.description(), constPool));
        if (ctField.getType().subclassOf(ClassPool.getDefault().get(String.class.getName())))
            ann.addMemberValue("example", new StringMemberValue(property.example(), constPool));
        if (ctField.getType().subclassOf(ClassPool.getDefault().get(Integer.class.getName())))
            ann.addMemberValue("example", new IntegerMemberValue(Integer.parseInt(property.example()), constPool));

        attr.addAnnotation(ann);
        ctField.getFieldInfo().addAttribute(attr);

        return ctField;
    }

    private CtClass getFieldType(String type) throws NotFoundException {
        CtClass fileType = null;
        switch (type) {
            case "string":
                fileType = ClassPool.getDefault().get(String.class.getName());
                break;
            case "int":
                fileType = ClassPool.getDefault().get(Integer.class.getName());
                break;
        }
        return fileType;
    }

    @Override
    public boolean supports(DocumentationType delimiter) {
        return true;
    }
}

4、对应controller层:
(1) 请求注释

    @PostMapping("/请求地址")
    @ApiOperation(value = "接口名称", notes = "接口描述")
   实体类接收pojo【返回值类型】  getSomething【方法名称】(
          		    @ApiJsonObject(name = "请求参数的总名称", value = {
                    @ApiJsonProperty(key = "CZjhaoma", example = "211381122245154541", description = "证件号码【String类型】"),
                    @ApiJsonProperty(key = "Size", example = "100", description = "大小【int类型】"),
                    @ApiJsonProperty(key = "StartTime", example = "2019-04-16 00:00:00.000", description = "开始时间"),
                    @ApiJsonProperty(key = "Hobby", example = "[' ']", description = "爱好【list类型】")
    
            }) @RequestBody Map 请求参数的总名称);

(2) 响应注释
实体类:

@Data
@ApiModel("请求响应结果VO")
public class ResponseVo {

/**
 * 姓名
 */
@JsonProperty
@ApiModelProperty(value = "姓名")
private String CName;

/**
 * 年龄
 */
@JsonProperty
@ApiModelProperty("年龄")
private Integer NAge;

@JsonIgnore
public String getCName() {
    return CName;
}

@JsonIgnore
public void setCName(String CName) {
    this.CName = CName;
}

@JsonIgnore
public Integer getNAge() {
    return NAge;
}

@JsonIgnore
public void setNAge(Integer NAge) {
    this.NAge = NAge;
}

5、所需架包 javassist.jar 请自行提取
链接:https://pan.baidu.com/s/1zrwwxO1M6CWDuWsufqYtUg
提取码:vvje

6、下面是我自己做的一个swagger接口的model,大家可以直接拿去使用
链接:https://pan.baidu.com/s/1ltwjw2AL7yMN0Elf2FtWEA
提取码:pc0e

接口截图如下:
swagger项目下载以及swagger生成带注释的请求体和响应体_第1张图片

swagger项目下载以及swagger生成带注释的请求体和响应体_第2张图片

swagger项目下载以及swagger生成带注释的请求体和响应体_第3张图片

swagger项目下载以及swagger生成带注释的请求体和响应体_第4张图片

swagger项目下载以及swagger生成带注释的请求体和响应体_第5张图片

你可能感兴趣的:(swagger,swagger生成带注释,的请求提和响应体)