Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/188.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Android HttpURLConnection放到Amazon AWS S3403错误_Java_Android_Amazon S3_Httpurlconnection_Put - Fatal编程技术网

Java Android HttpURLConnection放到Amazon AWS S3403错误

Java 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

使用带有签名、过期和AccessKey的预签名URL将文件上载到AmazonS3,使用以下代码,我可以使用普通java代码上载文件,但Android中的相同代码会给我403错误。预签名的URL是使用Amazon SDK生成的

我读过 但我不知道应该使用什么header参数,我猜在android中,它是在服务器拒绝的请求中设置header

    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"