Feign在Github上開源了一個項目,可以更加方便的利用Feign進行文件傳輸和多參數傳輸。項目地址:https://github.com/OpenFeign/feign-form這篇文章就結合官方的Test總結下用法。
使用前我們下載pom中引入相關包,其中核心的部分如下所示:
<dependency>
<groupId>io.github.openfeign.form</groupId>
<artifactId>feign-form</artifactId>
<version>xxx</version>
</dependency>
<dependency>
<groupId>io.github.openfeign.form</groupId>
<artifactId>feign-form-spring</artifactId>
<version>xxx</version>
</dependency>
最新的版本,大家自己從:http://mvnrepository.com/ 檢索吧!
文件上傳
服務提供方
在web層的核心代碼如下所示:
@RestController
public class Server {
// MultipartFile必須使用 @RequestPart 進行修飾
// consume為: MULTIPART_FORM_DATA_VALUE,表明只接收FormData這個類型的數據
@RequestMapping(
value = "/multipart/upload1/{folder}",
method = POST,
consumes = MULTIPART_FORM_DATA_VALUE)
public String upload1(@PathVariable("folder") String folder,
@RequestPart MultipartFile file,
@RequestParam(value = "message", required = false) String message) {
return new String(file.getBytes()) + ':' + message + ':' + folder;
}
該代碼中有需要注意:
- 必須是Post類型的請求。
- 文件形參必須用@RequestPara MultipartFile file來修飾,其中 @RequestParat和MultipartFile必不可少。
- 形參中有3類參數,實際開發中可以改為對文件的描述信息
- PathVariable 是在URL占位中的參數
- RequestPart 是修改文件的參數
- RequestParam 是URL中?后面的參數。
服務調用方Feign接口
@FeignClient(
name = "multipart-support-service",
url = "http://localhost:8080",
configuration = Client.ClientConfiguration.class
)
public interface Client {
//處理多個參數的時候,必須指定:consumes = MULTIPART_FORM_DATA_VALUE
@RequestMapping(
value = "/multipart/upload1/{folder}",
method = POST,
consumes = MULTIPART_FORM_DATA_VALUE
)
String upload1(@PathVariable("folder") String folder,
@RequestPart MultipartFile file,
@RequestParam(value = "message", required = false) String message);
/**
* 配置類
*/
class ClientConfiguration {
/**
* 此處注入的是: ObjectFactory<HttpMessageConverters>
*/
@Autowired
private ObjectFactory<HttpMessageConverters> messageConverters;
@Bean
public Encoder feignEncoder() {
return new SpringFormEncoder(new SpringEncoder(messageConverters));
}
}
}
方法中需要注意幾個細節:
- FeignClient中的描述信息中,指定了配置信息為:Client.ClientConfiguration
- 請求參數形參注意事項同上所示,此處不再贅述。
我們來看看配置信息:
/**
* 配置類
*/
class ClientConfiguration {
/**
* 此處注入的是: ObjectFactory<HttpMessageConverters>
*/
@Autowired
private ObjectFactory<HttpMessageConverters> messageConverters;
@Bean
public Encoder feignEncoder() {
return new SpringFormEncoder(new SpringEncoder(messageConverters));
}
}
這部分代碼表述的就是:獲取已有的HttpMessageConvert然后將其包裹下,外層增加自己的編碼器SpringFormEncoder。該寫法是針對某個Feign Client的配置。
如果你的客戶端所有的都需要這個配置,那么請通過如下方式配置:
@Configuration
public class MultipartSupportConfig {
@Autowired
private ObjectFactory<HttpMessageConverters> messageConverters;
@Bean
@Primary
@Scope("prototype")
public Encoder feignEncoder() {
return new SpringFormEncoder(new SpringEncoder(messageConverters));
}
}
該配置中也是細節滿滿:
- 通過@Primary修飾,優先注入我們聲明的。
- 通過 @Scope("prototype")每次使用都構建一個。
思考下為什么不做為單例了?
這樣客戶端調用的時候就成了,很簡單吧!
復雜參數傳遞
實際開發中,我們可能會通過多種方式進行傳輸傳遞,這里就構建一個非常復雜的方式,服務提供方web層接口如下:
@RestController
public class Server {
@RequestMapping(path = "/multipart/upload4/{id}",
method = POST)
public String upload4(@PathVariable("id") String id,
@RequestBody Map<String, Object> map,
@RequestParam String userName) {
return userName + ':' + id + ':' + map.size();
}
}
這個接口中包含了3類參數:
- @PathVariable
- @RequestBody
- @RequestParam
Feign的客戶端接口如何寫了?
@FeignClient(
name = "multipart-support-service",
url = "http://localhost:8080",
configuration = Client.ClientConfiguration.class
)
public interface Client {
// 傳輸的不是文件
// 因為傳輸的參數有個map所以必須指定類型為 json
// 經過測試發現:注釋 produces = APPLICATION_JSON_VALUE 是沒有問題的
@RequestMapping(
path = "/multipart/upload4/{id}",
method = POST,
produces = APPLICATION_JSON_VALUE
)
String upload4(@PathVariable("id") String id,
@RequestBody Map<Object, Object> map,
@RequestParam("userName") String userName);
/**
* 配置類,同上
*/
class ClientConfiguration {
/**
* 此處注入的是: ObjectFactory<HttpMessageConverters>
*/
@Autowired
private ObjectFactory<HttpMessageConverters> messageConverters;
@Bean
public Encoder feignEncoder() {
return new SpringFormEncoder(new SpringEncoder(messageConverters));
}
}
}
只需要包裹下編碼器即可,很簡單吧!
總結
上述用法都是來自:https://github.com/OpenFeign/feign-form 這個官方的pom中。
更多用法,可以參考這個pom中的Test。
