Я пытаюсь загрузить файл с Amazon S3.
Я хочу, чтобы пользователь посетил мое приложение через GET API.
Приложение, в свою очередь, получает контент от S3 и возвращает его пользователю в виде загружаемого файла.
Примечание:
Я не хочу хранить файл локально на моем сервере, я хочу, чтобы он транслировался из amazon s3 напрямую конечному пользователю
Я пытался с файлом около 300 МБ, если я запускаю его локально, как показано ниже
занимает мало места, т. е. локально присутствует один и тот же файл
@GET
@Path("/pdfdownload")
@Produces("application/pdf")
public Response getFile() {
File file = new File('/pathToFile'); // in local
ResponseBuilder response = Response.ok((Object) file);
response.header("Content-Disposition", "attachment; filename=file.pdf");
return response.build();
}
Но когда я загружаю то же самое с Amazon s3, память моего сервера tomcat быстро увеличивается до 600 МБ, я думаю, что я передаю содержимое, но когда я смотрю на используемую память, я сомневаюсь в этом
Я что-то упустил?
@GET
@Path("/pdfdownload")
@Produces("application/pdf")
public Response getFile2() {
final S3Object s3Object = getAmazonS3Object();// AWS S3
final S3ObjectInputStream s3is = s3Object.getObjectContent();
final StreamingOutput stream = new StreamingOutput() {
@Override
public void write(OutputStream os) throws IOException, WebApplicationException {
byte[] read_buf = new byte[1024];
int read_len = 0;
while ((read_len = s3is.read(read_buf)) > 0) {
os.write(read_buf, 0, read_len);
}
os.close();
s3is.close();
}
};
ResponseBuilder response = Response.ok(stream);
response.header("Content-Disposition", "attachment; filename=file.pdf");
return response.build();
}
private S3Object getAmazonS3Object() {
AWSCredentials credentials = new BasicAWSCredentials("accesskey",
"secretkey");
try {
AmazonS3 s3 = new AmazonS3Client(credentials);
S3Object s3object = s3.getObject(new GetObjectRequest("bucketName", "filename_WithExtension"));
return s3object;
} catch (AmazonServiceException e) {
System.err.println(e.getErrorMessage());
System.exit(1);
}
System.out.println("Done!");
return null;
}
Пом:
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-server</artifactId>
<version>1.8</version>
</dependency>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk</artifactId>
<version>1.11.542</version>
</dependency>
Аналогично этому S3 скачать pdf - REST API
Я не хочу использовать PreSignedURl: https://docs.aws.amazon.com/AmazonS3/latest/dev/ShareObjectPreSignedURLJavaSDK.html
Пожалуйста, смотрите эту статью о потоковой передаче: https://memorynotfound.com/low-level-streaming-with-jax-rs-streamingoutput/
Может, кто-нибудь поможет, почему память всплывает?