关键字:Spring Cloud, FeignClient,MultipartFile
场景
假设网站后台(ServiceA)、文件服务(ServiceB)与报表服务(ServiceC)分别是三个不同的微服务,需要满足如下两个场景:
- 用户通过ServiceA上传头像到ServiceB。
- ServiceC将生成的Excel二进制文件上传到ServiceB。
分析
J2EE架构网站一般通过Form Data上传,然后通过MultipartFile来接收文件。FeignClient本身是不支持MultipartFile,需要通过额外的配置使其支持。Spring Cloud实现起来非常简单。
步骤
Step 1.配置依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
一般这个依赖是现成的。
Step 2.注册SpringFormEncoder
@Configuration
public class FeignMultipartSupportConfig {
@Autowired
private ObjectFactory<HttpMessageConverters> messageConverters;
@Bean
@Primary
@Scope("prototype")
public Encoder multipartFormEncoder() {
return new SpringFormEncoder(new SpringEncoder(messageConverters));
}
@Bean
public feign.Logger.Level multipartLoggerLevel() {
return feign.Logger.Level.FULL;
}
}
关于异常
class XXX is not a type supported by this encoder.
,请务必在FeignMultipartSupportConfig
中注入messageConverters!不要轻信百度出来的结果,使用Fein的原生注解前,不如先去看下源代码。
Step 3.配置FeignClient
@FeignClient(value = "file-system", configuration = FeignMultipartSupportConfig.class)
public interface FileSystemClient {
@PostMapping(value = "/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
Resp<?> upload(@RequestPart("file") MultipartFile file);
}
此处file-system
是服务提供者的名字,consumes请配置成MediaType.MULTIPART_FORM_DATA_VALUE
。
这样就可以解决场景一的需求,将文件从前端一直传递到文件服务器了。
如果是场景二,还需要下面这一步操作。
Step 4.封装MultipartFile参数
CommonsMultipartFile是MultipartFile的一个常用实现。
private MultipartFile getMultipartFile(File file) {
final DiskFileItem item = new DiskFileItem("file", MediaType.MULTIPART_FORM_DATA_VALUE, true, file.getName(), 100000000, file.getParentFile());
try {
OutputStream os = item.getOutputStream();
os.write(FileUtils.readFileToByteArray(file));
} catch (IOException e) {
e.printStackTrace(); // do nothing!
}
return new CommonsMultipartFile(item);
}
将一个File对象封装成MultipartFile参数,传递给FileSystemClient的upload方法即可。文件名等会自动做URLEncoder。
PS. Spring Cloud版本为Finchley.SR4,FileUtils来自Spring框架自带的Commons IO组件。
全文完!
网友评论