Karate 1.3.1中Multipart/form-data JSON元数据传递异常求助
我们在项目中使用Karate 1.3.1测试一个接收文件与JSON元数据的API。编写Feature文件时使用multipart file和field传递参数,但报告中显示JSON元数据未正常携带;尝试GitHub Issue#1710中的方案仍无效。当前Karate请求返回200但响应为空{},而Postman与OkHttpClient调用该API可正常返回预期响应{id:123, status:'Done'}。
1. Karate Feature文件内容
Feature: 测试文件上传与元数据接口 Scenario: 上传文件并携带JSON元数据 Given url 'http://api.example.com/upload' And multipart file file = { read: 'test-file.txt', filename: 'test-file.txt' } And multipart field metadata = '{ "name": "test", "type": "text" }' When method post Then status 200 And match response == { id: '#number', status: 'Done' }
2. Karate请求响应详情
请求日志片段:
14:32:07.234 [main] INFO com.intuit.karate - [print] request: 1 > POST http://api.example.com/upload 1 > Content-Type: multipart/form-data; boundary=----KarateBoundary20240520143207232 1 > Content-Length: 1234 ------KarateBoundary20240520143207232 Content-Disposition: form-data; name="file"; filename="test-file.txt" Content-Type: text/plain [文件内容] ------KarateBoundary20240520143207232 Content-Disposition: form-data; name="metadata" { "name": "test", "type": "text" } ------KarateBoundary20240520143207232--响应结果:
1 < 200 1 < Content-Type: application/json {}
3. OkHttpClient实现代码
import okhttp3.*; import java.io.File; import java.io.IOException; public class ApiClient { public static void main(String[] args) throws IOException { OkHttpClient client = new OkHttpClient(); RequestBody requestBody = new MultipartBody.Builder() .setType(MultipartBody.FORM) .addFormDataPart("file", "test-file.txt", RequestBody.create(new File("test-file.txt"), MediaType.parse("text/plain"))) .addFormDataPart("metadata", "", RequestBody.create("{ \"name\": \"test\", \"type\": \"text\" }", MediaType.parse("application/json"))) .build(); Request request = new Request.Builder() .url("http://api.example.com/upload") .post(requestBody) .build(); try (Response response = client.newCall(request).execute()) { System.out.println(response.body().string()); // 输出: {"id":123,"status":"Done"} } } }
4. Postman生成的CURL命令
curl --location 'http://api.example.com/upload' \ --form 'file=@"/path/to/test-file.txt"' \ --form 'metadata="{\"name\": \"test\", \"type\": \"text\"}"'
排查思路与解决方案
指定JSON元数据的Content-Type
OkHttpClient中给metadata字段明确指定了application/json的MediaType,但Karate默认的multipart field Content-Type为text/plain,API可能仅识别application/json类型的元数据。修改Karate请求:And multipart field metadata = { value: '{ "name": "test", "type": "text" }', contentType: 'application/json' }校验请求格式一致性
开启Karate全量日志(配置logPrettyRequest=true),对比Postman/CURL生成的请求体,确认Karate的multipart边界、字段格式完全匹配。重点检查metadata字段的Content-Disposition和Content-Type头是否与工具生成的一致。改用multipart entity构造请求
若上述调整无效,尝试用multipart entity模拟OkHttpClient的请求构造方式:And multipart entity metadata = { value: '{ "name": "test", "type": "text" }', headers: { 'Content-Disposition': 'form-data; name="metadata"', 'Content-Type': 'application/json' } }升级Karate版本
Karate 1.3.1存在部分multipart请求的已知问题,建议升级到最新稳定版本(如1.4.1),验证是否修复相关bug。
内容的提问来源于stack exchange,提问作者automation.ninja.08

