Home > Enterprise >  Spring - Calling REST API with Webclient with an image(multipart) file
Spring - Calling REST API with Webclient with an image(multipart) file

Time:08-24

I am having a use case to call a REST API and I am using webclient to call the REST API. As part of the call I have to pass an image/pdf. I call an internal method downloadFile() which gives me the image of File type. To transmit this file I am doing the following

File file = downloadFile(key);
InputStream stream = new FileInputStream(file);
MultipartFile multipartFile = new MockMultipartFile(file.getName(), file.getName(), "multipart/form-data", stream);
JsonNode response = Objects.requireNonNull(webClient.post()
                .uri("/api/{groupId}/images", uriBuilder -> uriBuilder
                    .queryParam("referenceId", referenceId)
                    .build(Map.of("groupId", 1000)))
                .header(HttpHeaders.AUTHORIZATION, "Bearer "   auth2Service.getAccessToken())
                .bodyValue(multipartFile)
                .retrieve()
                .bodyToMono(JsonNode.class)
                .block());

But I am getting this error, "Type definition error: [simple type, class java.io.ByteArrayInputStream]; nested exception is com.fasterxml.jackson.databind.exc.InvalidDefinitionException: No serializer found for class java.io.ByteArrayInputStream and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) (through reference chain: org.springframework.mock.web.MockMultipartFile["inputStream"])"

Can someone please help if I am sending the image correctly? And if yes, what is the above issue?

CodePudding user response:

The way in which you are sending the image through webflux is not proper. You can do something like this,

File file = downloadFile(key);
InputStream stream = new FileInputStream(file);
MultipartFile multipartFile = new MockMultipartFile(file.getName(), file.getName(), "multipart/form-data", stream);

MultipartBodyBuilder builder = new MultipartBodyBuilder();
builder.part("file", multipartFile.getResource());
var payloadFile = builder.build();


JsonNode response = Objects.requireNonNull(webClient.post()
                .uri("/api/{groupId}/images", uriBuilder -> uriBuilder
                    .queryParam("referenceId", referenceId)
                    .build(Map.of("groupId", 1000)))
                .header(HttpHeaders.AUTHORIZATION, "Bearer "   auth2Service.getAccessToken())
                .body(BodyInserters.fromMultipartData(payloadFile))
                .retrieve()
                .bodyToMono(JsonNode.class)
                .block());

Here "file" in the builder variable is the key that contains the actual file that you want to send. On the receiving end, you have to use the same key to catch the file.

CodePudding user response:

Thanks Akhil. This worked. However a small change that I did is

File file = downloadFile(key);
MultipartBodyBuilder builder = new MultipartBodyBuilder();
builder.part("file", new FileSystemResource(file));

I don't need to have the MockMultipartFile dependency in the above case.

Thanks

  • Related