[英]Play 2.3.x: Non-blocking image upload to Amazon S3
I am wondering what the correct way with Play 2.3.x (Java) is to upload images to Amazon S3 in a non-blocking way. 我想知道Play 2.3.x(Java)的正确方法是以非阻塞方式将图像上传到Amazon S3。 Right now I am wrapping the amazons3.putObject method inside a promise.
现在,我将amazons3.putObject方法包装在promise中。 However I fear that I am basically just blocking another thread with this logic.
但是我担心我基本上只是用这种逻辑阻塞另一个线程。 My code looks like following:
我的代码如下:
return Promise.promise(
new Function0<Boolean>() {
public Boolean apply() {
if (S3Plugin.amazonS3 != null) {
try {
PutObjectRequest putObjectRequest = new PutObjectRequest(
S3Plugin.s3Bucket, name + "." + format, file.getFile());
ObjectMetadata metadata = putObjectRequest.getMetadata();
if(metadata == null) {
metadata = new ObjectMetadata();
}
metadata.setContentType(file.getContentType());
putObjectRequest.setMetadata(metadata);
putObjectRequest.withCannedAcl(CannedAccessControlList.PublicRead);
S3Plugin.amazonS3.putObject(putObjectRequest);
return true;
} catch (AmazonServiceException e) {
// error uploading image to s3
Logger.error("AmazonServiceException: " + e.toString());
} catch (AmazonClientException e) {
// error uploading image to s3
Logger.error("AmazonClientException: " + e.toString());
}
}
return false;
}
}
);
What is the best way to do the upload process non-blocking? 阻止上传过程的最佳方法是什么? The Amazon library also provides the TransferManager.class for asynchronous uploads but I am not sure how to utilize this in a non-blocking way either...
亚马逊图书馆还提供了用于异步上传的TransferManager.class,但是我也不知道如何以非阻塞方式利用它。
SOLUTION: After spending quite a while figuring out how to utilize the Promise/Future in Java, I came up with following solution thanks to Will Sargent: 解决方案:在花了很长时间弄清楚如何在Java中利用Promise / Future之后,由于Will Sargent,我提出了以下解决方案:
import akka.dispatch.Futures;
final scala.concurrent.Promise<Boolean> promise = Futures.promise();
... create AmazonS3 upload object ...
upload.addProgressListener(new ProgressListener() {
@Override
public void progressChanged(ProgressEvent progressEvent) {
if(progressEvent.getEventCode() == ProgressEvent.COMPLETED_EVENT_CODE) {
promise.success(true);
}
else if(progressEvent.getEventCode() == ProgressEvent.FAILED_EVENT_CODE) {
promise.success(false);
}
}
});
return Promise.wrap(promise.future());
Important to note is that I have to use the scala promise and not the play framework promise. 需要注意的重要一点是,我必须使用scala Promise,而不是play framework Promise。 The return value however is a play.libs.F.Promise.
但是,返回值是play.libs.F.Promise。
You can do the upload process and return a Future by creating a Promise, returning the promise's future, and only writing to the promise in the TransferManager's progress listener: 您可以执行上传过程,并通过创建一个Promise,返回Promise的Future并仅在TransferManager的进度侦听器中写入Promise来返回Future:
Examples of promises / futures: http://docs.scala-lang.org/overviews/core/futures.html 承诺/期货的示例: http : //docs.scala-lang.org/overviews/core/futures.html
Return the Scala future from Promise: http://www.playframework.com/documentation/2.3.x/api/java/play/libs/F.Promise.html#wrapped() 从Promise返回Scala的未来: http : //www.playframework.com/documentation/2.3.x/api/java/play/libs/F.Promise.html#wrapped()
TransferManager docs: http://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/s3/transfer/TransferManager.html TransferManager文档: http : //docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/s3/transfer/TransferManager.html
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.