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

使用oatpp 1.3.0的TemporaryFile实现多部分大文件上传遇边界错误求助

问题分析与修复方案

核心问题

  1. Swagger端点配置错误:ENDPOINT_INFO中addConsumes的模板参数使用不当,导致Swagger无法生成带正确boundary的请求头。
  2. 代码逻辑冗余:重复创建PartList实例,且第一次创建时因缺少boundary直接抛出异常。
  3. 请求头解析依赖:PartList构造必须依赖包含boundary参数的Content-Type头,若请求头缺失则触发异常。

修复步骤

1. 修正Swagger端点配置

移除addConsumes的多余模板参数,让Swagger自动识别多部分表单类型,生成正确的请求头格式:

ENDPOINT_INFO(upload) {
    info->summary = "Upload";
    info->addResponse<Object<CommandResponseDto>>(Status::CODE_200, "application/json");
    // 直接指定媒体类型,无需模板参数
    info->addConsumes("multipart/form-data");
}

2. 修复代码逻辑与异常处理

删除重复的PartList创建代码,确保仅在try块内创建一次并复用,完成请求体传输后再处理分片:

ENDPOINT("POST", "upload",
         upload,
         REQUEST(std::shared_ptr<IncomingRequest>, request)) {
    namespace mp = oatpp::web::mime::multipart;
    try {
        // 从请求头解析boundary,创建PartList实例
        mp::PartList multipart(request->getHeaders());
        mp::Reader multipartReader(&multipart);

        // 设置临时目录存储分片文件
        multipartReader.setDefaultPartReader(
            mp::createTemporaryFilePartReader("/tmp"));

        // 将请求体传输到Reader,完成分片写入
        request->transferBody(&multipartReader);

        // 遍历所有分片进行合并处理
        auto parts = multipart.getAllParts();
        for (auto& p : parts) {
            logger_->info("Multipart: Part name={}, filename={}",
                          p->getName()->c_str(), 
                          p->getFilename() ? p->getFilename()->c_str() : "无文件名");
            
            // 此处添加分片合并逻辑示例:
            // std::ofstream finalFile("merged_file.bin", std::ios::app | std::ios::binary);
            // std::ifstream tempPart(p->getInFile()->getPath()->c_str(), std::ios::binary);
            // finalFile << tempPart.rdbuf();
        }

        return createResponse("OK");
    } catch (const std::exception& e) {
        logger_->error("Error handling multipart upload: {}", e.what());
        return create_error_response(e.what());
    }
}

3. 额外注意事项

  • 测试时使用Swagger UI:修正配置后,Swagger会自动生成带boundary的Content-Type头,无需手动设置。
  • 临时文件生命周期:createTemporaryFilePartReader创建的临时文件会在PartList销毁时自动删除,若需保留可自定义PartReader。
  • 客户端异常提示:若客户端未发送带boundary的请求,需在错误响应中提示使用标准多部分表单格式。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 15:20:22