scala - 在 play-ws 多部分请求中发送 json 部分
问题描述
我正在实现一个外部 API,我需要发送一个与 JSON 元部件捆绑在一起的文件附件。
服务器不接受以下代码,因为 Play 硬编码DataPart
to的内容类型text/plain
,并且服务器期望application/json
val meta = Json.obj(
"name" -> s"Invoice ${invoiceNumber}.pdf",
"referenceType" -> "INVOICE",
"referenceId" -> 42
)
ws.url("{API-URL}")
.addHttpHeaders("Authorization" -> s"Bearer ${accessToken}")
.post(Source(DataPart("meta", meta.toString) :: FilePart("file", s"Invoice ${invoiceNumber}.pdf", Option("application/pdf"), FileIO.fromPath(file.toPath)) :: List()))
.map(res => {
logger.debug("Status: " + res.status)
logger.debug("JSON: " + res.json)
Right(invoiceNumber)
})
API 端点的示例 curl(我已经测试和验证)命令是:
curl -H "Authorization: Bearer {accessToken}" \
-F 'meta={"name": "Invoive 4.pdf", "referenceType": "INVOICE", "referenceId": 42 } \
;type=application/json' \
-F "file=@Invoice.pdf" \
'{API-URL}'
有没有一种简单的方法可以强制DataPart
使用不同的内容类型或使用不同的部分来更好地控制我发送的内容?
解决方案
我找到了解决问题的方法:
首先我创建一个临时文件来保存元数据
val meta = new File(s"/tmp/${UUID.randomUUID()}")
Files.write(meta.toPath, Json.obj(
"name" -> s"Invoice ${invoiceNumber}.pdf",
"referenceType" -> "INVOICE",
"referenceId" -> 42
).toString.getBytes)
FilePart
然后我在我的请求中使用了两个:
ws.url("{API-URL}")
.addHttpHeaders("Authorization" -> s"Bearer ${accessToken}")
.post(Source(FilePart("meta", "", Option("application/json"), FileIO.fromPath(meta.toPath)) :: FilePart("file", s"Invoice ${invoiceNumber}.pdf", Option("application/pdf"), FileIO.fromPath(file.toPath)) :: List()))
.map(res => {
logger.debug("Status: " + res.status)
logger.debug("JSON: " + res.json)
Right(invoiceNumber)
})
推荐阅读
- spring - 在 Liberty 中运行时 Spring Boot 服务未自动装配,但在 TomCat 中运行良好
- python - pandas 如何识别布尔索引中的目标列?
- c# - 在具有默认值的 UserControl 中绑定 DataContext
- r - 如何使用 ggplot 在同一个图上绘制多个列并带有图例
- tinymce - 根据用户光标的位置选择列表框的侦听器是什么?-插件
- typescript - “Promise”类型上不存在属性“密码”
' - css - 如何将反应网格中的滑出抽屉更改为固定位置
- javascript - JavaScript 何时不传递回调
- sql - 动态 SQL 查询循环记录并找到正确的类别
- python - 使用 LSL 的实时数据可视化任务