Swagger-UI调用@ModelAttribute绑定multipart表单POJO返回null如何解决
问题解答
关于Swagger对@ModelAttribute的支持性
Swagger(包括SpringDoc OpenAPI 3、旧版Swagger2)本身完全支持@ModelAttribute注解的参数绑定,你遇到的参数为null问题由以下两个原因导致:
- 你的接口
consumes同时配置了application/json和multipart/form-data两种格式,Swagger UI默认会优先选择JSON作为请求格式,而JSON格式本身无法传输二进制文件,且@ModelAttribute默认不会解析JSON请求体的参数,自然所有字段取值为null - 部分2.9.x及更早版本的Swagger2存在解析缺陷,无法正确识别
@ModelAttribute修饰的包含MultipartFile字段的POJO,会错误将参数识别为JSON请求体。
可落地解决方案
方案1:调整consumes配置(优先推荐)
由于文件上传只能通过multipart/form-data格式实现,JSON格式天生不支持传输二进制文件,你可以直接移除接口中application/json的consumes配置,不需要替换@ModelAttribute注解,即可实现Swagger UI正常调用:
@PostMapping(value = "/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) public ResponseEntity<UploadDocuments> upload(@ModelAttribute ExtractionRequest extractionRequest) throws MOException { System.out.println(extractionRequest.getFiles()); System.out.println(extractionRequest.getDocumentType()); // 其余业务逻辑 }
调整后Swagger UI会自动识别为form-data类型请求,生成对应的文件上传、文本参数填写区域,参数绑定逻辑和Postman调用完全一致。
方案2:兼容多请求格式的配置
如果你确实需要保留对JSON格式请求的支持(仅适用于无文件上传的纯文本参数请求场景),可以给POJO字段添加OpenAPI注解强制指定参数类型,同时调用时在Swagger UI手动选择multipart/form-data作为请求格式即可:
以SpringDoc OpenAPI 3为例,修改POJO如下:
@Data public class ExtractionRequest implements Serializable { private static final long serialVersionUID = -1594766216036852930L; @Parameter(description = "上传的文档文件列表", content = @Content(mediaType = MediaType.MULTIPART_FORM_DATA_VALUE)) public List<MultipartFile> files; @NotBlank @Parameter(description = "文档类型编码") private String documentType; }
额外说明
不需要替换@ModelAttribute注解,该注解本身就支持同时绑定文件、字符串等不同类型的参数到同一个POJO对象,完全符合你的业务限制要求。
内容的提问来源于stack exchange,提问作者Happs
相关产品推荐
相关产品推荐

