swagger @ApiParam игнорирует определенные свойства

у меня есть проект Spring Boot с 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 class, и это работает только для некоторых частей аннотации, но не для всех. The Id класс (который имеет зарегистрированный конвертер из String to Id):

public class Id {

  @ApiParam(value = "This is the description", defaultValue = "1f1f1f",required = true, name = "someId", type = "string")
  private final Long id;

  public Id(Long id) {
    this.id = id;
  }

  public Long getId() {
    return id;
  }
}

теперь Swagger JSON возвращены выглядит следующим образом:

"parameters":[{
  "name":"id",
  "in":"query",
  "description":"This is the description",
  "required":true,
  "type":"integer",
  "default":"1f1f1f",
  "format":"int64"
}]

мой вопрос (или, возможно, ошибка report) является: почему некоторые части @ApiParam аннотация (как value, defaultValue и required), но другие нет, как name и type? Почему кажется, что я не могу изменить name или type здесь? Для моего конкретного случая использования последний-тот, который я хотел бы изменить на string.

обновление

я решил добавить следующий компонент с помощью skadya.

@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();
    }
  }
}

авторы springfox чувствуют это может быть ошибка: https://github.com/springfox/springfox/issues/2107

3 ответов


по умолчанию атрибут @ApiParam "name" и "type" используются для переопределения имени параметра и обнаруженного типа прямых параметров, указанных в методе API. При использовании @ApiParam в поле Тип и имя выводятся по имени поля, а его объявленный тип и переопределенное значение для name и type не учитываются. (Он выглядит по дизайну в springfox, вы можете посмотреть на реализацию springfox.documentation.swagger.readers.parameter.SwaggerExpandedParameterBuilder)

Если вы все еще хотите изменить это поведение, вы можете зарегистрировать пользовательская реализация springfox.documentation.spi.service.ExpandedParameterBuilderPlugin интерлейс.

, например,

@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;
    }
}

надеюсь, что это помогает.


в идеале нужно использовать @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 "";

не уверен, есть ли атрибут type, но ниже приведен способ работы с типами:

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 и не могу найти атрибут "type" в @ApiParam, тогда как я вижу, что вы используете "type" с этим. Поэтому убедитесь, что он доступен для использования. Я также упомянул, что @ApiModelProperty предоставляет dataType () для обработки сценария, о котором вы упомянули.