自定义注解屏蔽Swagger接口文档属性
作者:互联网
描述
通过自定的注解屏蔽Swagger网页中的文档字段。
自定义注解
自定义注解ApiIgp,用在需要屏蔽的字段上。
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 屏蔽Swagger接口文档传输对象属性
* 示例:@ApiIgp({"hotId","hotName"}) @RequestBody HotTypeDTO hotTypeDTO
* @date 2021/1/18 11:25
*/
@Target({ElementType.PARAMETER, ElementType.FIELD, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface ApiIgp {
// 对象属性值
String[] value();
}
编写注解处理类
import com.fasterxml.classmate.TypeResolver;
import com.google.common.base.Optional;
import io.swagger.annotations.ApiModelProperty;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtField;
import javassist.NotFoundException;
import javassist.bytecode.AnnotationsAttribute;
import javassist.bytecode.ConstPool;
import javassist.bytecode.annotation.Annotation;
import javassist.bytecode.annotation.StringMemberValue;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
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.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
import java.util.stream.Collectors;
/**
* @date 2021/1/18 11:29
*/
@Configuration
@Order
public class SwaggerIgnorePropertyConfig implements ParameterBuilderPlugin {
@Autowired
private TypeResolver typeResolver;
@Override
public void apply(ParameterContext parameterContext) {
ResolvedMethodParameter methodParameter = parameterContext.resolvedMethodParameter();
Class originClass = parameterContext.resolvedMethodParameter().getParameterType().getErasedType();
Optional<ApiIgp> optional = methodParameter.findAnnotation(ApiIgp.class);
if (optional.isPresent()) {
Random random = new Random(System.currentTimeMillis());
//model 名称
String name = originClass.getSimpleName() + "-Model-" + random.nextInt(1000);
String[] properties = optional.get().value();
try {
parameterContext.getDocumentationContext()
.getAdditionalModels()
//像documentContext的Models中添加我们新生成的Class
.add(typeResolver.resolve(createRefModelIgp(properties, originClass.getPackage()+"."+name, originClass)));
} catch (Exception e) {
e.printStackTrace();
}
//修改Map参数的ModelRef为我们动态生成的class
parameterContext.parameterBuilder()
.parameterType("body")
.modelRef(new ModelRef(name))
.name(name);
}
}
private Class createRefModelIgp(String[] propertys, String name, Class origin) throws NotFoundException {
ClassPool pool = ClassPool.getDefault();
CtClass ctClass = pool.makeClass( name);
try {
Field[] fields = origin.getDeclaredFields();
List<Field> fieldList = Arrays.asList(fields);
List<String> ignorePropertys = Arrays.asList(propertys);
List<Field> dealFileds = fieldList.stream().filter(s -> !ignorePropertys.contains(s.getName())).collect(Collectors.toList());
for (Field field : dealFileds) {
CtField ctField = new CtField(ClassPool.getDefault().get(field.getType().getName()), field.getName(), ctClass);
ctField.setModifiers(Modifier.PUBLIC);
ApiModelProperty ampAnno = origin.getDeclaredField(field.getName()).getAnnotation(ApiModelProperty.class);
String attributes = java.util.Optional.ofNullable(ampAnno).map(s -> s.value()).orElse("");
//添加model属性说明
if (StringUtils.isNotBlank(attributes) ){
ConstPool constPool = ctClass.getClassFile().getConstPool();
AnnotationsAttribute attr = new AnnotationsAttribute(constPool, AnnotationsAttribute.visibleTag);
Annotation ann = new Annotation(ApiModelProperty.class.getName(), constPool);
ann.addMemberValue("value", new StringMemberValue(attributes, constPool));
attr.addAnnotation(ann);
ctField.getFieldInfo().addAttribute(attr);
}
ctClass.addField(ctField);
}
return ctClass.toClass();
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
@Override
public boolean supports(DocumentationType documentationType) {
return true;
}
}
标签:java,name,自定义,文档,new,import,Swagger,annotation,javassist 来源: https://blog.csdn.net/Ming_360/article/details/117755540