swagger @ApiParam 忽略某些属性
swagger @ApiParam ignores certain properties
我有一个 Spring 引导项目 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 来控制文档中显示的内容,这仅适用于注释的某些部分,而不是全部。
Id
class(它有一个从 String
到 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"
}]
我的问题(或者可能是错误报告)是:为什么使用了 @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
理想情况下,您需要将 @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 提供了 dataType() 来处理你提到的场景。
默认情况下,@ApiParam 属性 'name' 和 'type' 用于覆盖 API 方法中指定的参数名称和检测到的直接参数类型。当您在字段上使用 @ApiParam 时,类型和名称由字段的名称推导出来,并且不考虑其声明的类型和名称和类型的重写值。 (它看起来是在 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 类型 属性 或模型数据类型 属性:
的类型设置
@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()));
}
}
}
}
我有一个 Spring 引导项目 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 来控制文档中显示的内容,这仅适用于注释的某些部分,而不是全部。
Id
class(它有一个从 String
到 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"
}]
我的问题(或者可能是错误报告)是:为什么使用了 @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
理想情况下,您需要将 @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 提供了 dataType() 来处理你提到的场景。
默认情况下,@ApiParam 属性 'name' 和 'type' 用于覆盖 API 方法中指定的参数名称和检测到的直接参数类型。当您在字段上使用 @ApiParam 时,类型和名称由字段的名称推导出来,并且不考虑其声明的类型和名称和类型的重写值。 (它看起来是在 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 类型 属性 或模型数据类型 属性:
的类型设置@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()));
}
}
}
}