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类参数,实际开发中可以改为对文件的描述信息
@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));
}
}
}
方法中需要注意几个细节:
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。