当前位置:   article > 正文

自开发添加swagger map类型参数说明_optional optional = methodparameter

optional optional = methodparameter.findannotation(apijsonobj

1 添加maven

  1. <dependency>
  2. <groupId>io.springfox</groupId>
  3. <artifactId>springfox-swagger2</artifactId>
  4. <version>2.7.0</version>
  5. </dependency>

2 添加ApiJsonObject类

  1. import java.lang.annotation.ElementType;
  2. import java.lang.annotation.Retention;
  3. import java.lang.annotation.RetentionPolicy;
  4. import java.lang.annotation.Target;
  5. @Target({ElementType.PARAMETER, ElementType.FIELD, ElementType.METHOD})
  6. @Retention(RetentionPolicy.RUNTIME)
  7. public @interface ApiJsonObject {
  8. ApiJsonProperty[] value(); //对象属性值
  9. String name(); //对象名称
  10. }

3 添加属性类ApiJsonProperty

  1. import java.lang.annotation.ElementType;
  2. import java.lang.annotation.Retention;
  3. import java.lang.annotation.RetentionPolicy;
  4. import java.lang.annotation.Target;
  5. @Target(ElementType.ANNOTATION_TYPE)
  6. @Retention(RetentionPolicy.RUNTIME)
  7. public @interface ApiJsonProperty {
  8. String key(); // key
  9. String example() default "";// 示例
  10. String type() default "string"; // 支持string、int、double
  11. String description() default "";// 参数描述
  12. boolean required() default true; // 是否必传
  13. }

3 添加swagger读取自定义信息类MapReaderForApi

  1. import com.fasterxml.classmate.TypeResolver;
  2. import com.google.common.base.Optional;
  3. import javassist.*;
  4. import javassist.bytecode.AnnotationsAttribute;
  5. import javassist.bytecode.ConstPool;
  6. import javassist.bytecode.annotation.Annotation;
  7. import javassist.bytecode.annotation.BooleanMemberValue;
  8. import javassist.bytecode.annotation.DoubleMemberValue;
  9. import javassist.bytecode.annotation.IntegerMemberValue;
  10. import javassist.bytecode.annotation.StringMemberValue;
  11. import org.springframework.beans.factory.annotation.Autowired;
  12. import org.springframework.core.annotation.Order;
  13. import org.springframework.stereotype.Component;
  14. import springfox.documentation.schema.ModelRef;
  15. import springfox.documentation.service.ResolvedMethodParameter;
  16. import springfox.documentation.spi.DocumentationType;
  17. import springfox.documentation.spi.service.ParameterBuilderPlugin;
  18. import springfox.documentation.spi.service.contexts.ParameterContext;
  19. import java.util.Map;
  20. /**
  21. *
  22. * @Title: MapReaderForApi.java
  23. * @Description: 将map入参匹配到swagger文档的工具类
  24. * @version 1.0
  25. */
  26. @Component
  27. @Order // plugin加载顺序,默认是最后加载
  28. public class MapReaderForApi implements ParameterBuilderPlugin {
  29. @Autowired
  30. private TypeResolver typeResolver;
  31. private final static String basePackage = "com.xsy.dto."; // 动态生成的虚拟DTO Class的包路径
  32. @Override
  33. public void apply(ParameterContext parameterContext) {
  34. ResolvedMethodParameter methodParameter = parameterContext.resolvedMethodParameter();
  35. if (methodParameter.getParameterType().canCreateSubtype(Map.class)
  36. || methodParameter.getParameterType().canCreateSubtype(String.class)) { // 判断是否需要修改对象ModelRef,这里我判断的是Map类型和String类型需要重新修改ModelRef对象
  37. Optional<ApiJsonObject> optional = methodParameter.findAnnotation(ApiJsonObject.class); // 根据参数上的ApiJsonObject注解中的参数动态生成Class
  38. if (optional.isPresent()) {
  39. String name = optional.get().name(); // model 名称
  40. ApiJsonProperty[] properties = optional.get().value();
  41. parameterContext.getDocumentationContext().getAdditionalModels()
  42. .add(typeResolver.resolve(createRefModel(properties, name))); // 向documentContext的Models中添加我们新生成的Class
  43. parameterContext.parameterBuilder() // 修改Map参数的ModelRef为我们动态生成的class
  44. .parameterType("body").modelRef(new ModelRef(name)).name(name);
  45. }
  46. }
  47. }
  48. /**
  49. * 根据propertys中的值动态生成含有Swagger注解的javaBeen
  50. */
  51. private Class createRefModel(ApiJsonProperty[] propertys, String name) {
  52. ClassPool pool = ClassPool.getDefault();
  53. CtClass ctClass = pool.makeClass(basePackage + name);
  54. try {
  55. for (ApiJsonProperty property : propertys) {
  56. ctClass.addField(createField(property, ctClass));
  57. }
  58. return ctClass.toClass();
  59. } catch (Exception e) {
  60. e.printStackTrace();
  61. return null;
  62. }
  63. }
  64. /**
  65. * 根据property的值生成含有swagger apiModelProperty注解的属性
  66. */
  67. private CtField createField(ApiJsonProperty property, CtClass ctClass)
  68. throws NotFoundException, CannotCompileException {
  69. CtField ctField = new CtField(getFieldType(property.type()), property.key(), ctClass);
  70. ctField.setModifiers(Modifier.PUBLIC);
  71. ConstPool constPool = ctClass.getClassFile().getConstPool();
  72. AnnotationsAttribute attr = new AnnotationsAttribute(constPool, AnnotationsAttribute.visibleTag);
  73. Annotation ann = new Annotation("io.swagger.annotations.ApiModelProperty", constPool);
  74. ann.addMemberValue("value", new StringMemberValue(property.description(), constPool));
  75. // string类型
  76. if (ctField.getType().subclassOf(ClassPool.getDefault().get(String.class.getName())))
  77. ann.addMemberValue("example", new StringMemberValue(property.example(), constPool));
  78. // int类型
  79. if (ctField.getType().subclassOf(ClassPool.getDefault().get(Integer.class.getName())))
  80. ann.addMemberValue("example", new IntegerMemberValue(Integer.parseInt(property.example()), constPool));
  81. // double类型
  82. if (ctField.getType().subclassOf(ClassPool.getDefault().get(Double.class.getName())))
  83. ann.addMemberValue("example", new DoubleMemberValue(Double.parseDouble(property.example()), constPool));
  84. ann.addMemberValue("required", new BooleanMemberValue(property.required(), constPool));
  85. attr.addAnnotation(ann);
  86. ctField.getFieldInfo().addAttribute(attr);
  87. return ctField;
  88. }
  89. /**
  90. *
  91. * @Title: MapApiReader.java
  92. * @Description: 参数类型,后续可以增加多少类型
  93. * @date
  94. */
  95. private CtClass getFieldType(String type) throws NotFoundException {
  96. CtClass fileType = null;
  97. switch (type) {
  98. case "string":
  99. fileType = ClassPool.getDefault().get(String.class.getName());
  100. break;
  101. case "int":
  102. fileType = ClassPool.getDefault().get(Integer.class.getName());
  103. case "double":
  104. fileType = ClassPool.getDefault().get(Double.class.getName());
  105. break;
  106. }
  107. return fileType;
  108. }
  109. @Override
  110. public boolean supports(DocumentationType delimiter) {
  111. return true;
  112. }
  113. }

4 使用DemoController

  1. @PostMapping(value = "/demo")
  2. @ApiOperation(value = "获取资产", notes = "入参为map,userId必传")
  3. public String valuationValue(@ApiJsonObject(name = "RequestModel", value = {
  4. @ApiJsonProperty(key = "userId", example = "xsy123", description = "用户Id必传", type = "string", required = true),
  5. @ApiJsonProperty(key = "indexs", example = "1,2", description = "指标编号非必传", type = "string", required = false),
  6. @ApiJsonProperty(key = "queryDate", example = "2018-12-24", description = "查询日期非必传", type = "string", required = false) })
  7. @RequestBody Map<String, Object> params) {
  8. log.info(String.format("Method[%s], args[%s]", "demo", params.toString()));
  9. return "";
  10. }

 

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop】
推荐阅读
相关标签
  

闽ICP备14008679号