Home > Software engineering >  Spring WebClient BodyInserters.fromResource() changes content-type?
Spring WebClient BodyInserters.fromResource() changes content-type?

Time:03-12

I'm new to Spring's WebClient. I'm trying to post the contents of a file using the content-type application/octet-stream. Initially I loaded the contents of the file into a byte array and used .bodyValue() to add it. This works perfectly.

byte[] data;
 
// read file into byte array here ...

FileUploadResponse resp = client.post().uri(uri)
     .contentType(MediaType.APPLICATION_OCTET_STREAM)
     .accept(MediaType.APPLICATION_JSON)
     .bodyValue(data)  // From byte[]
     .retrieve()
     .bodyToMono(FileUploadResponse.class)
     .block();

Obviously loading the entire contents of the file into memory is not great. So I did a little searching and it looks like I need to use a "from resource body inserter." So I changed the code to this:

// Use a Spring FileSystemResource that will be used to insert the data into the body.
FileSystemResource resource = new FileSystemResource(localFilename);

// Create a web client
WebClient client = WebClient.create();

FileUploadResponse resp = client.post().uri(uri)
        .contentType(MediaType.APPLICATION_OCTET_STREAM)
        .accept(MediaType.APPLICATION_JSON)
        .body(BodyInserters.fromResource(resource)) // From file resource
        .retrieve()
        .bodyToMono(FileUploadResponse.class)
        .block();

Now the content-type is being sent as "text/plain" (see below)

POST /fileupload
accept-encoding: gzip
user-agent: ReactorNetty/0.9.11.RELEASE
host: localhost:8080
Content-Type: text/plain
Accept: application/json

What am I doing wrong? Does the BodyInserters.fromResource() always override the content-type to "text/plain"? Is there some other way I should be doing this?

Thank you!

CodePudding user response:

It happens because of the specific handling of the application/octet-stream in ResourceHttpMessageWriter. It tries to detect mime type by file extension.

You could use InputStreamResource instead to keep application/octet-stream

var resource = new InputStreamResource(new FileInputStream(localFilename));
  • Related