1

I am facing issues while sending MultipartFile from one service to another service.

API which I want to call is,

@PostMapping(value = "/posts/{postId}/comments/{commentId}/attachments")
@JsonView(CaseJsonView.ClientWithComments.class)
public ResponseEntity<?> createCommentAttachment(@PathVariable final String postId, @PathVariable final String commentId, @RequestParam("payload") final MultipartFile multipartFile, @RequestParam final String filename, final HttpServletRequest request) throws JsonProcessingException {
        try {
            FileUtils.writeByteArrayToFile(new File("C:\\CODE\\data\\" + filename), multipartFile.getBytes());
        } catch (IOException e) {
            e.printStackTrace();
        }
}

Here empty file is getting created when I call this API like below,

FeignClient

@FeignClient(name = "post-service")
public interface CommentClient {
    @RequestMapping(method = RequestMethod.POST, value = "/posts/{postId}/comments/{id}/attachments?filename={filename}", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    void storeCommentAttachmentPayload(@PathVariable("postId") String postId, @PathVariable("id") String id, @RequestBody MultiValueMap<String, Object> map, @PathVariable("filename") String filename);
}

And I am using this FeignClient like below,

public void sendAttachment() {
   //Adding only attachment code.
   // Here attachmentClient is some other FeignClient which is returning attachment.
   final Resource resource = attachmentClient.getAttachmentPayloadById(attachementId);
                final MultipartFile multipartFile = new InMemoryMultipartFile(filename, filename, 
   mimeType, IOUtils.toByteArray(resource.getInputStream()));
                final MultiValueMap<String, Object> map = new LinkedMultiValueMap<>();
                final ByteArrayResource byteArrayResource = new 
   ByteArrayResource(multipartFile.getBytes()) {
                    @Override
                    public String getFilename() {
                        return filename == null ? "" : filename;
                    }
                };
   map.add(PAYLOAD, byteArrayResource);
   commentService.storeCommentAttachmentPayload(postId commentId, map, filename);
}

Observation: Here my observation is that when I save files on disk from this method, all data is shown properly. But at the receiver end empty file is saved.

Another observation is that somehow byte array size is less at the receiver end than the sender end. Check the below image, https://i.stack.imgur.com/JjxEZ.png

One more observation is that text files are uploaded properly.

Brijesh Wani
  • 41
  • 1
  • 7

1 Answers1

0

So finally I found a solution to my problem. Instead of uploading a file using FeignClient, I am uploading using RestTemplate as below,

final List<ServiceInstance> postServiceInstances = discoveryClient.getInstances("post-service");
                if (postServiceInstances != null && !postServiceInstances.isEmpty()) {
                    final HttpEntity<MultiValueMap<String, Object>> entity = new HttpEntity<MultiValueMap<String, Object>>(multiValuMap);
                    final ResponseEntity<String> response = restTemplate
                            .postForEntity(postServiceInstances.get(0).getUri() + "/posts/" + postId + "/comments/" + commentId + "/attachments?filename=" + filename, entity, String.class);
                    if (response.getStatusCode() != HttpStatus.CREATED) {
                        throw new Exception("Exception from post-service: " + response.getStatusCode());
                    }
                } else {
                    throw new Exception("No post-service instance found");
                }

Not actually a perfect solution but it is solving my purpose. Also, I have added RestTemplate Interceptor which adds a token in my request.

Still, the solution using FeignClient will be appreciated.

Brijesh Wani
  • 41
  • 1
  • 7