3
votes

I have client role microservice and server role microservice on Spring Cloud I have FeignClient bean on client microservicewith method accepting MultipartFile like this

@RequestMapping(value = {"/files"}, consumes = {"multipart/form-data"}, method = {RequestMethod.POST}
)
ResponseEntity uploadFile(@RequestBody MultipartFile file, @RequestParam("someParam") String someParam)

With usage of these two libraries: "io.github.openfeign.form:feign-form:3.0.3" "io.github.openfeign.form:feign-form-spring:3.0.3"

It is possible to configure feign for file uploads like this:

@Configuration
public class FeignConfiguration {

    @Autowired
    private ObjectFactory<HttpMessageConverters> messageConverters;

    @Bean
    public Encoder feignFormEncoder() {
        return new SpringFormEncoder(new SpringEncoder(messageConverters));
    }
}

and then reference the configuration from feign client like this:

@FeignClient(name = "destination-microservice-id", configuration = FeignConfiguration.class)

What should be the implementation of MultipartFile interface and how to create the instance to proceed the call from client microservice? When using MockMultipartFile implementation from Spring that is intended for testing purpose it allmost works. File is transfered, "someParam" value is also transfered. However content type and file name that are other fields of MultipartFile instance are not passed to the server.

Any ideas how to approach it?

1
Another implementation besides the MockMultipartFile is the CommonsMultipartFile class from spring - Mihaita Tinta
I have seen this implementation but it looks like something created for server side processing - Lukas S

1 Answers

3
votes

To call your feign client interface from your client microservice app, you could use something like this.

public void uploadFile(File file) {

    DiskFileItem fileItem = (DiskFileItem) new DiskFileItemFactory().createItem("file",
                                                MediaType.TEXT_PLAIN_VALUE, true, file.getName());

    try (InputStream input = new FileInputStream(file); OutputStream os = fileItem.getOutputStream()) {
        IOUtils.copy(input, os);
    } catch (Exception e) {
        throw new IllegalArgumentException("Invalid file: " + e, e);
    }

    MultipartFile multipartFile = new CommonsMultipartFile(fileItem);
    feignClient.uploadFile(multipartFile);
}

The DiskFileItem class is from the commons-fileupload library.Hope it helps.