在一个请求中向 Spring Boot 发送文件和 JSON

很多人使用 Spring Boot 的 `@RequestPart` 来定义接收文件和 JSON 数据的端点。

然而,有些人在如何测试这样的端点方面遇到了困难,这就是我写这篇文章的原因。

⌨️ 使用@RequestPart的参数

通常,这种类型的端点如以下代码所示:

@RestController
@RequestMapping("/form-data")
public class FormDataController {
    @RequestMapping(value = "/json-and-file", method = POST)
    String jsonAndFile(@RequestPart User user,
                       @RequestPart MultipartFile file) {
       return "ok";
    }
}

我喜欢使用现代 Java,因此我使用记录而不是 Lombok 或手动编写 getter 和 setter。你呢?

public record User(String id, String name) {}

🤔 HTTP 状态代码 415

当使用 Yaak 等 HTTP 客户端时,通过 Multi-Part 提交参数后,我收到了 `415` 状态代码。真令人沮丧。

此时打开Spring Boot的控制台,你会看到一个警告,415状态码的意思是服务器不支持当前参数的媒体类型。

显然,user 字段是 JSON 字符串,而不是二进制,如果不手动设置内容类型,默认值就是错误的,因此我们只需要为 user 字段设置正确的内容类型即可。

不用担心,您的后端代码是正确的。

😀 解决方案:将文本字段的 Content-Type 设置为 application/json

Yaak 是一个非常干净的工具,我喜欢它!

但是面对这种复杂的情况时它无能为力,因为它不支持为多部分请求的文本字段设置内容类型。我试过 Paw、Bruno,它们也没用。

因此,我必须使用支持设置每个部分内容类型的专业工具,例如 Apidog 或 Postman。顺便说一句,我**只**发现这两个** GUI 工具可以做到这一点。

[2024 年 12 月 26 日更新] 在我发布这篇文章一周后,Bruno 发布了 v1.37.0 来支持此功能。他们读过这篇文章吗?

将`user`字段的`content-type`设置为`application/json`后,成功收到了Spring Boot响应的HTTP状态码`200`。

Received HTTP status code 200 with Apidog

问题解决了。🎉

如果你需要一个现代而专业的 API 工具,可以尝试 Apidog,这是一款新型的多功能工具。当然,Postman 也是一个不错的经典选择。

在这种情况下有人会使用 curl 吗?