我正在尝试上传文件并将文本参数从 Java 客户端发送到 Python FastAPI 服务器。但是,我遇到了错误:在索引 4 处未找到边界字符 54。
我使用的 CURL 命令运行良好(邮差也):
curl -X POST \
-F "files=@/path/to/my/file" \
-F "param1=someValue" \
"http://localhost:8000/my_endpoint"
而且我的Python测试也成功了:
with open(input_file, "rb") as file:
response = client.post(
url="/my_endpoint",
data={"param1": "someValue"},
files=[("files", file)],
)
但是,我的 Java 实现似乎引起了问题。
FastAPI 服务器日志显示:
Did not find boundary character 121 at index 4
INFO: 127.0.0.1:60803 - "POST /transcribe HTTP/1.1" 400 Bad Request
这是我的Java代码
String boundary = UUID.randomUUID().toString();
HttpRequest httpRequest = HttpRequest.newBuilder()
.uri(URI.create(myUrl))
.header("Content-Type", "multipart/form-data; boundary=" + boundary)
.version(HttpClient.Version.HTTP_1_1)
.POST(HttpRequest.BodyPublishers.ofByteArray(createFormData(multipartFile)))
.build();
HttpResponse<String> resp = httpClient.send(httpRequest, HttpResponse.BodyHandlers.ofString());
创建表单数据的方法如下:
private byte[] createFormData(MultipartFile multipartFile) throws IOException {
HttpEntity httpEntity = createMultipartFile(multipartFile);
return getByteArray(httpEntity);
}
public HttpEntity createMultipartFile(MultipartFile multipartFile) {
try {
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
byte[] fileBytes = multipartFile.getBytes();
ByteArrayBody fileBody = new ByteArrayBody(fileBytes, ContentType.DEFAULT_BINARY, multipartFile.getName());
builder.addPart("files", fileBody);
builder.addPart("param1", new StringBody("someValue", ContentType.TEXT_PLAIN));
// Set the multipart entity to the request
return builder.build();
} catch (IOException e) {
throw new MyException(e);
}
}
public byte[] getByteArray(HttpEntity multipartEntity) {
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
multipartEntity.writeTo(baos);
return baos.toByteArray();
} catch (IOException e) {
throw new MyException(e);
}
}
有趣的是,当我删除该行时:
.header("Content-Type", "multipart/form-data; boundary=" + boundary)
服务器返回 422 Unprocessable Entity 错误。
如何解决此问题并成功将多部分表单数据从 Java 客户端发送到 FastAPI 服务器?
使用Spring的RestTemplate:
MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
body.add("files", multipartFile.getResource());
body.add("param1","someValue");
HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(body, headers);
ResponseEntity<String> resp = restTemplate.postForEntity(myUrl, requestEntity, String.class);