I'm trying to upload a file and send a text parameter from my Java client to a Python FastAPI server. However, I'm encountering an error: Did not find boundary character 54 at index 4.
I'm using a CURL command that works fine (Postman also):
curl -X POST \
-F "files=@/path/to/my/file" \
-F "param1=someValue" \
"http://localhost:8000/my_endpoint"
And my Python test is also successful:
with open(input_file, "rb") as file:
response = client.post(
url="/my_endpoint",
data={"param1": "someValue"},
files=[("files", file)],
)
However, my Java implementation seems to be causing issues.
FastAPI server logs show:
Did not find boundary character 121 at index 4
INFO: 127.0.0.1:60803 - "POST /transcribe HTTP/1.1" 400 Bad Request
This is my Java code
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());
Here's the method to create the form data:
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);
}
}
Interestingly, when I remove the line:
.header("Content-Type", "multipart/form-data; boundary=" + boundary)
The server returns a 422 Unprocessable Entity error.
How can I resolve this issue and successfully send multipart form data from my Java client to the FastAPI server?
use Spring's 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);