如何用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
相关产品推荐
相关产品推荐

