Feign之Multipartfile文件傳輸填坑
Multipartfile文件傳輸
1. 添加依賴
<dependency>
<groupId>io.github.openfeign.form</groupId>
<artifactId>feign-form</artifactId>
<version>3.3.0</version>
</dependency>
<dependency>
<groupId>io.github.openfeign.form</groupId>
<artifactId>feign-form-spring</artifactId>
<version>3.3.0</version>
</dependency>
2. 添加配置類
@Configuration
public class FeignMultipartConfig {
@Bean
@Primary
@Scope("prototype")
public SpringFormEncoder multipartFormEncoder() {
return new SpringFormEncoder();
}
@Bean
public feign.Logger.Level multipartLoggerLevel() {
return feign.Logger.Level.FULL;
}
}
3. 接口編寫
@FeignClient使用配置類
@PostMapping設(shè)置
consumes = MediaType.MULTIPART_FORM_DATA_VALUE
使用@RequestPart(),不能使用@RequestParam()
@FeignClient(value = "face-service",configuration = FeignMultipartConfig.class)
public interface FaceClient {
@PostMapping(value = "/search/student", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
ResponseBase<SearchStudentFaceVO> searchStudentFace(@RequestPart("file") MultipartFile file);
}
feign不能正常傳遞參數(shù)MultipartFile(文件)的解決
之前工作中有個業(yè)務(wù)場景:需要把文件以MultipartFile進(jìn)行服務(wù)之間的調(diào)用(使用的是Feign),特此記錄下踩到的坑
需要注意的是:使用默認(rèn)的springcloud自帶的spring-cloud-starter-openfeign是不支持傳遞文件的。
我看網(wǎng)上有很多使用feign-form和feign-form-spring支持的jar包,然后配置SpringFormEncoder,但我試了,沒有成功,最后使用了另外一種方法,在此記錄下吧:
方法一:使用外部依賴
<dependency>
<groupId>io.github.openfeign.form</groupId>
<artifactId>feign-form</artifactId>
<version>3.3.0</version>
</dependency>
<dependency>
<groupId>io.github.openfeign.form</groupId>
<artifactId>feign-form-spring</artifactId>
<version>3.3.0</version>
</dependency>
新建配置類:
package com.jsyd.ict.ictservicemanager.configuration;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
import org.springframework.cloud.openfeign.support.SpringEncoder;
import org.springframework.context.annotation.Bean;
import feign.codec.Encoder;
import feign.form.spring.SpringFormEncoder;
import org.springframework.context.annotation.Configuration;
/**
* 處制定了注入的feignFormEncoder可以覆蓋掉原本的encoder
* 該方式可以讓發(fā)送multipartFile成為可能
* @author wangyang
* @version 1.0
* @date 2021/4/13 19:13
*/
@Configuration
public class MultipartSupportConfig {
@Autowired
private ObjectFactory<HttpMessageConverters> messageConverters;
@Bean
public Encoder feignFormEncoder() {
return new SpringFormEncoder(new SpringEncoder(messageConverters));
}
}
配置feign接口:
package com.jsyd.ict.ictservicemanager.feign;
import com.jsyd.ict.ictservicemanager.util.resp.RespUtil;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.InputStream;
/**
* 能力的調(diào)用
*
* @author wangyang
* @version 1.0
* @date 2021/3/11 21:01
*/
@FeignClient(name = "ict-service-capacity", configuration = MultipartSupportConfig.class)
public interface CapacityFeign {
@RequestMapping(value = "contentAudit/baiduImgAuditByFile", method = RequestMethod.POST, consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
RespUtil baiduImgAuditByFile(@RequestPart(value = "file") MultipartFile file);
}
注意:文件的傳輸需要使用@RequestPart()注解
服務(wù)端:
@RequestMapping(value = "/baiduImgAuditByFile", method = RequestMethod.POST)
public RespUtil baiduImgAuditByFile(@RequestParam("file") MultipartFile file) {
// 調(diào)用service
return null;
}
結(jié)果發(fā)現(xiàn),這樣是獲取不到結(jié)果的,研究了好一會,因為要著急聯(lián)調(diào),就沒有繼續(xù)跟蹤了,有時間在深入研究下。
后來使用了下面的方法,成功傳參
方法二:使用HttpServletRequest獲取
上述操作都不需要,即:不需要導(dǎo)入依賴,也不需要創(chuàng)建文件,只需要在服務(wù)端通過HttpServletRequest去設(shè)置
使用HttpServletRequest設(shè)置:
偽代碼如下:
@RequestMapping(value = "/baiduImgAuditByFile", method = RequestMethod.POST)
public RespUtil baiduImgAuditByFile(MultipartFile file, HttpServletRequest request) {
if (file == null) {
// 解決服務(wù)間調(diào)用無法接受MultipartFile參數(shù)的問題
String contentType = request.getContentType();
if (contentType != null && contentType.toLowerCase().startsWith("multipart/")) {
MultipartHttpServletRequest multipartRequest =
WebUtils.getNativeRequest(request, MultipartHttpServletRequest.class);
if (multipartRequest != null) {
MultiValueMap<String, MultipartFile> multiFileMap = multipartRequest.getMultiFileMap();
for (Map.Entry<String, List<MultipartFile>> entry : multiFileMap.entrySet()) {
file = entry.getValue().get(0);
}
}
}
}
// 處理業(yè)務(wù)邏輯
return null;
}
主要說明如下圖:

即通過HttpServletRequest 的方式即使文件獲取不到,也可以進(jìn)行特殊處理,從而獲取文件。
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
Java中LocalDate日期格式轉(zhuǎn)換(使用系統(tǒng)時區(qū))
本文主要介紹了Java中LocalDate日期格式轉(zhuǎn)換(使用系統(tǒng)時區(qū)),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2007-02-02
Spring?Boot循環(huán)依賴原理、解決方案與最佳實踐(全解析)
循環(huán)依賴指兩個或多個Bean相互直接或間接引用,形成閉環(huán)依賴關(guān)系,這篇文章主要介紹了Spring?Boot循環(huán)依賴原理、解決方案與最佳實踐(全解析),需要的朋友可以參考下2025-04-04
怎樣將一個JAR包添加到Java應(yīng)用程序的Boot?Classpath中
本文文章給大家介紹如何將一個JAR包添加到Java應(yīng)用程序的Boot?Classpath中,本文通過實例代碼給大家介紹的非常詳細(xì),需要的的朋友參考下吧2023-11-11
關(guān)于swagger配置及踩坑@Api參數(shù)postion無效解決接口排序問題
這篇文章主要介紹了關(guān)于swagger配置及踩坑@Api參數(shù)postion無效解決接口排序問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-06-06

