最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

使用Feign擴展包實現(xiàn)微服務(wù)間文件上傳

 更新時間:2019年04月24日 11:44:05   作者:AaronSimon  
這篇文章主要為大家詳細介紹了使用Feign擴展包實現(xiàn)微服務(wù)間文件上傳,具有一定的參考價值,感興趣的小伙伴們可以參考一下

在Spring Cloud 的Feign組件中并不支持文件的傳輸,會出現(xiàn)這樣的錯誤提示:

feign.codec.EncodeException: class [Lorg.springframework.web.multipart.MultipartFile; is not a type supported by this encoder.
  at feign.codec.Encoder$Default.encode(Encoder.java:90) ~[feign-core-9.5.1.jar:na]
  at feign.form.FormEncoder.encode(FormEncoder.java:87) ~[feign-form-3.3.0.jar:3.3.0]
  at feign.form.spring.SpringFormEncoder.encode(SpringFormEncoder.java:64) ~[feign-form-spring-3.3.0.jar:3.3.0]

但是我們可以通過使用Feign的擴展包實現(xiàn)這個功能。

一. 示例介紹

我們調(diào)用feign_upload_second的上傳文件接口上傳文件,feign_upload_second內(nèi)部使用feign調(diào)用feign_upload_first實現(xiàn)文件上傳。

二 、單文件上傳

2.1 feign_upload_first服務(wù)提供者

文件上傳的服務(wù)提供者接口比較簡單,如下所示:

@SpringBootApplication
public class FeignUploadFirstApplication {
 @RestController
 public class UploadController {

  @RequestMapping(value = "/uploadFile",method = RequestMethod.POST, consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
  public String handleFileUpload(@RequestPart(value = "file") MultipartFile file) {
   return file.getOriginalFilename();
  }
 }
 public static void main(String[] args) {
  SpringApplication.run(FeignUploadFirstApplication.class, args);
 }
}

2.2 feign_upload_second服務(wù)消費者

增加擴展包依賴

<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>
  <dependency>
   <groupId>commons-fileupload</groupId>
   <artifactId>commons-fileupload</artifactId>
   <version>1.3.3</version>
</dependency>

新增feign實現(xiàn)文件上傳的配置類

@Configuration
public class FeignSupportConfig {
 @Bean
 public Encoder feignFormEncoder() {
  return new SpringFormEncoder();
 }
}

feign遠程調(diào)用接口

@FeignClient(name = "file",url = "http://localhost:8100",configuration = FeignSupportConfig.class)
public interface UploadService {
 @RequestMapping(value = "/uploadFile", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
 String handleFileUpload(@RequestPart(value = "file") MultipartFile file);
}

上傳文件接口

@RestController
public class UploadController {
 @Autowired
 UploadService uploadService;

 @RequestMapping(value = "/uploadFile",method = RequestMethod.POST, consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
 public String handleFileUpload(@RequestPart(value = "file") MultipartFile file) {
  return uploadService.handleFileUpload(file);
 }
}

2.3 測試

使用postman進行測試,可以正常上傳文件

三、多文件上傳

既然單個文件可以上傳,那么多文件應(yīng)該也沒問題吧,我們對上面的代碼進行修改

3.1 feign_upload_first服務(wù)提供者

文件上傳的服務(wù)提供者接口比較簡單,如下所示:

@SpringBootApplication
public class FeignUploadFirstApplication {
 @RestController
 public class UploadController {

  @RequestMapping(value = "/uploadFile",method = RequestMethod.POST, consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
  public String handleFileUpload(@RequestPart(value = "file") MultipartFile file) {
   return file.getOriginalFilename();
  }

  @RequestMapping(value = "/uploadFile2",method = RequestMethod.POST, consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
  public String handleFileUpload(@RequestPart(value = "file") MultipartFile[] file) {
   String fileName = "";
   for(MultipartFile f : file){
    fileName += f.getOriginalFilename()+"---";
   }
   return fileName;
  }
 }
 public static void main(String[] args) {
  SpringApplication.run(FeignUploadFirstApplication.class, args);
 }
}

3.2 feign_upload_second服務(wù)消費者

feign遠程調(diào)用接口

@FeignClient(name = "file",url = "http://localhost:8100",configuration = FeignSupportConfig.class)
public interface UploadService {
 @RequestMapping(value = "/uploadFile", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
 String handleFileUpload(@RequestPart(value = "file") MultipartFile file);

 @RequestMapping(value = "/uploadFile2", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
 String handleFileUpload(@RequestPart(value = "file") MultipartFile[] file);
}

上傳文件接口

@RestController
public class UploadController {
 @Autowired
 UploadService uploadService;

 @RequestMapping(value = "/uploadFile",method = RequestMethod.POST, consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
 public String handleFileUpload(@RequestPart(value = "file") MultipartFile file) {
  return uploadService.handleFileUpload(file);
 }

 @RequestMapping(value = "/uploadFile2",method = RequestMethod.POST, consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
 public String handleFileUpload2(@RequestPart(value = "file") MultipartFile[] file) {
  return uploadService.handleFileUpload(file);
 }
}

3.3 測試

經(jīng)過測試發(fā)現(xiàn),無法上傳多個文件。經(jīng)過檢查,發(fā)現(xiàn)源碼里底層是有對MultipartFile[]類型的支持的,源碼中有個類叫SpringManyMultipartFilesWriter,是專門針對文件數(shù)組類型進行操作的,但是配置到項目里的SpringFormEncoder類里卻沒有對文件數(shù)組類型的判斷,以致不能支持文件數(shù)組的上傳

SpringManyMultipartFilesWriter源碼

public class SpringManyMultipartFilesWriter extends AbstractWriter {
 private final SpringSingleMultipartFileWriter fileWriter = new SpringSingleMultipartFileWriter();

 public SpringManyMultipartFilesWriter() {
 }

 public void write(Output output, String boundary, String key, Object value) throws Exception {
  if (value instanceof MultipartFile[]) {
   MultipartFile[] files = (MultipartFile[])((MultipartFile[])value);
   MultipartFile[] var6 = files;
   int var7 = files.length;

   for(int var8 = 0; var8 < var7; ++var8) {
    MultipartFile file = var6[var8];
    this.fileWriter.write(output, boundary, key, file);
   }
  } else if (value instanceof Iterable) {
   Iterable<?> iterable = (Iterable)value;
   Iterator var11 = iterable.iterator();

   while(var11.hasNext()) {
    Object file = var11.next();
    this.fileWriter.write(output, boundary, key, file);
   }
  }

 }

 public boolean isApplicable(Object value) {
  if (value == null) {
   return false;
  } else if (value instanceof MultipartFile[]) {
   return true;
  } else {
   if (value instanceof Iterable) {
    Iterable<?> iterable = (Iterable)value;
    Iterator<?> iterator = iterable.iterator();
    if (iterator.hasNext() && iterator.next() instanceof MultipartFile) {
     return true;
    }
   }

   return false;
  }
 }
}

SpringFormEncoder源碼

public class SpringFormEncoder extends FormEncoder {
 public SpringFormEncoder() {
  this(new Default());
 }

 public SpringFormEncoder(Encoder delegate) {
  super(delegate);
  MultipartFormContentProcessor processor = (MultipartFormContentProcessor)this.getContentProcessor(ContentType.MULTIPART);
  processor.addWriter(new SpringSingleMultipartFileWriter());
  processor.addWriter(new SpringManyMultipartFilesWriter());
 }

 public void encode(Object object, Type bodyType, RequestTemplate template) throws EncodeException {
  if (!bodyType.equals(MultipartFile.class)) {
   super.encode(object, bodyType, template);
  } else {
   MultipartFile file = (MultipartFile)object;
   Map<String, Object> data = Collections.singletonMap(file.getName(), object);
   super.encode(data, MAP_STRING_WILDCARD, template);
  }
 }
}

從上面SpringFormEncoder的源碼上可以看到SpringFormEncoder類構(gòu)造時把SpringManyMultipartFilesWriter實例添加到了處理器列表里了,但是在encode方法里又只判斷了MultipartFile類型,沒有判斷數(shù)組類型,底層有對數(shù)組的支持但上層卻缺少了相應(yīng)判斷。那么我們可以自己去擴展FormEncoder,仿照SpringFormEncoder源碼,只修改encode方法。

3.3 擴展FormEncoder支持多文件上傳

擴展FormEncoder,命名為FeignSpringFormEncoder

public class FeignSpringFormEncoder extends FormEncoder {
 /**
  * Constructor with the default Feign's encoder as a delegate.
  */
 public FeignSpringFormEncoder() {
  this(new Default());
 }


 /**
  * Constructor with specified delegate encoder.
  *
  * @param delegate delegate encoder, if this encoder couldn't encode object.
  */
 public FeignSpringFormEncoder(Encoder delegate) {
  super(delegate);

  MultipartFormContentProcessor processor = (MultipartFormContentProcessor) getContentProcessor(ContentType.MULTIPART);
  processor.addWriter(new SpringSingleMultipartFileWriter());
  processor.addWriter(new SpringManyMultipartFilesWriter());
 }


 @Override
 public void encode(Object object, Type bodyType, RequestTemplate template) throws EncodeException {
  if (bodyType.equals(MultipartFile.class)) {
   MultipartFile file = (MultipartFile) object;
   Map data = Collections.singletonMap(file.getName(), object);
   super.encode(data, MAP_STRING_WILDCARD, template);
   return;
  } else if (bodyType.equals(MultipartFile[].class)) {
   MultipartFile[] file = (MultipartFile[]) object;
   if(file != null) {
    Map data = Collections.singletonMap(file.length == 0 ? "" : file[0].getName(), object);
    super.encode(data, MAP_STRING_WILDCARD, template);
    return;
   }
  }
  super.encode(object, bodyType, template);
 }
}

注冊配置類

@Configuration
public class FeignSupportConfig {
 @Bean
 public Encoder feignFormEncoder() {
  return new FeignSpringFormEncoder();
 }
}

經(jīng)過測試可以上傳多個文件。

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • 使用HttpServletResponse對象獲取請求行信息

    使用HttpServletResponse對象獲取請求行信息

    這篇文章主要介紹了使用HttpServletResponse對象獲取請求行信息,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-02-02
  • Nacos框架與原理之Nacos的參數(shù)

    Nacos框架與原理之Nacos的參數(shù)

    這篇文章主要介紹了Nacos框架與原理之Nacos的參數(shù),Nacos?中的參數(shù)有很多,如:命名空間、分組名、服務(wù)名、保護閾值、服務(wù)路由類型、臨時實例等,但下面文章我們要講解的是參數(shù),參數(shù)是什么呢,下面一起進去文章學(xué)習(xí)詳細內(nèi)容吧
    2022-05-05
  • springboot prototype設(shè)置多例不起作用的解決操作

    springboot prototype設(shè)置多例不起作用的解決操作

    這篇文章主要介紹了springboot prototype設(shè)置多例不起作用的解決操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-09-09
  • 運行Jar包出現(xiàn)提示xxx中沒有主清單屬性報錯問題解決方法

    運行Jar包出現(xiàn)提示xxx中沒有主清單屬性報錯問題解決方法

    這篇文章主要介紹了運行Jar包出現(xiàn):xxx中沒有主清單屬性報錯,當出現(xiàn)報錯:xxx中沒有主清單屬性,解決方法也很簡單,在pom.xml配置中,加上相應(yīng)配置即可,需要的朋友可以參考下
    2023-08-08
  • Java語言之包和繼承詳解

    Java語言之包和繼承詳解

    這篇文章主要介紹了java的包和繼承,結(jié)合實例形式詳細分析了Java繼承的概念、原理、用法及相關(guān)操作注意事項,需要的朋友可以參考下
    2021-09-09
  • spring-boot整合dubbo:Spring-boot-dubbo-starter

    spring-boot整合dubbo:Spring-boot-dubbo-starter

    這篇文章主要介紹了spring-boot整合dubbo:Spring-boot-dubbo-starter的相關(guān)資料,非常不錯,具有參考借鑒價值,需要的朋友可以參考下
    2017-05-05
  • 使用Spring Batch實現(xiàn)批處理任務(wù)的詳細教程

    使用Spring Batch實現(xiàn)批處理任務(wù)的詳細教程

    在企業(yè)級應(yīng)用中,批處理任務(wù)是不可或缺的一部分,它們通常用于處理大量數(shù)據(jù),如數(shù)據(jù)遷移、數(shù)據(jù)清洗、生成報告等,Spring Batch是Spring框架的一部分,本文將介紹如何使用Spring Batch與SpringBoot結(jié)合,構(gòu)建和管理批處理任務(wù),需要的朋友可以參考下
    2024-06-06
  • Spring動態(tài)數(shù)據(jù)源實現(xiàn)讀寫分離詳解

    Spring動態(tài)數(shù)據(jù)源實現(xiàn)讀寫分離詳解

    這篇文章主要為大家詳細介紹了Spring動態(tài)數(shù)據(jù)源實現(xiàn)讀寫分離,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-07-07
  • HttpClient的KeepAlive接口方法源碼解析

    HttpClient的KeepAlive接口方法源碼解析

    這篇文章主要為大家介紹了HttpClient的KeepAlive接口方法源碼解析,
    有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-10-10
  • SpringBoot 注解事務(wù)聲明式事務(wù)的方式

    SpringBoot 注解事務(wù)聲明式事務(wù)的方式

    springboot使用上述注解的幾種方式開啟事物,可以達到和xml中聲明的同樣效果,但是卻告別了xml,使你的代碼遠離配置文件。今天就扒一扒springboot中事務(wù)使用注解的玩法,感興趣的朋友一起看看吧
    2017-09-09

最新評論

石狮市| 吉木萨尔县| 泽州县| 大渡口区| 昆山市| 瑞安市| 五大连池市| 西和县| 龙州县| 阿拉善右旗| 穆棱市| 兰西县| 温泉县| 三门峡市| 随州市| 鸡东县| 西和县| 车险| 津市市| 青海省| 绥化市| 阿克苏市| 怀宁县| 兴宁市| 多伦县| 桐城市| 榕江县| 旬邑县| 昆明市| 共和县| 论坛| 夏津县| 定州市| 大石桥市| 余江县| 大英县| 东平县| 长治市| 安化县| 资阳市| 友谊县|