使用Feign实现微服务间文件传输
家电修理 2023-07-16 19:17www.caominkang.com电器维修
在很多时候我们会遇到微服务之间文件传输,很多时候我们可以通过序列化等方式解决(如图片等)。
最近项目中有个excel上传,以及多媒体文件上传,直接报错。
也试了2种解决方式,都不可行。
1.写一个文件Encoder解析器,会出现其他的rest请求出现encoder错误
2.springcloud feign有一个规范,不可以传输2个对象,可以是一个对象带几个参数方式。
那么我们现在需要一种方式,不配置全局的解析器,而是通过Feign Builder 去管理上传文件,这种方式管理起来也较为方便。
引用包
.flix.feign feign-core8.17.0 .flix.feign feign-jackson8.17.0 .flix.feign feign-slf4j8.17.0
调用方式
@ApiOperation(value = "上传Excel", notes = "上传Excel")
@RequestMapping(value = "/imExcel", method = RequestMethod.POST, produces = request_headers)
public ActionResult imExcel(@RequestBody MultipartFile file,@RequestParam("operatorId") Integer operatorId){
if(file == null || file.isEmpty()|| operatorId==null)
return ne ActionResult<>(ResultType.BAD_REQUEST,"文件与操作用户ID都不能为空");
String fileName = file.getOriginalFilename();
if (!fileName.matches("^.+\.(?i)(xls)$") && !fileName.matches("^.+\.(?i)(xlsx)$")) {
return ne ActionResult<>(ResultType.BAD_REQUEST,"上传文件格式错误,请上传后缀为.xls或.xlsx的文件");
}
Feign.Builder encoder = Feign.builder()
.decoder(ne JacksonDecoder())
.encoder(ne FeignEncoder());
FileUpload plainFileUpload = encoder.target(FileUpload.class,LABEL_URL);
return plainFileUpload.imComplainExcel(file,operatorId);
}
文件Encode
import feign.RequestTemplate;
import feign.codec.EncodeException;
import feign.codec.Encoder;
import .springframeork.core.io.InputStreamResource;
import .springframeork.core.io.Resource;
import .springframeork.http.HttpEntity;
import .springframeork.http.HttpHeaders;
import .springframeork.http.HttpOutputMessage;
import .springframeork.http.MediaType;
import .springframeork.http.converter.HttpMessageConverter;
import .springframeork.util.CollectionUtils;
import .springframeork.util.linkedMultiValueMap;
import .springframeork.eb.client.RestTemplate;
import .springframeork.eb.multipart.MultipartFile;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Type;
import java.nio.charset.Charset;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
public class FeignEncoder implements Encoder {
private final List> converters = ne RestTemplate().getMessageConverters();
private final HttpHeaders multipartHeaders = ne HttpHeaders();
private final HttpHeaders jsonHeaders = ne HttpHeaders();
public static final Charset UTF_8 = Charset.forName("UTF-8");
public FeignEncoder() {
multipartHeaders.setContentType(MediaType.MULTIPART_FORM_DATA);
jsonHeaders.setContentType(MediaType.APPLICATION_JSON);
}
@Override
public void encode(Object object, Type bodyType, RequestTemplate template) thros EncodeException {
if (isFormRequest(bodyType)) {
encodeMultipartFormRequest((Map) object, template);
} else {
encodeRequest(object, jsonHeaders, template);
}
}
private void encodeMultipartFormRequest(Map formMap, RequestTemplate template) thros EncodeException {
if (CollectionUtils.isEmpty(formMap)) {
thro ne EncodeException("参数不能为空.");
}
linkedMultiValueMap map = ne linkedMultiValueMap<>();
for (Entry entry : formMap.entrySet()) {
Object value = entry.getValue();
if (isMultipartFile(value)) {
map.add(entry.getKey(), encodeMultipartFile((MultipartFile) value));
} else if (isMultipartFileArray(value)) {
encodeMultipartFiles(map, entry.getKey(), Arrays.asList((MultipartFile[]) value));
} else {
map.add(entry.getKey(), encodeJsonObject(value));
}
}
encodeRequest(map, multipartHeaders, template);
}
private boolean isMultipartFile(Object object) {
return object instanceof MultipartFile;
}
private boolean isMultipartFileArray(Object o) {
return o != null && o.getClass().isArray() && MultipartFile.class.isAssignableFrom(o.getClass().getComponentType());
}
private HttpEntity> encodeMultipartFile(MultipartFile file) {
HttpHeaders filePartHeaders = ne HttpHeaders();
filePartHeaders.setContentType(MediaType.APPLICATION_OCTET_STREAM);
try {
Resource multipartFileResource = ne MultipartFileResource(file.getOriginalFilename(), file.getSize(), file.getInputStream());
return ne HttpEntity<>(multipartFileResource, filePartHeaders);
} catch (IOException ex) {
thro ne EncodeException("Cannot encode request.", ex);
}
}
private void encodeMultipartFiles(linkedMultiValueMap map, String name, List extends MultipartFile> files) {
HttpHeaders filePartHeaders = ne HttpHeaders();
filePartHeaders.setContentType(MediaType.APPLICATION_OCTET_STREAM);
try {
for (MultipartFile file : files) {
Resource multipartFileResource = ne MultipartFileResource(file.getOriginalFilename(), file.getSize(), file.getInputStream());
map.add(name, ne HttpEntity<>(multipartFileResource, filePartHeaders));
}
} catch (IOException ex) {
thro ne EncodeException("Cannot encode request.", ex);
}
}
private HttpEntity> encodeJsonObject(Object o) {
HttpHeaders jsonPartHeaders = ne HttpHeaders();
jsonPartHeaders.setContentType(MediaType.APPLICATION_JSON);
return ne HttpEntity<>(o, jsonPartHeaders);
}
private void encodeRequest(Object value, HttpHeaders requestHeaders, RequestTemplate template) thros EncodeException {
ByteArrayOutputStream outputStream = ne ByteArrayOutputStream();
HttpOutputMessage dummyRequest = ne HttpOutputMessageImpl(outputStream, requestHeaders);
try {
Class> requestType = value.getClass();
MediaType requestContentType = requestHeaders.getContentType();
for (HttpMessageConverter> messageConverter : converters) {
if (messageConverter.canWrite(requestType, requestContentType)) {
((HttpMessageConverter
Feign调用接口
@RequestLine("POST /punish/imExcel")
ActionResult> imPunishExcel(@Param("file") MultipartFile file, @Param("operatorId") Integer operatorId);
空调维修
- 我的世界电脑版运行身份怎么弄出来(我的世界
- 空调抽湿是什么意思,设置抽湿的温度有什么意
- 方太燃气灶有一个打不着火 怎么修复与排查方法
- 夏季免费清洗汽车空调的宣传口号
- 清洗完空调后出现漏水现象
- iphone6能玩什么游戏(iphone6游戏)
- 如何设置电脑密码锁屏(如何设置电脑密码锁屏
- win10删除开机密码提示不符合密码策略要求
- 电脑w7显示不是正版(w7不是正版怎么解决)
- 万家乐z8热水器显示e7解决 怎么修复与排查方法
- 1匹空调多少瓦数(1匹空调多少瓦)
- 安卓手机连接电脑用什么软件好(关于安卓手机
- 电脑网页看视频卡是什么原因(爱拍看视频卡)
- 华帝燃气灶点火器一直响然后熄火怎么办:问题
- 电脑壁纸怎么换(关于电脑壁纸怎么换的介绍)
- 冬天空调的出风口应该朝什么方向(冬天空调风