Spring Boot接口Swagger传空串而非null致400错误解决需求
Spring Boot接口处理非必填MultipartFile时Swagger传空字符串的问题
问题场景
用Spring Boot开发REST API,接口通过@ModelAttribute接收DTO,其中包含3个普通参数和一个非必填的MultipartFile类型字段logotipo。当不传递文件时,Swagger会发送空字符串"",而接口期望接收MultipartFile类型,导致触发400 Bad Request错误。尝试在@Schema中设置默认值无效。
现有代码
接口方法
@Operation(tags = {"Contato"}, summary = "Atualizar contato", description = "Atualiza os dados de um contato ativo a partir do ID.") @PutMapping(path = "/atualizarContato",consumes = MediaType.MULTIPART_FORM_DATA_VALUE) public ResponseDto atualizarContato(@ModelAttribute ContatoUpdateDto contatoDto) throws IOException { // 业务逻辑实现 }
DTO类
package app.api.denuncia.Dto; import org.springframework.web.multipart.MultipartFile; import io.swagger.v3.oas.annotations.media.Schema; public class ContatoUpdateDto { @Schema(description = "O identificador (ID) do contato", required = true) private int id; @Schema(description = "O nome do contato", required = true) private String nome; @Schema(description = "O número de telefone do contato") private String telefone; @Schema(description = "Imagem que representa o contato") private MultipartFile logotipo; // 构造方法、Getter和Setter省略 }
解决方案
方案1:修正DTO字段的Swagger注解
在logotipo字段的@Schema注解中明确标记为非必填且可空,告诉Swagger该字段可以为null,不传递时不发送空字符串:
@Schema(description = "Imagem que representa o contato", required = false, nullable = true) private MultipartFile logotipo;
方案2:自定义参数解析器处理空字符串转null
如果Swagger仍发送空字符串,添加自定义参数解析器,将空字符串对应的MultipartFile转换为null:
@Component public class MultipartFileNullResolver implements HandlerMethodArgumentResolver { @Override public boolean supportsParameter(MethodParameter parameter) { return MultipartFile.class.isAssignableFrom(parameter.getParameterType()); } @Override public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception { MultipartHttpServletRequest request = webRequest.getNativeRequest(MultipartHttpServletRequest.class); String paramName = parameter.getParameterName(); MultipartFile file = request.getFile(paramName); // 若请求中存在该参数的空字符串,返回null if (file == null && request.getParameter(paramName) != null && request.getParameter(paramName).isEmpty()) { return null; } return file; } }
然后在Web配置类中注册该解析器:
@Configuration public class WebConfig implements WebMvcConfigurer { @Autowired private MultipartFileNullResolver multipartFileNullResolver; @Override public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) { resolvers.add(multipartFileNullResolver); } }
方案3:接口方法内手动处理
在接口方法中检查logotipo是否为无效的空文件,手动设置为null:
public ResponseDto atualizarContato(@ModelAttribute ContatoUpdateDto contatoDto) throws IOException { // 处理空文件转null if (contatoDto.getLogotipo() != null && contatoDto.getLogotipo().isEmpty()) { contatoDto.setLogotipo(null); } // 后续业务逻辑 }
方案4:配置Swagger UI不提交空文件参数
通过Swagger配置,让非必填的文件字段在未选择文件时不提交该参数,Spring会自动将字段设为null:
@Configuration public class OpenApiConfig { @Bean public OpenAPI customOpenAPI() { return new OpenAPI() .info(new Info().title("Contato API").version("1.0")); } @Bean public UiConfiguration uiConfiguration() { return UiConfigurationBuilder.builder() // 其他配置 .build(); } }
同时确保DTO字段的@Schema(required = false),Swagger UI会将该字段标记为可选,未选择文件时不会提交空字符串。
内容的提问来源于stack exchange,提问作者Elisângela Rosa
相关产品推荐
相关产品推荐

