You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 04:44:54