2

我将使用 C++ 将文件上传到 Java Spring Boot Web 服务器。

我构建的协议如下所示(纯文本):

POST /gallery/multimedia/uploadvideo HTTP/1.1
Host: 192.168.0.133:8981
Content-Type: multipart/form-data; boundary=------boundary1804289383
Connection: keep-alive

--------boundary1804289383
Content-Type: video/mp4
Content-Disposition: form-data; name="file"; filename="1.mp4"
Content-Length: 948611
Content-Transfer-Encoding: 8bit

... binary video data here ...

--------boundary1804289383--

服务器端是Java spring boot server,接口定义如下:

@PostMapping("uploadvideo")
public ResultVo uploadVideo(@RequestParam("file") MultipartFile file);

发布文件时,服务器以代码 400 响应,并抱怨

所需的请求部分“文件”不存在

但是对于一个简单的 HTML 页面,文件上传成功,HTML 页面如下:

<html>
    <head></head>
    <body>
        <form id="form" enctype="multipart/form-data" method="post" 
            action="http://192.168.0.133:8981/gallery/multimedia/uploadvideo">
            <input id="file" name="file" type="file" />
            <input id="submit" value="submit" type="submit" />
        </form>
    </body>
</html>

我想念什么?


编辑:

我试过 Postman/Chrome 控制台/curl,所有这些工具只打印请求,如下所示:

# this is from curl
POST /gallery/multimedia/uploadvideo HTTP/1.1
User-Agent: curl/7.29.0
Host: 192.168.0.133:8981
Accept: */*
Content-Length: 187
Expect: 100-continue
Content-Type: multipart/form-data; boundary=----------------------------3c653d03b97f

我应该如何构建文件部分?有任何想法吗?

4

1 回答 1

1

首先,感谢@strupo 的建议。

通过打开--trace选项curl并查看输出日志文件,我终于解决了这个问题。

curl中,它通过几个数据包发布文件:

标题:

POST /gallery/multimedia/uploadvideo HTTP/1.1
User-Agent: curl/7.29.0
Host: 192.168.0.133:8981
Accept: */*
Content-Length: 13602  # you have to calculate content length first
Expect: 100-continue   # very important line
Content-Type: multipart/form-data; boundary=------3c653d03b97f

然后它等待服务器响应:

HTTP/1.1 100

在服务器响应代码 100 后,它发送数据内容,表单数据头先行:

--------3c653d03b97f
Content-Type: video/mp4
Content-Disposition: form-data; name="file"; filename="1.mp4"
Content-Length: 6640
Content-Transfer-Encoding: 8bit

然后是文件内容(在我的情况下,分配了一个大内存,从文件中读取并一次写入套接字),以及下一个文件。

最后,协议应该以边界线结束:

--------3c653d03b97f--

应该包括在标头之后发送的Content-Length所有字节。boundary应该以文件--部分为前缀。也\r\n应该注意无处不在。

于 2020-12-08T07:51:15.390 回答