4

I would like to pass multipart file from one service to another.

Client --> Service1 --> Service2

This shows an error "500 internal server error, Current request is not a multipart request" when I pass the file from Service1 to Service2

Client --> Service2 when I send the file directly its working but not through Service1

I want to know what could be the reason, I guess I am missing some header parts when passing the multipart file as parameter.

Service2

@PostMapping(path="/upload")
public ResponseEntity<Properties> upload(@RequestParam("file") MultipartFile multiPart) {
    return saveFile(multiPart);
}

Service2-client

@FeignClient
(name="${feign.upload.serverId}", configuration = UploadServiceClientConfiguration.class, decode404 = true)
public interface UploadServiceClient {

    @PostMapping(path="/upload")
    ResponseEntity<Properties> upload(@RequestParam("file") MultipartFile multiPart);

    class UploadServiceClientConfiguration {
        @Value(value="${feign.upload.user}")
        String user;
        @Value(value="${feign.upload.password}")
        String password;
        @Bean
        public BasicAuthRequestInterceptor basicAuthRequestInterceptor() {
            return new BasicAuthRequestInterceptor(user, password);
        }
    }
}

Service1

@Autowired
UploadServiceClient uploadSvcClient;
@PostMapping(path="/upload")
public ResponseEntity<Properties> uploadAttachment(@RequestParam("file") MultipartFile file) {
    return uploadSvcClient.upload(file);
}

2 Answers2

3

At last able to solve the communication issue to the another service using the post File upload spring cloud feign client

I have changed the FeignClient parameter type from

@RequestParam("file") MultipartFile mFile

to

@RequestPart("file") MultiValueMap file.

FeignClient Signature

@PostMapping(value="/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
        ResponseEntity<Properties> upload(@RequestHeader(name=UID,required=false) String uid, @RequestPart("file") MultiValueMap<String, Object> file);

Service1 Implementation

@PostMapping(path="/upload")
    public ResponseEntity<Properties> uploadAttachment(@RequestHeader(IRSConsts.UID) String uid, @RequestParam("file") MultipartFile mFile) {
        MultiValueMap<String, Object> multiValueMap = new LinkedMultiValueMap<>();
        ByteArrayResource contentsAsResource = null;
        try {
            contentsAsResource = new ByteArrayResource(mFile.getBytes()) {
                @Override
                public String getFilename() {
                    return mFile.getOriginalFilename();
                }
            };
        } catch (IOException e) {
            e.printStackTrace();
        }
        multiValueMap.add("file", contentsAsResource);
        return transSvcClient.upload(uid, multiValueMap);
    }

Service2 Implementation

@PostMapping(path = "/upload")
    @Headers("Content-Type: multipart/form-data")
    public ResponseEntity<Properties> upload(@RequestHeader(name = UID, required = false) String uid,
            @RequestPart("file") MultipartFile multiPart) {
        //Save Attachment.
    }
0

Perhaps you need a header indicating your request is multipart. Does this answer solve your issue? What is required is a header annotation:

@PostMapping(path="/upload")
@Headers("Content-Type: multipart/form-data")
ResponseEntity<Properties> upload(@Param("file") MultipartFile multiPart);

This is just an assumption. Please, give it a try and let me know the result.

Stepan Tsybulski
  • 1,121
  • 8
  • 18
  • I tried this earlier and got the below error. feign.FeignException: status 400 reading UploadServiceClient #upload(String,MultipartFile); content: {"timestamp":"2020-01-09T19:01:44+0000","status":400,"error":"Bad Request","message":"Required request part 'file' is not present","path":"/upload"} at feign.FeignException.errorStatus(FeignException.java:60) at feign.codec.ErrorDecoder$Default.decode(ErrorDecoder.java:89) at – Gopikrishna Mandapati Jan 09 '20 at 19:03
  • ah, I found the difference, please try to use `@Param` indeed of `@RequestParam`. I have updated my answer – Stepan Tsybulski Jan 09 '20 at 19:09
  • No, it still shows the same error. feign.FeignException: status 400 reading UploadServiceClient#upload(String,MultipartFile); content: {"timestamp":"2020-01-09T19:21:20+0000","status":400,"error":"Bad Request","message":"Required request part 'file' is not present","path":"/upload"} – Gopikrishna Mandapati Jan 09 '20 at 19:24
  • I think I am passing multipart object as it is. I think I have to wrap it and assigned to the "file" parameter but I do not know how to do it. If you know please help me. – Gopikrishna Mandapati Jan 09 '20 at 19:29
  • I believe you do everything right. Let's give it a new try. Read this answer https://stackoverflow.com/a/58770206/5178057. It tells you have to use `@RequestPart` instead. Because based on the response, you're getting 400 telling you the service can't find just this `file` part in the request. – Stepan Tsybulski Jan 09 '20 at 19:44
  • Still getting the same error? Ok, I will tell you a trick. Try to use Netcat then https://www.computerhope.com/unix/nc.htm. You need to run `nc -lk 9000` to have running server on port 9000. Then you can pass your request from Service 1 to Service 2 which will forward it to `localhost:9000` then you can analyse what exactly is in your request and figure out what is missing there. – Stepan Tsybulski Jan 09 '20 at 20:31