Codename one 上传一张相机拍的照片到amazon s3 bucket
Codename one Upload a picture taken by the camera to amazon s3 bucket
原问题
我已经按照你的建议尝试过了,我有一些东西 运行 变成了几个问题。
以下是我所做的:filePath = Capture.capturePhoto(1024, -1);
我在 MutipartRequest 构造函数中传递 S3_BUCKET_URL 时遇到问题,所以我使用了 rq.setUrl(S3_BUCKET_URL)
我不得不添加 rq.setHttpMethod("PUT"); // 因为我收到 405 错误:不支持方法
最后我没有发现任何错误,而且我确实看到在我创建的存储桶下创建了一个子文件夹。我将 url 设置为“https://s3.amazonaws.com/bucket123/test/” 我看到已创建测试存储桶,但未上传图像文件。文件夹大小不是 0,因为它显示了文件的大小,但在该子文件夹中找不到图像文件。
当我尝试通过 S3 资源管理器访问该文件夹时,我得到了拒绝访问。 1. 我使用 S3 资源管理器手动创建了一个子文件夹并授予了读写权限,但是一旦从代号调用的 uploadFileToS3 方法我看到权限丢失了。
2. 所以我确实将 acl 更改为 "public-read-write" 仍然相同的效果。
如有遗漏请指教
谢谢。
修改问题
我已经修改了旧问题,并在 Sahi 的回答之后。
// Modified the url as following - full path including bucket name and key
private static final String S3_BUCKET_URL = "https://s3.amazonaws.com/my-bucket/myfile.jpg";
//String filePath = captured from Camera;
public void uploadFileToS3(String filePath, String uniqueFileName) {
MultipartRequest rq = new MultipartRequest();
rq.setUrl(S3_BUCKET_URL);
//rq.addArgument("acl", "private");
//rq.addArgument("key", uniqueFileName);
rq.addData(uniqueFileName, filePath, "image/jpeg");
rq.setReadResponseForErrors(true);
NetworkManager.getInstance().addToQueue(rq);
}
Now I do see that the file has been uploaded to the bucket as myfile.jpg under my bucket. The bucket has all the rights since the bucket is given rights to read and write also applied the permissions to sub folders.
Now the myfile.jpg lost all the permissions and I am not able to download that file even though I see it in the bucket.
I accessed it by the url but the file cannot be opened.
I am not sure what I am missing in the header or request. I am really trying to get this working but not getting where I wanted to. This is very important piece for the app I am working on.
Please provide any feedback.
Thank you.
--------------------------------------------------------------------------
添加代码
private static final String S3_BUCKET_URL = "https://s3.amazonaws.com/my-bucket/";
当我有上面的 url 时,我的存储桶被创建为未知对象(没有文件夹图标),但我确实看到文件大小是实际图像大小。
//String filePath = captured from Camera;
public void uploadFileToS3(String filePath, String uniqueFileName) {
//uniqueFileName including sub folder - subfolder/my-image.jpg
MultipartRequest rq = new MultipartRequest();
rq.setUrl(S3_BUCKET_URL);
rq.addArgument("acl", "public-read-write");
rq.addArgument("key", uniqueFileName);
rq.addData(uniqueFileName, filePath, "image/jpeg");
rq.setReadResponseForErrors(true);
NetworkManager.getInstance().addToQueue(rq);
}
看来我没有正确上传对象。我确实浏览了亚马逊文档,但找不到与通过 http 上传相关的任何内容。我真的被困住了,我希望能解决这个问题。您有任何可以简单上传到 s3 的工作代码吗?
More details: I am adding more detail to the question as I am still not able to resolve this.
// Original S3_BUCKET_URL
String S3_BUCKET_URL = "https://s3.amazonaws.com/my-bucket/";
// With this url I am getting 400 : Bad Request Error
// I added the uniqueFilename (key) to the url as
String uniqueFilename = "imageBucket/image12345.jpg";
String S3_BUCKET_URL = "https://s3.amazonaws.com/my-bucket /"+uniqueFilename;
//Now I do see the file I believe it's the file, the
//subfolder inherits the rights from bucket (read, write).
//Not the image file.
//When I click on the file using s3 client browser I got message
//prompted Access Denied.
// my function to call s3 bucket
public void takePicture()
{
String stringImg = Capture.capturePhoto(1024, -1);
MultipartRequest rq = new MultipartRequest();
rq.setUrl(S3_BUCKET_URL);
rq.addArgument("key", uniqueFilename );
rq.addArgument("acl", "public-read-write");
rq.setHttpMethod("PUT"); // If I don't specify this I am getting
// 405 : Method Not Allowed Error.
rq.addData("file", stringImg, "image/jpeg");
//Captured Image from camera
rq.setFilename("file", uniqueFilename);
NetworkManager.getInstance().addToQueue();
}
在这一点上,我相信我已经完成了所有建议的方法,但我仍然遇到同样的错误。我相信我没有做错任何事,我不想相信我是唯一一个尝试这样做的人:)
为了保留这个项目,我真的需要你的帮助来解决这个问题。我想知道是否有任何我可以在代号一中使用的 Amazon s3 sdk 或库。
请检查一下,让我知道这是否真的可以通过代号 1 实现。
谢谢。
在您的服务器上生成预签名 URL:
将 URL 传递给移动客户端。
IAmazonS3 client;
client = new AmazonS3Client(Amazon.RegionEndpoint.USEast1);
// Generate a pre-signed URL.
GetPreSignedUrlRequest request = new GetPreSignedUrlRequest
{
BucketName = bucketName,
Key = objectKey,
Verb = HttpVerb.PUT,
Expires = DateTime.Now.AddMinutes(5)
};
string url = null;
url = s3Client.GetPreSignedURL(request);
移动客户端可以使用旧的普通 PUT HTTP 请求将文件上传到 URL:
// Upload a file using the pre-signed URL.
HttpWebRequest httpRequest = WebRequest.Create(url) as HttpWebRequest;
httpRequest.Method = "PUT";
using (Stream dataStream = httpRequest.GetRequestStream())
{
// Upload object.
}
HttpWebResponse response = httpRequest.GetResponse() as HttpWebResponse;
您可以在 http://docs.aws.amazon.com/AmazonS3/latest/dev/UploadObjectPreSignedURLDotNetSDK.html
查看官方文档
我已经测试了这段代码,它应该可以工作,但是它取决于对代号一的修复来处理亚马逊的一些愚蠢行为 API:
Form hi = new Form("Upload");
Button upload = new Button("Upload");
hi.add(upload);
upload.addActionListener(e -> {
String file = Capture.capturePhoto();
if(file != null) {
try {
String uniqueFileName = "Image" + System.currentTimeMillis() + ".jpg";
MultipartRequest rq = new MultipartRequest();
rq.setUrl("https://s3.amazonaws.com/my-bucket/");
rq.addArgument("key", uniqueFileName);
rq.addArgument("acl", "private");
rq.addData("file", file, "image/jpeg");
rq.setReadResponseForErrors(true);
NetworkManager.getInstance().addToQueueAndWait(rq);
if(rq.getResponseCode() != 200 && rq.getResponseCode() != 204) {
System.out.println("Error response: " + new String(rq.getResponseData()));
}
ToastBar.showMessage("Upload completed", FontImage.MATERIAL_INFO);
} catch(IOException err) {
Log.e(err);
}
}
});
hi.show();
当 运行 下面的代码(使用 post)时,我没有收到您描述的错误,相反,我收到了来自 Amazon 的错误消息,指示密钥的顺序不正确。显然亚马逊依赖于提交字段的顺序,这是该死的愚蠢。不幸的是,我们在您添加参数时忽略了该顺序,因为这是一个 post 请求代码来解决这个问题,这是非常重要的。
我已经对代号一进行了修复,该修复将尊重添加参数的自然顺序,但由于我们已经在本周发布,因此只会在下周五(2016 年 12 月 23 日)发布。所以上面的代码应该在更新后按预期工作。
旧答案供参考
我还没有测试过这个,但是像这样的东西应该可以工作:
private static final String S3_BUCKET_URL = "https://s3.amazonaws.com/my-bucket/";
public void uploadFileToS3(String filePath, String uniqueFileName) {
MultipartRequest rq = new MultipartRequest(S3_BUCKET_URL);
rq.addArgument("acl", "private");
rq.addArgument("key", uniqueFileName);
rq.addData("file", filePath, "image/jpeg");
rq.setFilename("file", uniqueFileName);
rq.setReadResponseForErrors(true);
NetworkManager.getInstance().addToQueue(rq);
}
请注意,这不会进行授权,因此它假定存储桶至少可以进行写入访问。
原问题
我已经按照你的建议尝试过了,我有一些东西 运行 变成了几个问题。 以下是我所做的:filePath = Capture.capturePhoto(1024, -1);
我在 MutipartRequest 构造函数中传递 S3_BUCKET_URL 时遇到问题,所以我使用了 rq.setUrl(S3_BUCKET_URL)
我不得不添加 rq.setHttpMethod("PUT"); // 因为我收到 405 错误:不支持方法
最后我没有发现任何错误,而且我确实看到在我创建的存储桶下创建了一个子文件夹。我将 url 设置为“https://s3.amazonaws.com/bucket123/test/” 我看到已创建测试存储桶,但未上传图像文件。文件夹大小不是 0,因为它显示了文件的大小,但在该子文件夹中找不到图像文件。
当我尝试通过 S3 资源管理器访问该文件夹时,我得到了拒绝访问。 1. 我使用 S3 资源管理器手动创建了一个子文件夹并授予了读写权限,但是一旦从代号调用的 uploadFileToS3 方法我看到权限丢失了。 2. 所以我确实将 acl 更改为 "public-read-write" 仍然相同的效果。
如有遗漏请指教
谢谢。
修改问题 我已经修改了旧问题,并在 Sahi 的回答之后。
// Modified the url as following - full path including bucket name and key
private static final String S3_BUCKET_URL = "https://s3.amazonaws.com/my-bucket/myfile.jpg";
//String filePath = captured from Camera;
public void uploadFileToS3(String filePath, String uniqueFileName) {
MultipartRequest rq = new MultipartRequest();
rq.setUrl(S3_BUCKET_URL);
//rq.addArgument("acl", "private");
//rq.addArgument("key", uniqueFileName);
rq.addData(uniqueFileName, filePath, "image/jpeg");
rq.setReadResponseForErrors(true);
NetworkManager.getInstance().addToQueue(rq);
}
Now I do see that the file has been uploaded to the bucket as myfile.jpg under my bucket. The bucket has all the rights since the bucket is given rights to read and write also applied the permissions to sub folders.
Now the myfile.jpg lost all the permissions and I am not able to download that file even though I see it in the bucket.
I accessed it by the url but the file cannot be opened.
I am not sure what I am missing in the header or request. I am really trying to get this working but not getting where I wanted to. This is very important piece for the app I am working on.
Please provide any feedback.
Thank you.
--------------------------------------------------------------------------
添加代码
private static final String S3_BUCKET_URL = "https://s3.amazonaws.com/my-bucket/";
当我有上面的 url 时,我的存储桶被创建为未知对象(没有文件夹图标),但我确实看到文件大小是实际图像大小。
//String filePath = captured from Camera;
public void uploadFileToS3(String filePath, String uniqueFileName) {
//uniqueFileName including sub folder - subfolder/my-image.jpg
MultipartRequest rq = new MultipartRequest();
rq.setUrl(S3_BUCKET_URL);
rq.addArgument("acl", "public-read-write");
rq.addArgument("key", uniqueFileName);
rq.addData(uniqueFileName, filePath, "image/jpeg");
rq.setReadResponseForErrors(true);
NetworkManager.getInstance().addToQueue(rq);
}
看来我没有正确上传对象。我确实浏览了亚马逊文档,但找不到与通过 http 上传相关的任何内容。我真的被困住了,我希望能解决这个问题。您有任何可以简单上传到 s3 的工作代码吗?
More details: I am adding more detail to the question as I am still not able to resolve this.
// Original S3_BUCKET_URL
String S3_BUCKET_URL = "https://s3.amazonaws.com/my-bucket/";
// With this url I am getting 400 : Bad Request Error
// I added the uniqueFilename (key) to the url as
String uniqueFilename = "imageBucket/image12345.jpg";
String S3_BUCKET_URL = "https://s3.amazonaws.com/my-bucket /"+uniqueFilename;
//Now I do see the file I believe it's the file, the
//subfolder inherits the rights from bucket (read, write).
//Not the image file.
//When I click on the file using s3 client browser I got message
//prompted Access Denied.
// my function to call s3 bucket
public void takePicture()
{
String stringImg = Capture.capturePhoto(1024, -1);
MultipartRequest rq = new MultipartRequest();
rq.setUrl(S3_BUCKET_URL);
rq.addArgument("key", uniqueFilename );
rq.addArgument("acl", "public-read-write");
rq.setHttpMethod("PUT"); // If I don't specify this I am getting
// 405 : Method Not Allowed Error.
rq.addData("file", stringImg, "image/jpeg");
//Captured Image from camera
rq.setFilename("file", uniqueFilename);
NetworkManager.getInstance().addToQueue();
}
在这一点上,我相信我已经完成了所有建议的方法,但我仍然遇到同样的错误。我相信我没有做错任何事,我不想相信我是唯一一个尝试这样做的人:)
为了保留这个项目,我真的需要你的帮助来解决这个问题。我想知道是否有任何我可以在代号一中使用的 Amazon s3 sdk 或库。
请检查一下,让我知道这是否真的可以通过代号 1 实现。
谢谢。
在您的服务器上生成预签名 URL:
将 URL 传递给移动客户端。
IAmazonS3 client; client = new AmazonS3Client(Amazon.RegionEndpoint.USEast1); // Generate a pre-signed URL. GetPreSignedUrlRequest request = new GetPreSignedUrlRequest { BucketName = bucketName, Key = objectKey, Verb = HttpVerb.PUT, Expires = DateTime.Now.AddMinutes(5) }; string url = null; url = s3Client.GetPreSignedURL(request);
移动客户端可以使用旧的普通 PUT HTTP 请求将文件上传到 URL:
// Upload a file using the pre-signed URL. HttpWebRequest httpRequest = WebRequest.Create(url) as HttpWebRequest; httpRequest.Method = "PUT"; using (Stream dataStream = httpRequest.GetRequestStream()) { // Upload object. } HttpWebResponse response = httpRequest.GetResponse() as HttpWebResponse;
您可以在 http://docs.aws.amazon.com/AmazonS3/latest/dev/UploadObjectPreSignedURLDotNetSDK.html
查看官方文档我已经测试了这段代码,它应该可以工作,但是它取决于对代号一的修复来处理亚马逊的一些愚蠢行为 API:
Form hi = new Form("Upload");
Button upload = new Button("Upload");
hi.add(upload);
upload.addActionListener(e -> {
String file = Capture.capturePhoto();
if(file != null) {
try {
String uniqueFileName = "Image" + System.currentTimeMillis() + ".jpg";
MultipartRequest rq = new MultipartRequest();
rq.setUrl("https://s3.amazonaws.com/my-bucket/");
rq.addArgument("key", uniqueFileName);
rq.addArgument("acl", "private");
rq.addData("file", file, "image/jpeg");
rq.setReadResponseForErrors(true);
NetworkManager.getInstance().addToQueueAndWait(rq);
if(rq.getResponseCode() != 200 && rq.getResponseCode() != 204) {
System.out.println("Error response: " + new String(rq.getResponseData()));
}
ToastBar.showMessage("Upload completed", FontImage.MATERIAL_INFO);
} catch(IOException err) {
Log.e(err);
}
}
});
hi.show();
当 运行 下面的代码(使用 post)时,我没有收到您描述的错误,相反,我收到了来自 Amazon 的错误消息,指示密钥的顺序不正确。显然亚马逊依赖于提交字段的顺序,这是该死的愚蠢。不幸的是,我们在您添加参数时忽略了该顺序,因为这是一个 post 请求代码来解决这个问题,这是非常重要的。
我已经对代号一进行了修复,该修复将尊重添加参数的自然顺序,但由于我们已经在本周发布,因此只会在下周五(2016 年 12 月 23 日)发布。所以上面的代码应该在更新后按预期工作。
旧答案供参考
我还没有测试过这个,但是像这样的东西应该可以工作:
private static final String S3_BUCKET_URL = "https://s3.amazonaws.com/my-bucket/";
public void uploadFileToS3(String filePath, String uniqueFileName) {
MultipartRequest rq = new MultipartRequest(S3_BUCKET_URL);
rq.addArgument("acl", "private");
rq.addArgument("key", uniqueFileName);
rq.addData("file", filePath, "image/jpeg");
rq.setFilename("file", uniqueFileName);
rq.setReadResponseForErrors(true);
NetworkManager.getInstance().addToQueue(rq);
}
请注意,这不会进行授权,因此它假定存储桶至少可以进行写入访问。