OpenAPI 3.0:@Operation的parameters参数致文档参数重复的解决咨询
问题
刚接触OpenAPI 3.0,正在学习基于Javadoc的各类注解,暂未找到相关专属教程。在@Operation注解中使用parameters参数时,生成的文档会重复显示参数——同时展示parameters中定义的参数与RESTful方法签名中的参数。个人更倾向于通过parameters参数来优化代码结构,想咨询:是否可通过某种配置实现仅使用@Operation的parameters参数,避免参数重复?
依赖配置
<!-- https://mvnrepository.com/artifact/io.swagger.core.v3/swagger-annotations-jakarta --> <dependency> <groupId>io.swagger.core.v3</groupId> <artifactId>swagger-annotations-jakarta</artifactId> <version>${io.swagger.core.v3.version}</version> </dependency> <!-- https://mvnrepository.com/artifact/io.swagger.core.v3/swagger-jaxrs2-jakarta --> <dependency> <groupId>io.swagger.core.v3</groupId> <artifactId>swagger-jaxrs2-jakarta</artifactId> <version>${io.swagger.core.v3.version}</version> </dependency> <!-- https://mvnrepository.com/artifact/io.swagger.core.v3/swagger-jaxrs2-servlet-initializer-jakarta --> <dependency> <groupId>io.swagger.core.v3</groupId> <artifactId>swagger-jaxrs2-servlet-initializer-jakarta</artifactId> <version>${io.swagger.core.v3.version}</version> </dependency>
两种实现方式示例
#1 在@Operation注解中使用parameters:
@Operation( summary="Get some data", description="Get all data available", parameters= { @Parameter( name="issuer", description="Doc issuer", required=true, example="1", in=ParameterIn.PATH, allowEmptyValue=false, schema=@Schema( type="integer", implementation=Integer.class, pattern="\\d+" ) ) }, responses={ @ApiResponse(responseCode="200", description="All available data", content={ @Content(mediaType=MediaType.APPLICATION_JSON), @Content(mediaType=MediaType.APPLICATION_XML) } ) } ) @GET @Path("issuer/{issuer:\\d+}") public Response findByIssuer(@PathParam("issuer") Integer issuer) { ... }
#2 在方法签名中使用@Parameter:
@Operation( summary="Get some data", description="Get all data available", responses={ @ApiResponse(responseCode="200", description="All available data", content={ @Content(mediaType=MediaType.APPLICATION_JSON), @Content(mediaType=MediaType.APPLICATION_XML) } ) } ) @GET @Path("issuer/{issuer:\\d+}") public Response findByIssuer( @Parameter(name="issuer", description="Get all data available" ) @PathParam("issuer") Integer issuer) { ... }
使用方式1时,服务文档中issuer参数重复显示;使用方式2时仅显示一次。但在多参数(如@PathParam/@QueryParam)场景下,方式2代码会变得杂乱,故希望使用方式1并解决参数重复问题。
解决方案
方案1:全局禁用方法参数自动解析(推荐)
如果使用的是Swagger Core版本≥2.2.0,直接通过配置禁用方法参数的自动解析,Swagger只会读取@Operation中定义的parameters。
可以在项目中添加swagger-config.yaml配置文件:
swagger: jaxrs: reader: ignore-method-parameters: true
或者通过系统属性设置:-Dswagger.jaxrs.reader.ignore-method-parameters=true。
方案2:标记单个方法参数为隐藏
在方法签名的参数上添加@Parameter(hidden = true),Swagger会忽略该参数的自动解析,只保留@Operation中定义的参数:
@Operation( // 保持原有parameters配置不变 ) @GET @Path("issuer/{issuer:\\d+}") public Response findByIssuer(@Parameter(hidden = true) @PathParam("issuer") Integer issuer) { ... }
这种方式适合仅需处理少数参数的场景。
方案3:自定义OpenAPI配置
通过实现OpenApiConfigurationCustomizer接口,手动清理重复参数:
import io.swagger.v3.oas.integration.OpenApiConfigurationCustomizer; import io.swagger.v3.oas.models.OpenAPI; import io.swagger.v3.oas.models.parameters.Parameter; import jakarta.ws.rs.ApplicationPath; import jakarta.ws.rs.core.Application; import java.util.Set; import java.util.stream.Collectors; @ApplicationPath("/api") public class CustomSwaggerApp extends Application implements OpenApiConfigurationCustomizer { @Override public void customize(OpenAPI openApi) { openApi.getPaths().values().forEach(pathItem -> { pathItem.readOperations().forEach(operation -> { // 获取@Operation中定义的参数名称集合 Set<String> definedParamNames = operation.getParameters().stream() .map(Parameter::getName) .collect(Collectors.toSet()); // 移除不在集合中的参数(即方法签名解析出来的重复参数) operation.getParameters().removeIf(param -> !definedParamNames.contains(param.getName())); }); }); } }
这种方式适合需要更灵活控制参数解析逻辑的场景。
内容的提问来源于stack exchange,提问作者Romualdo Rubens de Freitas

