欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

使用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)文章

  • Java JDBC連接數(shù)據(jù)庫常見操作總結(jié)

    Java JDBC連接數(shù)據(jù)庫常見操作總結(jié)

    這篇文章主要介紹了Java JDBC連接數(shù)據(jù)庫常見操作,結(jié)合實例形式總結(jié)分析了java基于jdbc連接mysql、Oracle數(shù)據(jù)庫及連接池相關(guān)操作技巧,需要的朋友可以參考下
    2019-03-03
  • SpringCloudStream原理和深入使用小結(jié)

    SpringCloudStream原理和深入使用小結(jié)

    Spring?Cloud?Stream是一個用于構(gòu)建與共享消息傳遞系統(tǒng)連接的高度可擴展的事件驅(qū)動型微服務(wù)的框架,本文給大家介紹SpringCloudStream原理和深入使用,感興趣的朋友跟隨小編一起看看吧
    2024-06-06
  • SpringBoot深入理解之內(nèi)置web容器及配置的總結(jié)

    SpringBoot深入理解之內(nèi)置web容器及配置的總結(jié)

    今天小編就為大家分享一篇關(guān)于SpringBoot深入理解之內(nèi)置web容器及配置的總結(jié),小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2019-03-03
  • 一篇超詳細的Spring Boot整合Mybatis文章

    一篇超詳細的Spring Boot整合Mybatis文章

    大家都知道springboot搭建一個spring框架只需要秒秒鐘。下面通過實例代碼給大家介紹一下springboot與mybatis的完美融合,非常不錯,具有參考借鑒價值,感興趣的朋友一起看看吧
    2021-07-07
  • Java利用位運算實現(xiàn)乘法運算詳解

    Java利用位運算實現(xiàn)乘法運算詳解

    這篇文章主要為大家詳細介紹了Java如何用位運算實現(xiàn)乘法運算,在實現(xiàn)乘法時要用位運算實現(xiàn),并且不能出現(xiàn)加減乘除任何符號,感興趣的可以了解一下
    2023-04-04
  • java中Sources目錄Resources目錄的區(qū)別解讀

    java中Sources目錄Resources目錄的區(qū)別解讀

    這篇文章主要介紹了java中Sources目錄Resources目錄的區(qū)別解讀,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-12-12
  • Java連接Mysql數(shù)據(jù)庫詳細代碼實例

    Java連接Mysql數(shù)據(jù)庫詳細代碼實例

    這篇文章主要介紹了Java連接Mysql數(shù)據(jù)庫詳細代碼實例,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-02-02
  • SpringBoot項目使用協(xié)同過濾的實現(xiàn)

    SpringBoot項目使用協(xié)同過濾的實現(xiàn)

    協(xié)同過濾是一種常用的推薦系統(tǒng)算法,用于預(yù)測用戶可能喜歡的物品,本文主要介紹了SpringBoot項目使用協(xié)同過濾的實現(xiàn),感興趣的可以了解一下
    2023-09-09
  • Java實現(xiàn)文件上傳保存

    Java實現(xiàn)文件上傳保存

    這篇文章主要為大家詳細介紹了Java實現(xiàn)文件上傳保存,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-06-06
  • Java常用類之System類的使用指南

    Java常用類之System類的使用指南

    System類代表系統(tǒng),系統(tǒng)級的很多屬性和控制方法都放置在該類的內(nèi)部。該類位于java.lang包。本文將通過示例為大家詳細講講System類的使用,需要的可以參考一下
    2022-07-07

最新評論