javaspring-webfluxinputstreamfileinputstreamspring-webclient

Using Spring WebClient to upload a file as inputstream


Im using a webflux springboot application. where i have an API which takes a FilePart as input and then convert it to inputstream since i make a filetype check using Tika library and then upload this file to API using webclient i get 500 internal server error from the server

MultipartBodyBuilder builder = new MultipartBodyBuilder();
        builder.part("file", new InputStreamResource(inputStream)).header("Content-Disposition",
            "form-data; name=file; filename="test.txt");
return webClient
            .post()
            .uri("https://example.com/file")
            .contentType(MediaType.MULTIPART_FORM_DATA)
            .body(BodyInserters.fromMultipartData(multipartBody))
            .retrieve()
            .bodyToMono(String.class);

but if i skip converting the file to input stream the webclient works

return webClient.post()
                .uri("https://example.com/file")
                .contentType(MediaType.MULTIPART_FORM_DATA)
                .body(BodyInserters.fromMultipartData("file", filePart))
                .retrieve()
                .bodyToMono(String.class);

Solution

  • the internal server error you are getting is not actually related to WebClient, but you have two other issues in your code:

    1. String Concatenation in the Content-Disposition header, because of the double quotes around text.txt.
    2. second is that you didn't build the MultiPartBodyBuilder, and multipartBody used in BodyInserters.fromMultipartData(multipartBody) is not initialized.

    the WORKING code:

    MultipartBodyBuilder builder = new MultipartBodyBuilder();
    builder.part("file", new InputStreamResource(inputStream))
       .header("Content-Disposition", "form-data; name=\"file\"; 
    filename=\"test.txt\"");
    
    //building MultipartBodyBuilder and assigning it to multipartBody
    MultiValueMap<String, HttpEntity<?>> multipartBody = builder.build();
    
    return webClient`enter code here`
        .post()
        .uri("https://example.com/file")
        .contentType(MediaType.MULTIPART_FORM_DATA)
        .body(BodyInserters.fromMultipartData(multipartBody))
        .retrieve()
        .bodyToMono(String.class);
    

    notice the use of \" instead of " in around file and test.txt in Content-Disposition header String.