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

Vert.x WebClient向Django REST Framework发送Multipart/form-data失败

问题排查:Vert.x客户端向Django REST Framework发送多表单数据失败

问题描述

我用Vert.x作为客户端,Django REST Framework作为服务端,尝试发送文档和表单数据。两端代码都已编写,但请求后服务端接收不到test参数,客户端返回“test attribute not found”,同时出现Netty版本格式错误。使用Postman调用该API可正常运行,需排查此问题。

服务端代码

@api_view(['POST'])
@parser_classes([MultiPartParser, FormParser])
def quick_indexing(request):
    
    data = request.data
    print(data)  # print the entire request data dictionary
    test_value = data.get("test")
    if test_value:
        return Response(f"test attribute value: {test_value}")
    else:
        return Response("test attribute not found")

客户端代码

Vertx vertx = Vertx.vertx();
WebClient client = WebClient.create(vertx);
Buffer file = vertx.fileSystem().readFileBlocking("C:/Users/houth/CIN Hassan.pdf");
MultipartForm form = MultipartForm.create()
    .attribute("test", "succed")
    .binaryFileUpload("file", "filename", file, "Application/pdf");
// Send a POST request with the file and form data
client.postAbs("http://localhost:8000/quick-indexing")
    .putHeader(String.valueOf(HttpHeaders.CONTENT_TYPE), "multipart/form-data")
    .sendMultipartForm(form,
        ar -> {
            if (ar.succeeded()) {
                // Handle the response
                HttpResponse<Buffer> response = ar.result();
                System.out.println("Status code: " + response.statusCode());
                System.out.println("Response body: " + response.bodyAsString());
            } else {
                // Handle the failure
                Throwable cause = ar.cause();
                System.err.println("Request failed: " + cause.getMessage());
            }
        });
System.out.println("end");

客户端运行结果

end
Status code: 200
Response body: "test attribute not found"
[ERROR] 2023-04-08 01:39:22.881  invalid version format: <!DOCTYPE
java.lang.IllegalArgumentException: invalid version format: <!DOCTYPE
    at io.netty.handler.codec.http.HttpVersion.<init>(HttpVersion.java:116) ~[netty-codec-http-4.1.86.Final.jar:4.1.86.Final]
    at io.netty.handler.codec.http.HttpVersion.valueOf(HttpVersion.java:78) ~[netty-codec-http-4.1.86.Final.jar:4.1.86.Final]

服务端运行结果

<QueryDict: {}>
[08/Apr/2023 01:39:22] "POST /quick-indexing HTTP/1.1" 200 26
[08/Apr/2023 01:39:22] code 400, message Bad request syntax ('9d')
[08/Apr/2023 01:39:22] "9d" 400 -

问题分析与解决方案

核心问题点

  1. 手动设置Content-Type破坏请求格式:
    Vert.x的sendMultipartForm方法会自动生成带boundary的Content-Type头(格式为multipart/form-data; boundary=xxx),手动设置multipart/form-data会覆盖这个自动生成的头,导致服务端无法识别表单数据的分隔边界,最终解析出空的request.data。

  2. Netty错误根源是请求格式异常:
    服务端日志中的"9d" 400 -是请求格式错误引发的后续异常,Netty的版本格式错误则是错误响应解析导致的,本质都源于请求头设置错误。

  3. MIME类型拼写不规范:
    binaryFileUpload中的"Application/pdf"应改为小写的"application/pdf",虽不是参数丢失的直接原因,但符合HTTP规范。

修正后的客户端代码

Vertx vertx = Vertx.vertx();
WebClient client = WebClient.create(vertx);
Buffer file = vertx.fileSystem().readFileBlocking("C:/Users/houth/CIN Hassan.pdf");
MultipartForm form = MultipartForm.create()
    .attribute("test", "succed")
    .binaryFileUpload("file", "filename", file, "application/pdf");
// Send a POST request with the file and form data
client.postAbs("http://localhost:8000/quick-indexing")
    .sendMultipartForm(form,
        ar -> {
            if (ar.succeeded()) {
                // Handle the response
                HttpResponse<Buffer> response = ar.result();
                System.out.println("Status code: " + response.statusCode());
                System.out.println("Response body: " + response.bodyAsString());
            } else {
                // Handle the failure
                Throwable cause = ar.cause();
                System.err.println("Request failed: " + cause.getMessage());
            }
        });
System.out.println("end");

修正说明

  • 移除手动设置Content-Type的代码,让Vert.x自动生成带boundary的正确请求头,服务端即可正常解析表单中的test参数和文件。
  • 修正MIME类型大小写,符合HTTP规范。

内容的提问来源于stack exchange,提问作者Hassan Outhami

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 16:47:49