首页 > 其他分享 >使用Feign接口实现文件上传的解决方案

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

时间:2023-11-06 17:06:20浏览次数:33  
标签:文件 Feign 接口 file new 上传

原文链接:使用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.


标签:文件,Feign,接口,file,new,上传
From: https://blog.51cto.com/kdyzm/8214182

相关文章

  • vue3.0 + ts 实现上传工厂(oss与cos)
    概述将上传基类命名为MOS(MineObjectStorage)mos.ts代码import{MosType}from'./mosConfig'import{Loading}from'../loading'import{typeBinaryFile,typeMosFile}from'./fileUtil'importtype{PathTemplate}from'./pathTempla......
  • 简单易懂,高效实用的接口文档编写技巧
    大家好!我是sum墨,一个一线的底层码农,平时喜欢研究和思考一些技术相关的问题并整理成文,限于本人水平,如果文章和代码有表述不当之处,还请不吝赐教。以下是正文!接口文档是什么接口文档是一个软件系统的重要组成部分,它描述了系统中所有可供外部应用程序使用的接口。简单来说,接口文档就......
  • 文件上传
    关于文件上传修改myproject/myproject/urls.py添加路由#上传文件path('upload/list/',upload.upload_list),新建myproject/app01/views/upload.pyfromdjango.shortcutsimportrender,HttpResponsedefupload_list(request):ifrequest.method=="GE......
  • WEB端实现文件夹上传
    webkitdirectory属性。这个属性加上之后,就是选择文件夹,然后根据自己业务上传至后台;前端代码:<formaction="${ctxPath}/invoice/uploadFolder"method="post"enctype="multipart/form-data"> <inputname="chooseFolder"type="file"id="c......
  • 模拟攻击beescms框架网站,并且一步一步渗透测试,上传shell,连接蚁剑,拿到对方网站根目录
    打开网站发现它是beescms框架搭建的网站,一言不合直接用webpathbrute扫描发现了管理员登录页面尝试任意用户名密码登录发现不太行,直接暴力破解,先burp抓数据包发现有4个参数有user,password,code,submit,把submit=ture修改为submit=false验证码就不会刷新了就是284c。接下来......
  • 带你理解 Java 8 的函数式接口使用和自定义
    函数式接口是Java8引入的一种接口,用于支持函数式编程。函数式接口通常包含一个抽象方法,可以被Lambda表达式或方法引用所实现。在本文中,我们将深入探讨函数式接口的概念、用途以及如何创建和使用函数式接口。什么是函数式接口函数式接口是只包含一个抽象方法的接口。但是默认方......
  • (十)Robot Framework之处理接口响应
    处理响应数据1.获得响应正文${响应结果.content}二进制编码${响应结果.text}unicode码形式的正文${响应结果.content.decode("utf-8")}转码为utf-82.json格式${json变量} tojson ${响应结果.content} pretty_print=True获取json中的的项(相当于正则提取器)${变......
  • java web 上传文件夹的实现(支持Chrome)
    上传文件夹的思路其实就是将文件夹中所有的文件上传到服务器,上传的时候文件名称要从文件夹目录开始截取,以下图中的目录为例,index.html文件应该以news_1/index.html的路径传到服务器,所有文件上传之后,上传到服务器的文件夹路径是从上传的上传的文件路径截取到文件夹结束。下面详细介......
  • 11、SpringMVC之文件下载和上传
    创建名为spring_mvc_file的新module,过程参考9.1节和9.5节11.1、文件下载11.1.1、创建图片目录并放置图片11.1.2、页面请求示例<ath:href="@{/test/down}">下载图片</a>11.1.3、控制器方法示例packageonline.liaojy.controller;importorg.springframework.http.Ht......
  • JUC并发编程学习(十一)四大函数式接口(必备)
    四大函数式接口(必备)程序员:泛型、反射、注解、枚举新时代程序员:lambda表达式、链式编程、函数式接口、Stream流式计算函数式接口:只有一个方法的接口@FunctionalInterfacepublicinterfaceRunnable{publicabstractvoidrun();}//@FunctionalInterface函数式接口,超......