springfox-swagger2
2.7.0
のSpringBootプロジェクトがあり、次のコントローラーがあります。
@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
へのコンバーターが登録されています):
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
など)が使用されているのに、他の部分は使用されていない理由です。 't、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属性の「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タイププロパティまたはModeldataTypeプロパティの両方からのタイプの設定を考慮に入れるより完全なソリューション:
@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()));
}
}
}
}