Java Android HttpURLConnection放到Amazon AWS S3403错误
使用带有签名、过期和AccessKey的预签名URL将文件上载到AmazonS3,使用以下代码,我可以使用普通java代码上载文件,但Android中的相同代码会给我403错误。预签名的URL是使用Amazon SDK生成的 我读过 但我不知道应该使用什么header参数,我猜在android中,它是在服务器拒绝的请求中设置headerJava Android HttpURLConnection放到Amazon AWS S3403错误,java,android,amazon-s3,httpurlconnection,put,Java,Android,Amazon S3,Httpurlconnection,Put,使用带有签名、过期和AccessKey的预签名URL将文件上载到AmazonS3,使用以下代码,我可以使用普通java代码上载文件,但Android中的相同代码会给我403错误。预签名的URL是使用Amazon SDK生成的 我读过 但我不知道应该使用什么header参数,我猜在android中,它是在服务器拒绝的请求中设置header HttpURLConnection connection=(HttpURLConnection) url.openConnection(); c
HttpURLConnection connection=(HttpURLConnection) url.openConnection();
connection.setDoOutput(true);
connection.setRequestMethod("PUT");
OutputStreamWriter out = new OutputStreamWriter(connection.getOutputStream());
out.write("This text uploaded as object.");
out.close();
int responseCode = connection.getResponseCode();
例外情况:403;签名不匹配:-o
有人遇到过这个问题吗?
或者更多详细信息,这些标题参数是在后台从android库添加的?您使用的是?它有正确的API,我怀疑使用它上传到S3会更容易,而且更安全。我相信他们也有教程、代码示例和演示
你可能还需要一个和其他课程。A将帮助您从电话客户端上传文件,并在您的情况下非常有用。因此,经过一些尝试/错误/搜索后,发现问题: 在创建预签名的URL时,指定内容类型(基于您的数据)很重要,否则您将继续获得403签名不匹配,您在此处指定的内容类型应在HttpURLConnection对象中提及
string s3url = s3Client.GetPreSignedURL(new GetPreSignedUrlRequest()
.WithBucketName(bucketName)
.WithKey(keyName)
.WithContentType("application/octet-stream") // IMPORTANT
.WithVerb(HttpVerb.PUT)
.WithExpires(<YOUR EXPIRATION TIME>);
string s3url=s3Client.GetPreSignedURL(新的GetPreSignedUrlRequest()
.带bucketName(bucketName)
.WithKey(键名)
.WithContentType(“应用程序/八位字节流”)//重要
.WithVerb(HttpVerb.PUT)
.WithExpires();
在您的连接中..在“PUT”之后将其添加到有问题的代码中
connection.setFixedLengthStreamingMode();
setRequestProperty(“内容类型”、“应用程序/八位字节流”);
选中此项,最新的SDK应允许您设置内容类型以生成URL:
private static URL generateRUL(String objectKey, String ACCESS_KEY, String SECRET_KEY, String BUCKET_NAME) {
AmazonS3 s3Client = new AmazonS3Client(new BasicAWSCredentials(ACCESS_KEY, SECRET_KEY));
URL url = null;
try {
GeneratePresignedUrlRequest request = new GeneratePresignedUrlRequest(BUCKET_NAME, objectKey);
request.setMethod(com.amazonaws.HttpMethod.PUT);
request.setExpiration(new Date( System.currentTimeMillis() + (60 * 60 * 1000)));
// Very important ! It won't work without adding this!
// And request.addRequestParameter("Content-Type", "application/octet-stream") won't work neither
request.setContentType("application/octet-stream");
url = s3Client.generatePresignedUrl(request );
} catch (AmazonServiceException exception) {
} catch (AmazonClientException ace) { }
return url;
}
上载文件的方式:
public int upload(byte[] fileBytes, URL url) {
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoOutput(true);
connection.setRequestMethod("PUT");
connection.setRequestProperty("Content-Type", "application/octet-stream"); // Very important ! It won't work without adding this!
OutputStream output = connection.getOutputStream();
InputStream input = new ByteArrayInputStream(fileBytes);
byte[] buffer = new byte[4096];
int length;
while ((length = input.read(buffer)) > 0) {
output.write(buffer, 0, length);
}
output.flush();
return connection.getResponseCode();
}
请按如下方式设置您的内容类型:
connection.setRequestProperty("Content-Type"," ");
因为HttpsUrlConnection的默认值会自动将内容类型生成为:
"Content-Type: application/x-www-form-urlencoded"
这将导致签名不匹配。我也遇到了同样的问题。以下是我面临此问题的原因: 预签名的URL允许您访问URL中标识的对象, 前提是预签名URL的创建者有权 访问该对象。也就是说,如果您收到要上载的预签名URL 一个对象,只有当对象的创建者 预签名URL具有上载该对象所需的权限
一旦我给了我的lambda函数PutObject权限,它就可以了!限制应用程序的大小,我正在避免在设备上使用SDK,我不想使用SDK来执行这一操作。你有没有解决这个问题的解决方案??@MayankI,你有没有得到任何解决方案?不…这对我来说是不管用的…我可以上传你使用mac os运行的JAVA客户端。但是使用相同的url,我得到403错误。这意味着Android环境和mac os不同。
"Content-Type: application/x-www-form-urlencoded"