我正在尝试使用我从API获得的预先签名的网址将图像从Android设备的图库上传到S3存储桶。
尝试上传图片时出现403 - Forbidden错误。以下是我的代码。
改造界面:
// Upload image to s3
@PUT("{uploadUri}")
Call<ResponseBody> uploadImage(
@Path("uploadUri") String uploadUri,
@Body File file
);
活动的相关代码:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
...
Button uploadBtn = (Button)findViewById(R.id.uploadbtn);
uploadBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(
Intent.createChooser(intent, "Select Picture"),
PICK_IMAGE_FROM_GALLERY_REQUEST);
}
});
}
public void uploadFile(Uri fileUri){
originalFile = FileUtils.getFile(this, fileUri);
File file = new File(originalFile.getPath());
//Create retrofit instance
Retrofit.Builder builder = new Retrofit.Builder()
.baseUrl(baseURL)
.addConverterFactory(GsonConverterFactory.create());
Retrofit retrofit = builder.build();
ApiInterface client = retrofit.create(ApiInterface.class);
Call<ResponseBody> call = client.uploadImage(uploadUri, file);
call.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
int statusCode = response.code();
if(statusCode == 200){
Toast.makeText(TestActivity.this, "Success!", Toast.LENGTH_SHORT).show();
}
else{
Toast.makeText(TestActivity.this, "Failure " + statusCode, Toast.LENGTH_SHORT).show();
Log.d("Failure: ", response.message());
Log.d("Failure: ", response.headers().toString());
}
}
@Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
Toast.makeText(TestActivity.this, "Failure", Toast.LENGTH_SHORT).show();
Log.d("Failure: ", t.getMessage());
t.printStackTrace();
}
});
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(requestCode == PICK_IMAGE_FROM_GALLERY_REQUEST && resultCode == RESULT_OK && data != null && data.getData() != null){
Uri uri = data.getData();
Log.d("uri: ", uri.toString());
ContentResolver cr = getContentResolver();
String mimetype = cr.getType(uri);
Log.d("mimetype: ", mimetype);
uploadFile(uri);
}
}
我从logcat获得的内容:
09-26 11:00:07.869 3295-3295/com.example.erawi D/SignedRequest::
https://test-name.s3.amazonaws.com/59ca33381cd9961425046d3c5b?AWSAccessKeyId=AKIAIAOASKDVRB2VL7LQ&Content-Type=image%2Fpng&Expires=1506423668&Signature=8JKskq%2BZLiYItas8k4%2FoQpRgKhk%3D&x-amz-acl=public-read
09-26 11:00:07.869 3295-3295/com.example.erawi D/URL:: https://test-name.s3.amazonaws.com/59ca33381cd9961425046d3c5b
09-26 11:00:17.394 3295-3295/com.example.erawi D/uri:: content://com.android.providers.media.documents/document/image%3A102
09-26 11:00:17.415 3295-3295/com.example.erawi D/mimetype:: image/png
09-26 11:00:18.088 3295-3295/com.example.erawi D/Failure:: Forbidden
09-26 11:00:18.088 3295-3295/com.example.erawi D/Failure:: x-amz-request-id: D444F94AS5C3BAF2
x-amz-id-2: MM6KkMJ1PSvDVo86A4123Sf0InM0S/FUP1czIxpvaOdRJnhcgWqwQeu3bkS4puTDlrBpZS6JX/s=
Content-Type: application/xml
Transfer-Encoding: chunked
Date: Tue, 26 Sep 2017 11:00:17 GMT
Connection: close
Server: AmazonS3
文件上传在浏览器中使用javascript但在android中没有。
配置存储桶:
<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
<AllowedOrigin>*</AllowedOrigin>
<AllowedMethod>GET</AllowedMethod>
<AllowedMethod>POST</AllowedMethod>
<AllowedMethod>PUT</AllowedMethod>
<AllowedHeader>*</AllowedHeader>
</CORSRule>
</CORSConfiguration>