我想公开一个API,以将S3存储桶文件内容作为流下载到其使用者。 API URL类似于/ downloadfile / **,这是GET请求。
这是我到目前为止编写的控制器伪代码,这始终使我出现406错误。
@GetMapping(value = "/downloadfile/**", produces = { MediaType.APPLICATION_OCTET_STREAM_VALUE })
public ResponseEntity<Object> downloadFile(HttpServletRequest request) {
//reads the content from S3 bucket and returns a S3ObjectInputStream
S3ObjectInputStream object = null;
object = publishAmazonS3.getObject("12345bucket", "/logs/file1.log").getObjectContent();
return object
}
这里有什么建议,我做错了什么?
答案 0 :(得分:0)
您可以使用以下示例进行解决
import java.io.ByteArrayOutputStream;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import com.grokonez.s3.services.S3Services;
@RestController
public class DownloadFileController {
@Autowired
S3Services s3Services;
/*
* Download Files
*/
@GetMapping("/api/file/{keyname}")
public ResponseEntity<byte[]> downloadFile(@PathVariable String keyname) {
ByteArrayOutputStream downloadInputStream = s3Services.downloadFile(keyname);
return ResponseEntity.ok().contentType(contentType(keyname))
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + keyname + "\"")
.body(downloadInputStream.toByteArray());
}
private MediaType contentType(String keyname) {
String[] arr = keyname.split("\\.");
String type = arr[arr.length - 1];
switch (type) {
case "txt":
return MediaType.TEXT_PLAIN;
case "png":
return MediaType.IMAGE_PNG;
case "jpg":
return MediaType.IMAGE_JPEG;
default:
return MediaType.APPLICATION_OCTET_STREAM;
}
}
}
答案 1 :(得分:0)
我可以使用Spring的StreamingResponseBody
类将文件作为流下载。
这是我使用的代码:
@GetMapping(value = "/downloadfile/**", produces = { MediaType.APPLICATION_OCTET_STREAM_VALUE })
public ResponseEntity<S3ObjectInputStream> downloadFile(HttpServletRequest request) {
//reads the content from S3 bucket and returns a S3ObjectInputStream
S3Object object = publishAmazonS3.getObject("12345bucket", "/logs/file1.log");
S3ObjectInputStream finalObject = object.getObjectContent();
final StreamingResponseBody body = outputStream -> {
int numberOfBytesToWrite = 0;
byte[] data = new byte[1024];
while ((numberOfBytesToWrite = finalObject.read(data, 0, data.length)) != -1) {
System.out.println("Writing some bytes..");
outputStream.write(data, 0, numberOfBytesToWrite);
}
finalObject.close();
};
return new ResponseEntity<>(body, HttpStatus.OK);
}
测试流传输是否正确完成的方法是下载大约400mb的文件。通过传递vm选项将Xmx减少到256mb。现在,比较使用和不使用StreamingResponseBody
的下载功能,使用常规OutputStream编写内容时,您将得到OutofMemoryError