Search code examples
javahttpfastapimultipartform-data

Facing "Did not find boundary character" error when sending multipart form data from Java client to FastAPI server


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?


Solution

  • 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);