使用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);
空调维修
- 温岭冰箱全国统一服务热线-全国统一人工【7X2
- 荆州速热热水器维修(荆州热水器维修)
- 昆山热水器故障码5ER-昆山热水器故障码26
- 温岭洗衣机24小时服务电话—(7X24小时)登记报
- 统帅热水器售后维修服务电话—— (7X24小时)登
- 阳江中央空调统一电话热线-阳江空调官方售后电
- 乌鲁木齐阳春燃气灶厂家服务热线
- 珠海许昌集成灶售后服务电话-全国统一人工【
- 乌鲁木齐中央空调维修服务专线-乌鲁木齐中央空
- 新沂热水器故障电话码维修-新沂热水器常见故障
- 诸城壁挂炉24小时服务热线电话
- 靖江空调24小时服务电话-——售后维修中心电话
- 空调室外滴水管维修(空调室外排水管维修)
- 九江壁挂炉400全国服务电话-(7X24小时)登记报修
- 热水器故障码f.22怎么解决-热水器f0故障解决方法
- 营口热水器售后维修服务电话—— 全国统一人工