Java swagger@ApiParam忽略某些属性

Java swagger@ApiParam忽略某些属性,java,spring-boot,swagger,swagger-ui,swagger-2.0,Java,Spring Boot,Swagger,Swagger Ui,Swagger 2.0,我有一个SpringBoot项目,带有springfox-swagger22.7.0,我有以下控制器: @Api(tags = { "Some" }, description = "CRUD for Some Stuff") @RestController @RequestMapping(path = "/some") public class SomeController { @ApiOperation(value = "Get some") @GetMapping(value =

我有一个SpringBoot项目,带有
springfox-swagger2
2.7.0
,我有以下控制器:

@Api(tags = { "Some" }, description = "CRUD for Some Stuff")
@RestController
@RequestMapping(path = "/some")
public class SomeController {

  @ApiOperation(value = "Get some")
  @GetMapping(value = "{someId}", produces = MediaType.APPLICATION_JSON_VALUE)
  public Response getSomeById(@PathVariable("someId") Id someId) {
    return ...;
  }
...
}
我想通过注释
Id
类来控制文档中显示的内容,这只适用于注释的某些部分,而不是全部。
Id
类(它有一个从
String
Id
的注册转换器):

现在返回的
Swagger JSON
如下所示:

"parameters":[{
  "name":"id",
  "in":"query",
  "description":"This is the description",
  "required":true,
  "type":"integer",
  "default":"1f1f1f",
  "format":"int64"
}]
我的问题(或者可能是错误报告)是:为什么使用了
@ApiParam
注释的某些部分(如
默认值
必需
),而其他部分没有,如
名称
类型
? 为什么我不能在这里更改
名称
类型
? 对于我的特定用例,后者是我想要更改为
string
的用例

更新 在斯卡迪亚的帮助下,我决定添加以下组件

@Component
public class OverrideSwaggerApiParamBuilder implements 
ExpandedParameterBuilderPlugin {

  @Override
  public boolean supports(DocumentationType type) {
    return DocumentationType.SWAGGER_2 == type;
  }

  @Override
  public void apply(ParameterExpansionContext context) {
    Optional<ApiParam> apiParamOptional = findApiParamAnnotation(context.getField().getRawMember());
    if (apiParamOptional.isPresent()) {
      ApiParam param = apiParamOptional.get();
      context.getParameterBuilder()
          .name(param.name())
          .modelRef(new ModelRef(param.type()))
          .build();
    }
  }
}
@组件
公共类重写WaggerapiParamBuilder实现
扩展参数builderPlugin{
@凌驾
公共布尔支持(DocumentationType){
return DocumentationType.SWAGGER_2==type;
}
@凌驾
public void apply(参数expansioncontext){

可选

理想情况下,您需要对方法参数使用
@ApiParam
,而对模型属性使用
@ApiModelProperty

public @interface ApiParam {
    /**
     * The parameter name.
     * The name of the parameter will be derived from the field/method/parameter name,
     * however you can override it.
     * Path parameters must always be named as the path section they represent.
     */
    String name() default "";
不确定是否存在类型属性,但以下是处理类型的方法:

public @interface ApiModelProperty {

    /**
     * The data type of the parameter.
     * This can be the class name or a primitive. The value will override the data type as read from the class
     * property.
     */
    String dataType() default "";

......

我正在使用版本2.6.1,在@ApiParam中找不到“type”属性,但我可以看到您正在使用“type”属性。因此,请确保它可用。我还提到@ApiModelProperty提供数据类型()处理您提到的场景。

默认情况下,@ApiParam属性“name”和“type”用于覆盖API方法中指定的参数名和检测到的直接参数类型。当您在字段上使用@ApiParam时,类型和名称由字段名及其声明的类型以及name和type的覆盖值推导而来未考虑。(在springfox中,从设计上看,您可以查看实现
springfox.documentation.swagger.readers.parameter.SwaggerExpandedParameterBuilder

如果仍希望更改此行为,可以注册
springfox.documentation.spi.service.ExpandedParameterBuilderPlugin
interlace的自定义实现

例如

@Component
public class OverrideSwaggerApiParamNameBuilder implements ExpandedParameterBuilderPlugin {

    @Override
    public boolean supports(DocumentationType type) {
        return DocumentationType.SWAGGER_2 == type;
    }

    @Override
    public void apply(ParameterExpansionContext context) {
        Optional<ApiParam> apiParamOptional = findApiParamAnnotation(context.getField().getRawMember());
        if (apiParamOptional.isPresent()) {
            fromApiParam(context, apiParamOptional.get());
        }
    }

    private void fromApiParam(ParameterExpansionContext context, ApiParam apiParam) {
        context.getParameterBuilder()
                .name(emptyToNull(apiParam.name()));
    }

    private String emptyToNull(String str) {
        return StringUtils.hasText(str) ? str : null;
    }
}
@组件
公共类重写WaggerapiParamNameBuilder实现ExpandedParameterBuilderPlugin{
@凌驾
公共布尔支持(DocumentationType){
return DocumentationType.SWAGGER_2==type;
}
@凌驾
public void apply(参数expansioncontext){
可选apiParamOptional=findApiParamAnnotation(context.getField().getRawMember());
if(apiParamOptional.isPresent()){
fromApiParam(上下文,apiParamOptional.get());
}
}
ApiParam中的私有void(参数扩展上下文,ApiParam ApiParam){
context.getParameterBuilder()
.name(emptyToNull(apiParam.name());
}
私有字符串emptyToNull(字符串str){
返回StringUtils.hasText(str)?str:null;
}
}

希望能有所帮助。

一个更完整的解决方案,可以实际编译,并考虑ApiParam type属性或模型数据类型属性中的类型设置:

@Component
@Order(SwaggerPluginSupport.SWAGGER_PLUGIN_ORDER + 1000)
public class OverrideSwaggerApiParamTypeBuilder extends 
SwaggerExpandedParameterBuilder implements ExpandedParameterBuilderPlugin {

public OverrideSwaggerApiParamTypeBuilder(DescriptionResolver descriptions, EnumTypeDeterminer enumTypeDeterminer) {
    super(descriptions, enumTypeDeterminer);
}

@Override
public boolean supports(DocumentationType type) {
    return DocumentationType.SWAGGER_2 == type;
}

public void apply(ParameterExpansionContext context) {
    super.apply(context);
    Optional<ApiModelProperty> apiModelPropertyOptional = context.findAnnotation(ApiModelProperty.class);
    if (apiModelPropertyOptional.isPresent()) {
        if(!StringUtils.isAllEmpty(apiModelPropertyOptional.get().dataType())) {
            context.getParameterBuilder().modelRef(new ModelRef(apiModelPropertyOptional.get().dataType()));
        }
    }

    Optional<ApiParam> apiParamOptional = context.findAnnotation(ApiParam.class);
    if (apiParamOptional.isPresent()) {
        if(!StringUtils.isAllEmpty(apiParamOptional.get().type())) {
            context.getParameterBuilder().modelRef(new ModelRef(apiParamOptional.get().type()));
        }
    }

}
@组件
@订单(SwaggerPluginSupport.SWAGGER\u PLUGIN\u订单+1000)
公共类重写WaggerapiParamTypeBuilder扩展
SwaggerExpandedParameterBuilder实现ExpandedParameterBuilderPlugin{
public重写WaggerapiParamTypeBuilder(DescriptionResolver描述,EnumTypeDeterminator EnumTypeDeterminator){
超级(描述、枚举类型确定器);
}
@凌驾
公共布尔支持(DocumentationType){
return DocumentationType.SWAGGER_2==type;
}
public void apply(参数expansioncontext){
super.apply(上下文);
可选apiModelPropertyOptional=context.findAnnotation(ApiModelProperty.class);
if(apiModelPropertyOptional.isPresent()){
如果(!StringUtils.isAllEmpty(apiModelPropertyOptional.get().dataType())){
context.getParameterBuilder().modelRef(新的modelRef(apiModelPropertyOptional.get().dataType());
}
}
可选apiParamOptional=context.findAnnotation(ApiParam.class);
if(apiParamOptional.isPresent()){
如果(!StringUtils.isAllEmpty(apiParamOptional.get().type())){
context.getParameterBuilder().modelRef(新的modelRef(apiParamOptional.get().type());
}
}
}

}

正如我所提到的,正在提取
@ApiParam
的某些部分(如
value
变成
description
,但其他则不是。
type
属性是可用的,否则我的代码将无法编译。从这里可以看到:最终这成功了,我对代码做了一些修改,使其更简单,并使用了
modelRef()
设置类型。我已更新我的问题以反映他的问题。
@Component
@Order(SwaggerPluginSupport.SWAGGER_PLUGIN_ORDER + 1000)
public class OverrideSwaggerApiParamTypeBuilder extends 
SwaggerExpandedParameterBuilder implements ExpandedParameterBuilderPlugin {

public OverrideSwaggerApiParamTypeBuilder(DescriptionResolver descriptions, EnumTypeDeterminer enumTypeDeterminer) {
    super(descriptions, enumTypeDeterminer);
}

@Override
public boolean supports(DocumentationType type) {
    return DocumentationType.SWAGGER_2 == type;
}

public void apply(ParameterExpansionContext context) {
    super.apply(context);
    Optional<ApiModelProperty> apiModelPropertyOptional = context.findAnnotation(ApiModelProperty.class);
    if (apiModelPropertyOptional.isPresent()) {
        if(!StringUtils.isAllEmpty(apiModelPropertyOptional.get().dataType())) {
            context.getParameterBuilder().modelRef(new ModelRef(apiModelPropertyOptional.get().dataType()));
        }
    }

    Optional<ApiParam> apiParamOptional = context.findAnnotation(ApiParam.class);
    if (apiParamOptional.isPresent()) {
        if(!StringUtils.isAllEmpty(apiParamOptional.get().type())) {
            context.getParameterBuilder().modelRef(new ModelRef(apiParamOptional.get().type()));
        }
    }

}