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

Dropwizard+swagger-core 2.2.6:如何标记x-www-form-urlencoded请求体为必填

问题场景与诉求

在使用Dropwizard结合swagger-core与swagger-jaxrs2 2.2.6开发接口时,编写了如下POST接口,通过@NotNull标记@FormParam参数为必填:

@POST
@Path("/do-something")
@Consumes({ MediaType.APPLICATION_FORM_URLENCODED })
@Operation(summary = "Does something")
public void doSomething(@NotNull @FormParam("what") String what) {
  // ...
}

但生成的Swagger文档中,仅在schema内标记了参数必填,requestBody整体未添加"required": true字段:

"/do-something" : {
  "post" : {
    "summary" : "Does something",
    "operationId" : "doSomething",
    "requestBody" : {

      /* missing here: "required": true */

      "content" : {
        "application/x-www-form-urlencoded" : {
          "schema" : {
            "required" : [ "what" ],
            "type" : "object",
            "properties" : {
              "what" : {
                "type" : "string"
              }
            }
          }
        }
      }
    },
    "responses" : { /* ... */ }
  }
},

这导致生成的TypeScript客户端允许省略请求体。但直接使用@RequestBody(required = true)注解会禁用参数自动检测,需要一种无需手动重写大量文档的解决办法。

解决方法

可以通过实现Swagger的OperationCustomizer接口,自动为包含必填参数的form-urlencoded请求设置requestBody的required属性:

  1. 自定义OperationCustomizer实现类:
import io.swagger.v3.core.converter.ModelConverterContext;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.Operation;
import io.swagger.v3.oas.models.media.Schema;
import io.swagger.v3.oas.models.parameters.RequestBody;
import io.swagger.v3.oas.models.responses.ApiResponses;
import io.swagger.v3.jaxrs2.OperationCustomizer;
import jakarta.ws.rs.container.ResourceInfo;
import jakarta.ws.rs.core.MediaType;
import java.util.Map;

public class FormRequestBodyRequiredCustomizer implements OperationCustomizer {

    @Override
    public Operation customize(Operation operation, ApiResponses apiResponses, OpenAPI openAPI, ResourceInfo resourceInfo, ModelConverterContext modelConverterContext) {
        RequestBody requestBody = operation.getRequestBody();
        if (requestBody != null) {
            // 检查是否是form-urlencoded类型的请求体
            Schema<?> formSchema = requestBody.getContent().get(MediaType.APPLICATION_FORM_URLENCODED)?.getSchema();
            if (formSchema != null) {
                // 如果schema存在必填参数,设置requestBody为required
                if (formSchema.getRequired() != null && !formSchema.getRequired().isEmpty()) {
                    requestBody.setRequired(true);
                }
            }
        }
        return operation;
    }
}
  1. 在Dropwizard的swagger配置中注册该自定义类:
// 在你的Dropwizard Application类的run方法中
@Override
public void run(YourConfiguration config, Environment env) {
    // 初始化swagger配置
    OpenAPI oas = new OpenAPI();
    SwaggerConfiguration swaggerConfig = new SwaggerConfiguration()
            .openAPI(oas)
            .resourcePackages(Set.of("your.package.name"))
            // 添加自定义的OperationCustomizer
            .operationCustomizers(Set.of(new FormRequestBodyRequiredCustomizer()));

    SwaggerUiConfiguration uiConfig = SwaggerUiConfiguration.builder().build();
    SwaggerBundleConfiguration bundleConfig = new SwaggerBundleConfiguration()
            .swaggerConfiguration(swaggerConfig)
            .swaggerUiConfiguration(uiConfig);

    new SwaggerBundle().run(bundleConfig, env);
}

这个自定义逻辑会自动扫描所有form-urlencoded类型的请求体,当对应的schema中存在必填参数时,自动将requestBody的required属性设为true,无需手动为每个接口添加@RequestBody注解,也不会破坏参数的自动检测逻辑。

内容的提问来源于stack exchange,提问作者Sebastian vom Meer

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 13:43:04