Feign呼叫檔案上傳服務介面樣例
前面做了Feign呼叫檔案下載服務介面的例子,這裡順帶把Feign呼叫檔案上傳服務介面的例子也一起做了!一樣直接上程式碼:
首先是檔案上傳服務提供者的主要程式碼:
@PostMapping(value = "/upload") public String uploadFile(@RequestPart MultipartFile file) { if (file.isEmpty()) { return null; } String fileName = file.getOriginalFilename(); String storePath= "C:\\java\\upload";//換成你自己的檔案上傳儲存目錄 File destFile = new File(storePath + "\\" + fileName); if (!destFile.getParentFile().exists()) { destFile.getParentFile().mkdirs();//注意,是mkdirs不是mkdir,後者只建立檔案的直接父目錄,建立不了多層目錄 } try { file.transferTo(destFile);return destFile.getAbsolutePath();//返回檔案上傳成功後的檔案儲存完整路徑 } catch (IOException e) { e.printStackTrace(); return null; } }
接著我們在Postman中先測試一下上述介面是否可用(Postman中使用POST請求,在Body中選擇form-data格式,將Key的引數型別切換成File,在Value中選擇目標檔案):
可以看到上傳成功了,接著我又試著上傳一個大一點的檔案,上傳了一個電影,結果翻車了:
檢視IDEA控制檯的報錯輸出看到以下資訊:
2020-07-15 17:49:54.227 ERROR 5936 --- [nio-8001-exec-8] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.web.multipart.MaxUploadSizeExceededException: Maximum upload size exceeded; nested exception is java.lang.IllegalStateException: org.apache.tomcat.util.http.fileupload.impl.SizeLimitExceededException: the request was rejected because its size (1538829581) exceeds the configured maximum (10485760)] with root cause org.apache.tomcat.util.http.fileupload.impl.SizeLimitExceededException: the request was rejected because its size (1538829581) exceeds the configured maximum (10485760)
看到重要資訊——SizeLimitExceededException異常,超出大小限制異常!好吧,檢視SpringBoot原始碼發現檔案下載預設單檔案最大是1MB,單次多個檔案總大小最大是10MB,這也太小了!
在application.yml中修改一下配置,加大電流!將單檔案下載的最大尺寸設為3GB,單次多個檔案總大小最大尺寸設為10GB:
spring: servlet: multipart: max-file-size: 3GB max-request-size: 10GB
重新啟動服務提供者,再次測試上傳剛才1.43GB的電影:
現在服務提供者的檔案上傳服務介面就已經準備好了!
接下來是服務消費者(Feign客戶端)的程式碼:
新版本的Feign宣告檔案上傳介面也已經很簡單了,下面是我的Feign依賴資訊:
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> <version>2.2.3.RELEASE</version> </dependency>
Feign介面宣告:
import org.springframework.cloud.openfeign.FeignClient; import org.springframework.http.MediaType; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestPart; import org.springframework.web.multipart.MultipartFile; @FeignClient(name = "provider-user") @RequestMapping(value = "/user") public interface UserFeignClient extends FeignClientParent { @PostMapping(value = "/upload",produces = MediaType.APPLICATION_PROBLEM_JSON_VALUE,consumes = MediaType.MULTIPART_FORM_DATA_VALUE) String uploadFile(@RequestPart MultipartFile file); }
然後是服務消費者的Controller介面:
@PostMapping(value = "/upload", produces = MediaType.APPLICATION_PROBLEM_JSON_VALUE, consumes = MediaType.MULTIPART_FORM_DATA_VALUE) public String uploadFile(@RequestPart MultipartFile file) { return this.userFeignClient.uploadFile(file); }
這裡特別提醒一下:首先一定要注意上述程式碼中標紅標粗的produces、consumes和@RequestPart註解,特是是@RequestPart註解不要寫成了@RequestParam,否則你會翻車的!
另外,Feign呼叫上傳檔案服務介面是藉助了feign-form和feign-form-spring元件,早期的Feign包中不包含這兩個元件,需有額外引用,但現在較新版本的Feign都內部集成了這兩個依賴,不用再額外引用了!
接著我就先後跑起了Eureka服務端→檔案上傳服務提供者端→檔案上傳服務消費者端,然後輕輕鬆鬆的開啟Postman進行了測試: