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

Spring Boot控制器接收MultipartFile为null问题求助

解决应用A调用测试接口C时MultipartFile参数为null的问题

问题背景

应用A通过WebClient调用第三方接口B可正常工作,调用代码如下:

public static String invokeB(String requestJson) throws Exception
{
    String response;
    byte[] fileContent = requestJson.getBytes();
    WebClient myClient = someLogic;

    HttpHeaders parts = new HttpHeaders();
    parts.setContentType(MediaType.TEXT_PLAIN);

    ByteArrayResource byteArrayResource = new ByteArrayResource(fileContent);
    final HttpEntity<ByteArrayResource> partsEntity = new HttpEntity<>(byteArrayResource, parts);

    MultiValueMap<String, HttpEntity<?>> requestMap = new LinkedMultiValueMap<>();
    requestMap.add("datafile", partsEntity);

    response = myClient.post()
        .contentType(MediaType.MULTIPART_FORM_DATA)
        .header(HttpHeaders.AUTHORIZATION, "")
        .body(BodyInserters.fromMultipartData(requestMap))
        .retrieve()
        .bodyToMono(String.class)
        .block();
    return response;
}

现编写模拟接口B的测试接口C,当A调用C时请求可到达,但MultipartFile参数始终为null。无法修改应用A或接口B,仅能调整接口C的代码。当前C的控制器代码:

@RestController
public class WrapperController {

    @PostMapping(value = "/test")
    public String visionPlusTester(@RequestHeader(HttpHeaders.AUTHORIZATION) String authorization,
        @RequestBody(required = true) MultipartFile datafile,
        @RequestParam(value = "port", defaultValue = "1234", required = false) String port,
        @RequestParam(value = "url", defaultValue = "10.10.10.10", required = false) String url) {

        byte[] fileContent = datafile.getBytes();
        return "some JSON String";
    }
}

已尝试添加MultipartResolver Bean、将@RequestBody改为@RequestPart、配置spring.servlet.multipart.enabled=true,均无效。使用Postman测试C接口可正常工作,使用spring-boot-starter-parent 2.7.11版本。

问题原因

应用A发送的Multipart请求中,datafile对应的part是TEXT_PLAIN类型,且未设置filename属性。Spring MVC默认仅将带有filename的Multipart part解析为MultipartFile,Postman测试时会自动为文件part添加filename,因此可以正常解析,但应用A的请求不符合这个条件。

解决方案

修改接口C的控制器代码,直接接收datafile对应的HttpEntity,若业务需要MultipartFile则手动封装:

修改后的控制器代码

@RestController
public class WrapperController {

    @PostMapping(value = "/test", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public String visionPlusTester(@RequestHeader(HttpHeaders.AUTHORIZATION) String authorization,
                                   @RequestPart("datafile") HttpEntity<byte[]> datafileEntity,
                                   @RequestParam(value = "port", defaultValue = "1234", required = false) String port,
                                   @RequestParam(value = "url", defaultValue = "10.10.10.10", required = false) String url) throws IOException {
        // 手动封装MultipartFile,适配A请求无filename的情况
        MultipartFile datafile = new MockMultipartFile(
                "datafile",
                "",
                MediaType.TEXT_PLAIN_VALUE,
                datafileEntity.getBody()
        );

        byte[] fileContent = datafile.getBytes();
        return "some JSON String";
    }
}

关键修改点

  1. 明确指定consumes = MediaType.MULTIPART_FORM_DATA_VALUE,确保Spring MVC正确识别请求类型
  2. 使用@RequestPart("datafile") HttpEntity<byte[]>接收part内容,绕过MultipartFile对filename的强制要求
  3. 若业务依赖MultipartFile,用MockMultipartFile手动封装,第二个参数传空字符串匹配应用A的请求格式

内容的提问来源于stack exchange,提问作者Thiagarajan Ramanathan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 16:45:11