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属性:
- 自定义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; } }
- 在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
相关产品推荐
相关产品推荐

