使用场景: 需要改造swagger原有的注解,使其达到高扩展性;
本文扩展的@ApiImplicitParam 注解;
直接上代码吧
1.@ApiParams 注解
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.stereotype.Component;
import io.swagger.annotations.ApiImplicitParam;
@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Component
public @interface ApiParams {
// basicHeader
ApiImplicitParam[] basicHeader() default {@ApiImplicitParam(name = "Accept-Language", value = "语言zh-CN",
paramType = "header", dataTypeClass = String.class, defaultValue = "zh-CN", example = "zh-CN"),};
// userHeader
ApiImplicitParam[] userHeader() default {@ApiImplicitParam(name = "userId", value = "用户id", required = true,
paramType = "header", dataTypeClass = Integer.class, example = "1")};
// 扩展的参数
ApiImplicitParam[] expandParam() default {};
}
2.OperationApiParamsReader 实现
import static com.google.common.base.Strings.emptyToNull;
import static springfox.documentation.schema.Types.isBaseType;
import static springfox.documentation.swagger.common.SwaggerPluginSupport.SWAGGER_PLUGIN_ORDER;
import static springfox.documentation.swagger.common.SwaggerPluginSupport.pluginDoesApply;
import static springfox.documentation.swagger.readers.parameter.Examples.examples;
import static springfox.documentation.swagger.schema.ApiModelProperties.allowableValueFromString;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import com.google.common.base.MoreObjects;
import com.google.common.base.Optional;
import com.google.common.collect.Lists;
import io.swagger.annotations.ApiImplicitParam;
import springfox.documentation.builders.ParameterBuilder;
import springfox.documentation.schema.ModelRef;
import springfox.documentation.service.AllowableValues;
import springfox.documentation.service.Parameter;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spi.service.OperationBuilderPlugin;
import springfox.documentation.spi.service.contexts.OperationContext;
import springfox.documentation.spring.web.DescriptionResolver;
import springfox.documentation.swagger.common.SwaggerPluginSupport;
@Component
@Order(SwaggerPluginSupport.SWAGGER_PLUGIN_ORDER)
public class OperationApiParamsReader implements OperationBuilderPlugin {
private final DescriptionResolver descriptions;
@Autowired
public OperationApiParamsReader(DescriptionResolver descriptions) {
this.descriptions = descriptions;
}
@Override
public void apply(OperationContext context) {
context.operationBuilder().parameters(readParameters(context));
}
@Override
public boolean supports(DocumentationType delimiter) {
return pluginDoesApply(delimiter);
}
private List<Parameter> readParameters(OperationContext context) {
Optional<ApiParams> annotation = context.findAnnotation(ApiParams.class);
List<Parameter> parameters = Lists.newArrayList();
if (annotation.isPresent()) {
// basicHeader
for (ApiImplicitParam param : annotation.get().basicHeader()) {
parameters.add(implicitParameter(descriptions, param));
}
// userHeader
for (ApiImplicitParam param : annotation.get().userHeader()) {
parameters.add(implicitParameter(descriptions, param));
}
// expandParam
for (ApiImplicitParam param : annotation.get().expandParam()) {
parameters.add(implicitParameter(descriptions, param));
}
}
return parameters;
}
static Parameter implicitParameter(DescriptionResolver descriptions, ApiImplicitParam param) {
ModelRef modelRef = maybeGetModelRef(param);
return new ParameterBuilder().name(param.name()).description(descriptions.resolve(param.value()))
.defaultValue(param.defaultValue()).required(param.required()).allowMultiple(param.allowMultiple())
.modelRef(modelRef).allowableValues(allowableValueFromString(param.allowableValues()))
.parameterType(emptyToNull(param.paramType())).parameterAccess(param.access()).order(SWAGGER_PLUGIN_ORDER)
.scalarExample(param.example()).complexExamples(examples(param.examples())).build();
}
private static ModelRef maybeGetModelRef(ApiImplicitParam param) {
String dataType = MoreObjects.firstNonNull(emptyToNull(param.dataType()), "string");
AllowableValues allowableValues = null;
if (isBaseType(dataType)) {
allowableValues = allowableValueFromString(param.allowableValues());
}
if (param.allowMultiple()) {
return new ModelRef("", new ModelRef(dataType, allowableValues));
}
return new ModelRef(dataType, allowableValues);
}
}
3.TestController使用
@GetMapping(value = {"/test"})
@ApiParams(expandParam = {@ApiImplicitParam(name = "menuId", value = "菜单id", required = true,
dataTypeClass = Integer.class, example = "1")})
public String menu(@RequestParam("menuId") Integer menuId) {
return "";
}