使用Feign接口实现文件上传的解决方案

简介: 一般的情况下,后端有个微服务,暴露出一个文件上传的restful接口给前端,前端调用该接口获取上传后的链接以及oss key值完成上传。假设提供restful接口的这个服务叫做A,现在有个微服务B有个本地文件,需要将本地文件调用A文件文件上传接口上传到文件服务器,该如何做?

原文链接:使用Feign接口实现文件上传的解决方案

一般的情况下,后端有个微服务,暴露出一个文件上传的restful接口给前端,前端调用该接口获取上传后的链接以及oss key值完成上传。假设提供restful接口的这个服务叫做A,现在有个微服务B有个本地文件,需要将本地文件调用A文件文件上传接口上传到文件服务器,该如何做?

一般情况下,一个文件上传的restful接口如下所示:

@PostMapping("/upload")
public WrapperResult<UploadResult> uploadFile(@RequestParam("file") MultipartFile multipartFile){
   
    ......
}

那对应的Feign接口就如下所示

@PostMapping("/upload")
public WrapperResult<UploadResult> uploadFile(@RequestParam("file") MultipartFile multipartFile);

从直觉上来看,直接调用八成会出问题(笑),通过踩坑,我梳理了下后端调用Feign接口实现文件上传的改造点

1. 接口修改

一般的文件上传接口定义:

@PostMapping("/upload")
public WrapperResult<UploadResult> uploadFile(@RequestParam("file") MultipartFile multipartFile){
   
    ......
}

在Feign接口暴露出来的情况下,则不能再使用@RequestParam注解,应当使用@RequestPart注解,另外需要指定consumes类型为表单类型,否则会翻车。

修改后的接口如下

 @PostMapping(
    value = {
   "/upload"},
    consumes = {
   "multipart/form-data"}
)
UploadResult uploadFile(@RequestPart("file") @NotNull MultipartFile multipartFile);

这里注意两点:

  1. 使用@RequestPart注解替换掉@RequestParam注解
  2. 指定consumes类型为表单类型

2. Encoder修改

在springboot中,一般的Encoder定义如下

@Bean
@Primary
public Encoder feignEncoder() {
   
    HttpMessageConverter jacksonConverter = new MappingJackson2HttpMessageConverter(
            JsonUtils.getObjectMapper()
    );
    ObjectFactory<HttpMessageConverters> objectFactory = 
            () -> new HttpMessageConverters(jacksonConverter);
    return new SpringEncoder(objectFactory);
}

返回了一个SpringEncoder对象,这里需要返回一个SpringFormEncoder对象以支持Feign接口的表单功能,只需要将new SpringEncoder(objectFactory)修改为new SpringFormEncoder(new SpringEncoder(objectFactory))即可,修改后的代码如下

@Bean
@Primary
public Encoder feignEncoder() {
   
    HttpMessageConverter jacksonConverter = new MappingJackson2HttpMessageConverter(
            JsonUtils.getObjectMapper()
    );
    ObjectFactory<HttpMessageConverters> objectFactory = 
            () -> new HttpMessageConverters(jacksonConverter);
    return new SpringFormEncoder(new SpringEncoder(objectFactory));
}

3. 客户端调用修改

现在Feign接口长这个样子

 @PostMapping(
    value = {
   "/upload"},
    consumes = {
   "multipart/form-data"}
)
UploadResult uploadFile(@RequestPart("file") @NotNull MultipartFile multipartFile);

那我们Feign接口调用的时候就得构造MultipartFile对象,这里需要引入spring-test的依赖

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-test</artifactId>
</dependency>

然后代码这么写

FileInputStream fis = null;
try {
   
    Tika tika = new Tika();
    String mimeType = tika.detect(file);
    fis = new FileInputStream(file);
    MockMultipartFile mockMultipartFile = new MockMultipartFile(
            "file",
            file.getName(),
            mimeType,
            fis
    );

    UploadResult uploadResult = ossPublicApi.uploadFile(mockMultipartFile);
}catch(Exception e){
   
    ......
}

这里为了告知正确的媒体类型,引入了tika,关于tika,参考文章 使用tika获取文件的实际类型 引入

需要注意以下几点

  1. 需要引入spring-test,注意scope默认就行,不能为provided
  2. 需要引入tika,告知正确的媒体类型,否则上传到minio等文件服务器,在浏览器中打开图片、mp4视频等文件本来应当在浏览器打开的文件会变成自动下载

END.

目录
相关文章
Springboot接口同时支持GET和POST请求
Springboot接口同时支持GET和POST请求
839 0
|
Dubbo Java 数据库连接
利用FactoryBean接口实例化,来实现dubbo接口调用和mybatis接口调用
Java编程规范中声明,Java接口类是不能直接实例化的,但是我们在平时的开发中经常会遇到只声明接口就可以直接使用的。 eg: 1. Mybatis中只用使用`@MapperScan`声明要扫描的Mapper接口类就可以直接从Spring中获取使用,进行操作数据库 2. Dubbo中只要用Dubbo提供的`@Service`注解,同样可以直接从Spring中获取使用进行远程调用。
422 0
|
JSON 数据格式
Feign调用文件下载服务接口实例
Feign调用文件下载服务接口实例
1249 0
Feign调用文件下载服务接口实例
|
5月前
|
XML JSON Java
通过 Feign 进行文件上传
通过 Feign 进行文件上传
215 7
|
7月前
|
前端开发 Java Apache
JAVAEE框架技术之6-springMVC拦截器和文件上传功能
JAVAEE框架技术之6-springMVC拦截器和文件上传功能
105 0
JAVAEE框架技术之6-springMVC拦截器和文件上传功能
|
6月前
|
JSON Java API
技术笔记:springboot项目使用拦截器实现一个简单的网关请求透传
技术笔记:springboot项目使用拦截器实现一个简单的网关请求透传
245 0
|
6月前
|
Java 应用服务中间件 开发工具
基于Servlet的3.1以上注解方式完成上传功能。
基于Servlet的3.1以上注解方式完成上传功能。
29 0
|
7月前
|
JSON Java 关系型数据库
【Feign】 基于 Feign 远程调用、 自定义配置、性能优化、实现 Feign 最佳实践
【Feign】 基于 Feign 远程调用、 自定义配置、性能优化、实现 Feign 最佳实践
258 0
|
7月前
|
JSON Java API
Spring Boot 无侵入式 实现API接口统一JSON格式返回
Spring Boot 无侵入式 实现API接口统一JSON格式返回
|
Cloud Native Java API
Java Spring拦截器优化实践: 专注于API路径拦截
Java Spring拦截器优化实践: 专注于API路径拦截
103 0