123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120 |
- package com.qmth.distributed.print.config;
- import com.fasterxml.classmate.TypeResolver;
- import com.qmth.teachcloud.common.annotation.ApiJsonObject;
- import com.qmth.teachcloud.common.annotation.ApiJsonProperty;
- import com.qmth.teachcloud.common.contant.SystemConstant;
- import org.apache.ibatis.javassist.*;
- import org.apache.ibatis.javassist.bytecode.AnnotationsAttribute;
- import org.apache.ibatis.javassist.bytecode.ConstPool;
- import org.apache.ibatis.javassist.bytecode.annotation.Annotation;
- import org.apache.ibatis.javassist.bytecode.annotation.BooleanMemberValue;
- import org.apache.ibatis.javassist.bytecode.annotation.StringMemberValue;
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.core.annotation.Order;
- import org.springframework.stereotype.Component;
- 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;
- import java.util.Map;
- import java.util.Optional;
- /**
- * @Description: swagger2 map参数说明插件
- * @Param:
- * @return:
- * @Author: wangliang
- * @Date: 2020/4/23
- */
- @Component
- @Order //plugin加载顺序,默认是最后加载
- public class MapApiReader implements ParameterBuilderPlugin {
- private final static Logger log = LoggerFactory.getLogger(MapApiReader.class);
- @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<ApiJsonObject> 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.qmth.teachcloud.entity."; //动态生成的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) {
- log.error(SystemConstant.LOG_ERROR, e);
- 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));
- ann.addMemberValue("required", new BooleanMemberValue(property.required(), 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;
- case "long":
- fileType = ClassPool.getDefault().get(Long.class.getName());
- break;
- case "boolean":
- fileType = ClassPool.getDefault().get(Boolean.class.getName());
- break;
- default:
- break;
- }
- return fileType;
- }
- @Override
- public boolean supports(DocumentationType delimiter) {
- return true;
- }
- }
|