1. 程式人生 > >如何基於ServiceComb實現檔案上傳功能

如何基於ServiceComb實現檔案上傳功能

檔案上傳,當前支援在vertx rest通道和servlet rest中使用。

檔案上傳使用標準的http form格式,可與瀏覽器的上傳直接對接。

Producer:

支援jaxrs和springmvc開發模式

jaxrs開發模式:

  • 支援servlet定義的javax.servlet.http.Part型別

  • 可以直接使用@FormParam傳遞檔案型別及普通引數

springmvc開發模式:

  • 支援servlet定義的javax.servlet.http.Part型別,也支援org.springframework.web.multipart.MultipartFile型別

  • 兩種資料型別功能是一致的,MultipartFile的底層也是Part

  • 兩種資料型別可以混合使用,比如第一個引數是Part,第二個引數是MultipartFile

  • 可以直接使用@RequestPart傳遞檔案型別及普通引數

注意:

  • 先配置檔案上傳臨時目錄,預設為null不支援檔案上傳,檔案上傳請求Content-Type必須為multipart/form-data

  • 同名引數只支援一個檔案

  • 支援一次傳輸多個不同引數名的檔案

  • 通過MultipartFile或Part開啟流後,記得關閉,否則上傳的臨時檔案會無法刪除,最終導致上傳臨時目錄被撐爆

Springmvc模式下的程式碼樣例:

@PostMapping(path = "/upload", consumes = MediaType.MULTIPART_FORM_DATA)
public String fileUpload(@RequestPart(name = "file1") MultipartFile file1, @RequestPart(name = "file2") Part file2, @RequestPart String param1) {
  ……
}

配置說明:

配置項 預設值 取值範圍 含義
servicecomb.uploads.directory null 上傳的臨時檔案儲存在哪個目錄,預設值null表示不支援檔案上傳
servicecomb.uploads.maxSize -1 http body的最大允許大小,預設值-1表示無限制

Consumer:

支援以下資料型別:

  • java.io.File

  • javax.servlet.http.Part

  • java.io.InputStream

  • org.springframework.core.io.Resource

使用InputStream時,因為是流的方式,此時沒有客戶端檔名的概念,所以producer獲取客戶端檔名會得到null

如果既要使用記憶體資料,又想讓producer可以獲取客戶端檔名,可以使用resource型別,繼承org.springframework.core.io.ByteArrayResource,且override getFilename即可。

透明RPC程式碼樣例:

interface UploadIntf {
  String upload(File file);
}

獲得介面引用後,直接呼叫即可:

String result = uploadIntf.upload(file);

RestTemplate程式碼樣例:

Map<String, Object> map = new HashMap<>();
map.put("file", new FileSystemResource("a file path!"));
map.put("param1", "test");
HttpHeaders headers = new HttpHeaders();
headers.setContentType(org.springframework.http.MediaType.MULTIPART_FORM_DATA);
HttpEntity<Map<String, Object>> entry = new HttpEntity<>(map, headers);

String reseult = template.postForObject(
    url,
    entry,
    String.class);