@@ -11,13 +11,11 @@ Include the dependency to your project's pom.xml file:
1111
1212``` xml
1313<dependencies >
14- ...
15- <dependency >
16- <groupId >io.github.openfeign.form</groupId >
17- <artifactId >feign-form</artifactId >
18- <version >3.5.0</version >
19- </dependency >
20- ...
14+ <dependency >
15+ <groupId >io.github.openfeign.form</groupId >
16+ <artifactId >feign-form</artifactId >
17+ <version >3.5.0</version >
18+ </dependency >
2119</dependencies >
2220```
2321
@@ -27,31 +25,30 @@ Add `FormEncoder` to your `Feign.Builder` like so:
2725
2826``` java
2927SomeApi github = Feign . builder()
30- .encoder(new FormEncoder ())
31- .target(SomeApi . class, " http://api.some.org" );
28+ .encoder(new FormEncoder ())
29+ .target(SomeApi . class, " http://api.some.org" );
3230```
3331
3432Moreover, you can decorate the existing encoder, for example JsonEncoder like this:
3533
3634``` java
3735SomeApi github = Feign . builder()
38- .encoder(new FormEncoder (new JacksonEncoder ()))
39- .target(SomeApi . class, " http://api.some.org" );
36+ .encoder(new FormEncoder (new JacksonEncoder ()))
37+ .target(SomeApi . class, " http://api.some.org" );
4038```
4139
4240And use them together:
4341
4442``` java
4543interface SomeApi {
4644
47- @RequestLine (" POST /json" )
48- @Headers (" Content-Type: application/json" )
49- void json (Dto dto );
50-
51- @RequestLine (" POST /form" )
52- @Headers (" Content-Type: application/x-www-form-urlencoded" )
53- void from (@Param (" field1" ) String field1 , @Param (" field2" ) String field2 );
45+ @RequestLine (" POST /json" )
46+ @Headers (" Content-Type: application/json" )
47+ void json (Dto dto );
5448
49+ @RequestLine (" POST /form" )
50+ @Headers (" Content-Type: application/x-www-form-urlencoded" )
51+ void from (@Param (" field1" ) String field1 , @Param (" field2" ) String field2 );
5552}
5653```
5754
@@ -62,14 +59,21 @@ You can specify two types of encoding forms by `Content-Type` header.
6259``` java
6360interface SomeApi {
6461
65- ...
62+ @RequestLine (" POST /authorization" )
63+ @Headers (" Content-Type: application/x-www-form-urlencoded" )
64+ void authorization (@Param (" email" ) String email , @Param (" password" ) String password );
65+
66+ // Group all parameters within a POJO
67+ @RequestLine (" POST /user" )
68+ @Headers (" Content-Type: application/x-www-form-urlencoded" )
69+ void addUser (User user );
6670
67- @RequestLine (" POST /authorization" )
68- @Headers (" Content-Type: application/x-www-form-urlencoded" )
69- void authorization (@Param (" email" ) String email , @Param (" password" ) String password );
71+ class User {
7072
71- ...
73+ Integer id;
7274
75+ String name;
76+ }
7377}
7478```
7579
@@ -78,38 +82,47 @@ interface SomeApi {
7882``` java
7983interface SomeApi {
8084
81- ...
85+ // File parameter
86+ @RequestLine (" POST /send_photo" )
87+ @Headers (" Content-Type: multipart/form-data" )
88+ void sendPhoto (@Param (" is_public" ) Boolean isPublic , @Param (" photo" ) File photo );
89+
90+ // byte[] parameter
91+ @RequestLine (" POST /send_photo" )
92+ @Headers (" Content-Type: multipart/form-data" )
93+ void sendPhoto (@Param (" is_public" ) Boolean isPublic , @Param (" photo" ) byte [] photo );
8294
83- // File parameter
84- @RequestLine (" POST /send_photo" )
85- @Headers (" Content-Type: multipart/form-data" )
86- void sendPhoto (@Param (" is_public" ) Boolean isPublic , @Param (" photo" ) File photo );
95+ // FormData parameter
96+ @RequestLine (" POST /send_photo" )
97+ @Headers (" Content-Type: multipart/form-data" )
98+ void sendPhoto (@Param (" is_public" ) Boolean isPublic , @Param (" photo" ) FormData photo );
8799
88- // byte[] parameter
89- @RequestLine (" POST /send_photo" )
90- @Headers (" Content-Type: multipart/form-data" )
91- void sendPhoto (@Param ( " is_public " ) Boolean isPublic , @Param ( " photo " ) byte [] photo );
100+ // Group all parameters within a POJO
101+ @RequestLine (" POST /send_photo" )
102+ @Headers (" Content-Type: multipart/form-data" )
103+ void sendPhoto (MyPojo pojo );
92104
93- // FormData parameter
94- @RequestLine (" POST /send_photo" )
95- @Headers (" Content-Type: multipart/form-data" )
96- void sendPhoto (@Param (" is_public" ) Boolean isPublic , @Param (" photo" ) FormData photo );
97- ...
105+ class MyPojo {
98106
107+ Boolean isPublic;
108+
109+ File photo;
110+ }
99111}
100112```
101113
102114In the example above, the ` sendPhoto ` method uses the ` photo ` parameter using three different supported types.
103115
104- * ` File ` will use the File's extension to detect the ` Content-Type ` .
105- * ` byte[] ` will use ` application/octet-stream ` as ` Content-Type ` .
106- * ` FormData ` will use the ` FormData ` 's ` Content-Type ` and ` fileName ` .
116+ * ` File ` will use the File's extension to detect the ` Content-Type ` ;
117+ * ` byte[] ` will use ` application/octet-stream ` as ` Content-Type ` ;
118+ * ` FormData ` will use the ` FormData ` 's ` Content-Type ` and ` fileName ` ;
119+ * Client's custom POJO for grouping parameters (including types above).
107120
108121` FormData ` is custom object that wraps a ` byte[] ` and defines a ` Content-Type ` and ` fileName ` like this:
109122
110123``` java
111- FormData formData = new FormData (" image/png" , " filename.png" , myDataAsByteArray);
112- someApi. sendPhoto(true , formData);
124+ FormData formData = new FormData (" image/png" , " filename.png" , myDataAsByteArray);
125+ someApi. sendPhoto(true , formData);
113126```
114127
115128### Spring MultipartFile and Spring Cloud Netflix @FeignClient support
@@ -120,51 +133,55 @@ Include the dependencies to your project's pom.xml file:
120133
121134``` xml
122135<dependencies >
123- ...
124- <dependency >
125- <groupId >io.github.openfeign.form</groupId >
126- <artifactId >feign-form</artifactId >
127- <version >3.5.0</version >
128- </dependency >
129- <dependency >
130- <groupId >io.github.openfeign.form</groupId >
131- <artifactId >feign-form-spring</artifactId >
132- <version >3.5.0</version >
133- </dependency >
134- ...
136+ <dependency >
137+ <groupId >io.github.openfeign.form</groupId >
138+ <artifactId >feign-form</artifactId >
139+ <version >3.5.0</version >
140+ </dependency >
141+ <dependency >
142+ <groupId >io.github.openfeign.form</groupId >
143+ <artifactId >feign-form-spring</artifactId >
144+ <version >3.5.0</version >
145+ </dependency >
135146</dependencies >
136147```
137148
138149``` java
139- @FeignClient (name = " file-upload-service" , configuration = FileUploadServiceClient . MultipartSupportConfig . class)
150+ @FeignClient (
151+ name = " file-upload-service" ,
152+ configuration = FileUploadServiceClient . MultipartSupportConfig . class
153+ )
140154public interface FileUploadServiceClient extends IFileUploadServiceClient {
141155
142- public class MultipartSupportConfig {
156+ public class MultipartSupportConfig {
143157
144- @Autowired
145- private ObjectFactory<HttpMessageConverters > messageConverters;
158+ @Autowired
159+ private ObjectFactory<HttpMessageConverters > messageConverters;
146160
147- @Bean
148- public Encoder feignFormEncoder () {
149- return new SpringFormEncoder (new SpringEncoder (messageConverters));
150- }
161+ @Bean
162+ public Encoder feignFormEncoder () {
163+ return new SpringFormEncoder (new SpringEncoder (messageConverters));
151164 }
165+ }
152166}
153167```
154168
155169Or, if you don't need Spring's standard encoder:
156170
157171``` java
158- @FeignClient (name = " file-upload-service" , configuration = FileUploadServiceClient . MultipartSupportConfig . class)
172+ @FeignClient (
173+ name = " file-upload-service" ,
174+ configuration = FileUploadServiceClient . MultipartSupportConfig . class
175+ )
159176public interface FileUploadServiceClient extends IFileUploadServiceClient {
160177
161- public class MultipartSupportConfig {
178+ public class MultipartSupportConfig {
162179
163- @Bean
164- public Encoder feignFormEncoder () {
165- return new SpringFormEncoder ();
166- }
180+ @Bean
181+ public Encoder feignFormEncoder () {
182+ return new SpringFormEncoder ();
167183 }
184+ }
168185}
169186```
170187
@@ -174,38 +191,41 @@ To use this feature, include SpringManyMultipartFilesReader in the list of messa
174191
175192``` java
176193@FeignClient (
177- name = " ${feign.name}" ,
178- url = " ${feign.url}"
179- configuration = DownloadClient . ClientConfiguration . class)
194+ name = " ${feign.name}" ,
195+ url = " ${feign.url}"
196+ configuration = DownloadClient . ClientConfiguration . class
197+ )
180198public interface DownloadClient {
181199
182- @RequestMapping (
183- value = " /multipart/download/{fileId}" ,
184- method = GET )
185- MultipartFile [] download (@PathVariable (" fileId" ) String fileId );
200+ @RequestMapping (" /multipart/download/{fileId}" )
201+ MultipartFile [] download (@PathVariable (" fileId" ) String fileId );
202+
203+ class ClientConfiguration {
204+
205+ @Autowired
206+ private ObjectFactory<HttpMessageConverters > messageConverters;
207+
208+ @Bean
209+ public Decoder feignDecoder () {
210+ List<HttpMessageConverter<?> > springConverters =
211+ messageConverters. getObject(). getConverters();
186212
187- class ClientConfiguration {
213+ List<HttpMessageConverter<?> > decoderConverters =
214+ new ArrayList<HttpMessageConverter<?> > (springConverters. size() + 1 ;
188215
189- @Autowired
190- private ObjectFactory< HttpMessageConverters > messageConverters ;
216+ decoderConverters . addAll(springConverters);
217+ decoderConverters . add( new SpringManyMultipartFilesReader ( 4096 )) ;
191218
192- @Bean
193- public Decoder feignDecoder () {
194- final List<HttpMessageConverter<?> > springConverters = messageConverters. getObject(). getConverters();
195- final List<HttpMessageConverter<?> > decoderConverters
196- = new ArrayList<HttpMessageConverter<?> > (springConverters. size() + 1 );
219+ HttpMessageConverters httpMessageConverters = new HttpMessageConverters (decoderConverters);
197220
198- decoderConverters. addAll(springConverters);
199- decoderConverters. add(new SpringManyMultipartFilesReader (4096 ));
200- final HttpMessageConverters httpMessageConverters = new HttpMessageConverters (decoderConverters);
221+ return new SpringDecoder (new ObjectFactory<HttpMessageConverters > () {
201222
202- return new SpringDecoder (new ObjectFactory<HttpMessageConverters > () {
203- @Override
204- public HttpMessageConverters getObject () {
205- return httpMessageConverters;
206- }
207- });
223+ @Override
224+ public HttpMessageConverters getObject () {
225+ return httpMessageConverters;
208226 }
227+ });
209228 }
229+ }
210230}
211231```
0 commit comments