Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

File Upload Using Feign - multipart/form-data

I'm trying to accomplish a multipart file upload using feign, but I can't seem to find a good example of it anywhere. I essentially want the HTTP request to turn out similar to this:

...
Content-Type: multipart/form-data; boundary=AaB03x

--AaB03x
Content-Disposition: form-data; name="name"

Larry
--AaB03x
   Content-Disposition: form-data; name="file"; filename="file1.txt"
   Content-Type: text/plain

... contents of file1.txt ...
--AaB03x--

Or even...

------fGsKo01aQ1qXn2C
Content-Disposition: form-data; name="file"; filename="file.doc"
Content-Type: application/octet-stream

... binary data ...

------fGsKo01aQ1qXn2C--

Do I need to manually build the request body, including generating the multipart boundaries? That seems a bit excessive considering everything else this client can do.

like image 747
btidwell Avatar asked Jul 31 '15 18:07

btidwell


4 Answers

MBozic solution not full, you will also need to enable an Encoder for this:


public class FeignConfig {
     
    @Autowired
    private ObjectFactory<HttpMessageConverters> messageConverters;

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

@FeignClient(name = "file", url = "http://localhost:8080", configuration = FeignConfig.class)
public interface UploadClient {
    @PostMapping(value = "/upload-file", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    String fileUpload(@RequestPart(value = "file") MultipartFile file);
}
like image 199
Emerson Micu Avatar answered Oct 04 '22 02:10

Emerson Micu


For spring boot 2 and spring-cloud-starter-openfeign use this code:

@PostMapping(value="/upload", consumes = "multipart/form-data" )
QtiPackageBasicInfo upload(@RequestPart("package") MultipartFile package);

You need to change @RequestParam to @RequestPart in the feign client call to make it work, and also add consumes to the @PostMapping.

like image 33
MBozic Avatar answered Oct 04 '22 02:10

MBozic


No, you don't. You just need to define a kind of proxy interface method, specify the content-type as: multipart/form-data and other info such as parameters required by the remote API. Here is an example:

public interface FileUploadResource {

    @RequestLine("POST /upload")
    @Headers("Content-Type: multipart/form-data")
    Response uploadFile(@Param("name") String name, @Param("file") File file);

} 

The completed example can be found here: File Uploading with Open Feign

like image 27
NangSaigon Avatar answered Oct 04 '22 02:10

NangSaigon


If you are already using Spring Web, you can try my implementation of a Feign Encoder that is able to create Multipart requests. It can send a single file, an array of files alongwith one or more additional JSON payloads. Here is my test project. If you don't use Spring, you can refactor the code by changing the encodeRequest method in FeignSpringFormEncoder.

like image 41
pcan Avatar answered Oct 04 '22 03:10

pcan