This is an automated email from the ASF dual-hosted git repository. liubao pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/incubator-servicecomb-docs.git
commit 15fc3276950cbd4be5537c05ea09c3daa3a2ddd9 Author: DeanLee <lidi...@huawei.com> AuthorDate: Wed Aug 22 17:22:01 2018 +0800 update general-development/file-download.md --- .../en_US/general-development/file-download.md | 85 +++++++++++----------- 1 file changed, 43 insertions(+), 42 deletions(-) diff --git a/java-chassis-reference/en_US/general-development/file-download.md b/java-chassis-reference/en_US/general-development/file-download.md index 1a039aa..d6d274b 100644 --- a/java-chassis-reference/en_US/general-development/file-download.md +++ b/java-chassis-reference/en_US/general-development/file-download.md @@ -1,26 +1,26 @@ -文件下载,当前在vertx rest通道和servlet rest中可用。 +File downloads are currently available in the vertx rest channel and servlet rest. -# 一、Producer +# First, producer -## 1.下载普通文件 +## 1. Download normal files ``` return new File(......); ``` -## 2.下载临时文件 +## 2. Download temporary files -本场景下,需要根据请求参数动态创建临时文件,下载完成后,需要将临时文件删除 +In this scenario, you need to create temporary files based on the request parameters dynamically. After the download is complete, you need to delete the temporary files. ``` return new FilePart(file).setDeleteAfterFinished(true); ``` -## 3.下载org.springframework.core.io.Resource +## 3. Download org.springframework.core.io.Resource -因为resource不一定表示文件下载,所以需要通过swagger annotation(@ApiResponse)标识这是一个文件下载场景 +Because the resource does not necessarily mean file download, you need to identify this file download scenario by swagger annotation (@ApiResponse). -以ByteArrayResource为例说明: +Take ByteArrayResource as an example: ``` @GetMapping(path = "/resource") @@ -28,7 +28,7 @@ return new FilePart(file).setDeleteAfterFinished(true); @ApiResponse(code = 200, response = File.class, message = "") }) public Resource resource() { - …… + ...... return new ByteArrayResource(bytes) { @Override public String getFilename() { @@ -38,7 +38,7 @@ public Resource resource() { } ``` -上例中,因为ByteArrayResource没有文件名的概念,所以需要实现Resource的getFilename方法,也可以通过ResponseEntity进行包装: +In the above example, because ByteArrayResource does not have the concept of a file name, you need to implement the resource's getFilename method, or you can wrap it with ResponseEntity: ``` @GetMapping(path = "/resource") @@ -46,7 +46,7 @@ public Resource resource() { @ApiResponse(code = 200, response = File.class, message = "") }) public ResponseEntity<Resource> resource() { - …… + ...... return ResponseEntity .ok() .header(HttpHeaders.CONTENT_TYPE, MediaType.TEXT_PLAIN_VALUE) @@ -55,11 +55,11 @@ public ResponseEntity<Resource> resource() { } ``` -## 4.下载InputStream +## 4.Download InputStream -因为InputStream不一定表示文件下载,所以需要通过swagger annotation(@ApiResponse)标识这是一个文件下载场景 +Because InputStream does not necessarily mean file downloading, it needs to be identified by swagger annotation (@ApiResponse). This is a file download scenario. -有的场景下,资源并不保存在本地,比如保存在OBS云服务中,而OBS资源是以InputStream方式输出的 +In some scenarios, resources are not stored locally, such as in OBS cloud services, and OBS resources are output in InputStream mode. ``` return ResponseEntity @@ -69,75 +69,76 @@ return ResponseEntity .body(stream); ``` -在下载完成后,ServiceComb会自动关闭stream,开发人员不必再关注 +After the download is complete, ServiceComb will automatically close the stream, and developers don't have to pay attention -## 5.文件类型判定 +## 5. File type determination -只要没有通过ResponseEntity直接设置HttpHeaders.CONTENT\_TYPE,ServiceComb都会尝试通过File、Part、Resource中的文件名后缀进行自动判定。 +As long as the HttpHeaders.CONTENT\_TYPE is not set directly via ResponseEntity, ServiceComb will try to automatically determine the file name suffix in File, Part, and Resource. -ServiceComb使用java的mime type机制进行文件类型判定,如果业务场景中的文件后缀无法被识别,ServiceComb会默认处理为application/octet-stream +ServiceComb uses java's mime type mechanism for file type determination. If the file suffix in the business scenario cannot be identified, ServiceComb will default to application/octet-stream. -如果这不满足要求,假设文件后缀为xyz,期望文件类型为application/file-xyz,以下方式任选一种均可解决: +If this does not meet the requirements, assuming the file suffix is, and the expected file type is application/file-xyz, any of the following methods can be resolved: -### 1)通过Java的mime type机制扩展 +### 1)Expanding through Java's mime type mechanism -在META-INF目录下,创建mime.types文件,其内容为: +In the META-INF directory, create a mime. Types file with the contents: ``` application/file-xyz xyz ``` -### 2)在业务代码中通过Part指定 +### 2) Specify by Part in the business code ``` return new FilePart(null, file).contentType("application/file-xyz"); ``` -### 3)在业务代码中通过ResponseEntity指定 +### 3) specified in the business code by ResponseEntity ``` return ResponseEntity .ok() .header(HttpHeaders.CONTENT_TYPE, "application/file-xyz") .body(……); + .body(...); ``` -## 6.文件名 +## 6.File name -只要没有通过ResponseEntity直接设置HttpHeaders.CONTENT\_DISPOSITION,ServiceComb都会尝试通过File、Part、Resource中的文件名生成HttpHeaders.CONTENT\_DISPOSITION,假设文件名为file.txt,则生成的数据如下: +As long as HttpHeaders.CONTENT\_DISPOSITION is not set directly via ResponseEntity, ServiceComb will try to generate HttpHeaders.CONTENT\_DISPOSITION through the file names in File, Part, and Resource. Assuming the file name is file.txt, the generated data is as follows: ``` Content-Disposition: attachment;filename=file.txt;filename*=utf-8’’file.txt ``` -不仅仅生成filename,还生成了filename\*,这是因为如果文件名中出现了中文、空格,并且filename正确地做了encode,ie、chrome都没有问题,但是firefox直接将encode后的串当作文件名直接使用了。firefox按照[https://tools.ietf.org/html/rtf6266](https://tools.ietf.org/html/rtf6266),只对filename\*进行解码。 +Not only the filename is generated, but also filename\* is generated. This is because if there is Chinese, space, and filename correctly in the file name, i.e., chrome is fine, but firefox directly treats the string after the encoding as a text. The name of the item is used directly. Firefox only decodes filename\* according to [https://tools.ietf.org/html/rtf6266] (https://tools.ietf.org/html/rtf6266). -如果业务代码中直接设置Content-Disposition,需要自行处理多浏览器支持的问题。 +If Content-Disposition is set directly in the business code, you need to handle the problems supported by multiple browsers. -# 二、Consumer +# Second, Consumer -消费端统一使用org.apache.servicecomb.foundation.vertx.http.ReadStreamPart处理文件下载。 +The consumer side uses org.apache.servicecomb.foundation.vertx.http.ReadStreamPart to process file downloads. -## 1.透明RPC +## 1. Transparent RPC ``` -public interface ……{ - ReadStreamPart download1(……); - ReadStreamPart download2(……); +public interface ......{ + ReadStreamPart download1(...); + ReadStreamPart download2(...); } ``` ## 2.RestTemplate -以get为例: +Take get as an example: ``` ReadStreamPart part = restTemplate.getForObject(url, ReadStreamPart.class); ``` -## 3.从ReadStreamPart读取数据 +## 3. Read data from ReadStreamPart -ReadStreamPart提供了一系列方法,将数据流保存为本地数据: +ReadStreamPart provides a set of methods to save the data stream as local data: ``` org.apache.servicecomb.foundation.vertx.http.ReadStreamPart.saveAsBytes() @@ -146,13 +147,13 @@ org.apache.servicecomb.foundation.vertx.http.ReadStreamPart.saveToFile(String) org.apache.servicecomb.foundation.vertx.http.ReadStreamPart.saveToFile(File, OpenOptions) ``` -注意: +note: -* 在得到ReadStreamPart实例时,并没有完成文件内容的下载,调用save系列方法才开始真正从网络上读取文件数据。 +* When the ReadStreamPart instance is obtained, the file content is not downloaded. The save series method is called to start reading the file data from the network. -* 如果使用saveAsBytes、saveAsString,数据是直接保存在内存中的,如果下载的文件很大,会内存撑爆的风险。 +* If you use saveAsBytes, saveAsString, the data is directly stored in the memory; if the downloaded file is large, there will be a risk of memory explosion. -* save系列方法,返回的都是CompletableFuture对象: +* The save series method returns all CompletableFuture objects: - * 如果要阻塞等待下载完成,通过future.get\(\)即可 - * 如果通过future.whenComplete进行异步回调处理,要注意回调是发生在网络线程中的,此时需要遵守reactive的线程规则。 + * If you want to block waiting for the download to complete, you can use future.get\(\) + * If asynchronous callback processing is performed through future.whenComplete, be aware that callbacks occur in network threads, and you must follow the reactive thread rules.