FeignClient通过MultipartFile传递文件

2019-10-10  本文已影响0人  iakuil

关键字:Spring Cloud, FeignClient,MultipartFile

场景

假设网站后台(ServiceA)、文件服务(ServiceB)与报表服务(ServiceC)分别是三个不同的微服务,需要满足如下两个场景:

分析

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组件。

全文完!

上一篇下一篇

猜你喜欢

热点阅读