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

如何用Apache Camel构造带files键的multipart/form-data上传至Strapi?

问题

Strapi REST API要求上传文件时使用multipart/form-data格式,且文件必须对应名为files的键。我尝试通过Apache Camel(Karavan创建,jbang camel运行)构造等效于JavaScript FormData的请求,路由配置如下:

- route:
    id: route-cdce
    nodePrefixId: route-126
    from:
      id: from-b77e
      uri: timer
      parameters:
        timerName: start
        repeatCount: "1"
        delay: "1000"
        fixedRate: false
        period: "1000"
      steps:
        - pollEnrich:
            id: pollEnrich-a5ff
            expression:
              constant:
                id: constant-6f3a
                expression: file:testimages?noop=true&readLock=none&fileName=example.jpg
            timeout: 5000
        - setHeader:
            id: setHeader-6071
            name: Authorization
            expression:
              constant:
                id: constant-32a3
                expression: >-
                  Bearer
                  d3ff178a3013ecc1747e9726f2ef0c0cbd5d8b7da5835d1a0edca58c2f3719547c69ad828012e3d864272aa1f657f80b63b499a00db12c385505e62a97ceea2d1d7898cf9759e3c09a30b5f26ff12a0a02b0ecedeb1a25b23dab25f1dbe18ca74ece699b2e9b50155f51131cad705c3b67207824da490dd49926d48c75b73cde
        - marshal:
            id: marshal-e5a3
            mimeMultipart:
              id: mimeMultipart-810e
              multipartSubType: form-data
        - to:
            id: to-ee85
            uri: http
            parameters:
              httpMethod: POST
              httpUri: localhost:1337/api/upload

运行命令camel run fileupload.yaml后,Strapi端点返回400错误,问题出在multipart请求中缺少绑定文件的files键。请问如何实现这一要求,或有其他方法构造符合要求的文件上传请求体?

解决方案

方法1:通过MimeMultipartData构建带files键的请求体

Camel默认的marshal mimeMultipart不会自动给文件设置表单字段名,需要先把文件封装成MimeMultipartData对象并指定字段名为files,再进行marshal。修改后的完整路由如下:

- route:
    id: route-cdce
    nodePrefixId: route-126
    from:
      id: from-b77e
      uri: timer
      parameters:
        timerName: start
        repeatCount: "1"
        delay: "1000"
        fixedRate: false
        period: "1000"
      steps:
        - pollEnrich:
            id: pollEnrich-a5ff
            expression:
              constant:
                id: constant-6f3a
                expression: file:testimages?noop=true&readLock=none&fileName=example.jpg
            timeout: 5000
        - process:
            id: process-build-formdata
            expression:
              simple: |
                var data = new org.apache.camel.component.mail.MimeMultipartData();
                var file = exchange.getIn().getBody(java.io.File.class);
                data.addAttachment("files", file.getName(), new javax.activation.FileDataSource(file));
                exchange.getIn().setBody(data);
        - setHeader:
            id: setHeader-6071
            name: Authorization
            expression:
              constant:
                id: constant-32a3
                expression: >-
                  Bearer
                  d3ff178a3013ecc1747e9726f2ef0c0cbd5d8b7da5835d1a0edca58c2f3719547c69ad828012e3d864272aa1f657f80b63b499a00db12c385505e62a97ceea2d1d7898cf9759e3c09a30b5f26ff12a0a02b0ecedeb1a25b23dab25f1dbe18ca74ece699b2e9b50155f51131cad705c3b67207824da490dd49926d48c75b73cde
        - marshal:
            id: marshal-e5a3
            mimeMultipart:
              id: mimeMultipart-810e
              multipartSubType: form-data
        - to:
            id: to-ee85
            uri: http
            parameters:
              httpMethod: POST
              httpUri: localhost:1337/api/upload

方法2:直接利用Camel HTTP组件的multipartFormData参数

这种方式更简洁,无需手动marshal,直接通过HTTP组件的内置支持实现:

- route:
    id: route-cdce
    nodePrefixId: route-126
    from:
      id: from-b77e
      uri: timer
      parameters:
        timerName: start
        repeatCount: "1"
        delay: "1000"
        fixedRate: false
        period: "1000"
      steps:
        - pollEnrich:
            id: pollEnrich-a5ff
            expression:
              constant:
                id: constant-6f3a
                expression: file:testimages?noop=true&readLock=none&fileName=example.jpg
            timeout: 5000
        - setHeader:
            id: setHeader-auth
            name: Authorization
            expression:
              constant:
                id: constant-32a3
                expression: >-
                  Bearer
                  d3ff178a3013ecc1747e9726f2ef0c0cbd5d8b7da5835d1a0edca58c2f3719547c69ad828012e3d864272aa1f657f80b63b499a00db12c385505e62a97ceea2d1d7898cf9759e3c09a30b5f26ff12a0a02b0ecedeb1a25b23dab25f1dbe18ca74ece699b2e9b50155f51131cad705c3b67207824da490dd49926d48c75b73cde
        - setHeader:
            id: setHeader-content-type
            name: Content-Type
            expression:
              constant: multipart/form-data
        - setHeader:
            id: setHeader-multipart
            name: CamelHttpMultipartFormData
            expression:
              simple: |
                var map = new java.util.HashMap();
                var file = exchange.getIn().getBody(java.io.File.class);
                map.put("files", file);
                map
        - to:
            id: to-ee85
            uri: http
            parameters:
              httpMethod: POST
              httpUri: localhost:1337/api/upload
              multipartFormData: "true"

关键说明

  • 两种方法的核心都是给文件绑定files表单字段名,匹配Strapi的API要求;
  • 方法1适合多文件上传或复杂表单场景,灵活性更高;方法2更简洁,适合单文件上传场景;
  • 确保文件路径file:testimages?noop=true&readLock=none&fileName=example.jpg正确指向目标文件,避免因文件找不到导致的隐性错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 07:06:06