【发布时间】:2015-12-16 06:25:41
【问题描述】:
我正在尝试将 Image 从我的 Android APP 上传到 Amazon AWS S3,我需要使用 AWS Restful API。
我正在使用Retrofit 2 提出请求。
我的应用程序与 Amazon S3 成功连接并按预期执行请求,但是当我尝试从 Bucket 查看Image 时,图片没有打开。我将Image 下载到我的电脑并尝试打开,但不断收到图像已损坏的消息。
下面看看我的完整代码。
我的 Gradle 依赖项
compile 'com.squareup.retrofit:retrofit:2.0.0-beta1'
compile 'com.squareup.retrofit:converter-gson:2.0.0-beta1'
compile 'net.danlew:android.joda:2.8.2'
这里创建了一个文件并开始请求
File file = new File(mCurrentPhotoPath);
RequestBody body = RequestBody.create(MediaType.parse("image/jpeg"), file);
uploadImage(body, "photo_name.jpeg");
改造界面
public interface AwsS3 {
@Multipart
@PUT("/{Key}")
Call<String> upload(@Path("Key") String Key,
@Header("Content-Length") long length,
@Header("Accept") String accept,
@Header("Host") String host,
@Header("Date") String date,
@Header("Content-type") String contentType,
@Header("Authorization") String authorization,
@Part("Body") RequestBody body);
}
Utils 类挂载凭据
public class AWSOauth {
public static String getOAuthAWS(Context context, String fileName) throws Exception{
String secret = context.getResources().getString(R.string.s3_secret);
String access = context.getResources().getString(R.string.s3_access_key);
String bucket = context.getResources().getString(R.string.s3_bucket);
return gerateOAuthAWS(secret, access, bucket,fileName);
}
private static String gerateOAuthAWS(String secretKey, String accessKey, String bucket, String imageName) throws Exception {
String contentType = "image/jpeg";
DateTimeFormatter fmt = DateTimeFormat.forPattern("EEE', 'dd' 'MMM' 'yyyy' 'HH:mm:ss' 'Z").withLocale(Locale.US);
String ZONE = "GMT";
DateTime dt = new DateTime();
DateTime dtLondon = dt.withZone(DateTimeZone.forID(ZONE)).plusHours(1);
String formattedDate = dtLondon.toString(fmt);
String resource = "/" + bucket + "/" + imageName;
String stringToSign = "PUT" + "\n\n" + contentType + "\n" + formattedDate + "\n" + resource;
Mac hmac = Mac.getInstance("HmacSHA1");
hmac.init(new SecretKeySpec(secretKey.getBytes("UTF-8"), "HmacSHA1"));
String signature = ( Base64.encodeToString(hmac.doFinal(stringToSign.getBytes("UTF-8")), Base64.DEFAULT)).replaceAll("\n", "");
String oauthAWS = "AWS " + accessKey + ":" + signature;
return oauthAWS;
}
}
最后提出请求的方法
public void uploadImage(RequestBody body, String fileName){
String bucket = getString(R.string.s3_bucket);
Retrofit restAdapter = new Retrofit.Builder()
.baseUrl("http://" + bucket + ".s3.amazonaws.com")
.addConverterFactory(GsonConverterFactory.create())
.build();
AwsS3 service = restAdapter.create(AwsS3.class);
DateTimeFormatter fmt = DateTimeFormat.forPattern("EEE', 'dd' 'MMM' 'yyyy' 'HH:mm:ss' 'Z").withLocale(Locale.US);
String ZONE = "GMT";
DateTime dt = new DateTime();
DateTime dtLondon = dt.withZone(DateTimeZone.forID(ZONE)).plusHours(1);
String formattedDate = dtLondon.toString(fmt);
try {
String oauth = AWSOauth.getOAuthAWS(getApplicationContext(), fileName);
Call<String> call = service.upload(fileName, body.contentLength(), "/**", bucket + ".s3.amazonaws.com", formattedDate, body.contentType().toString(), oauth, body);
call.enqueue(new Callback<String>() {
@Override
public void onResponse(Response<String> response) {
Log.d("tag", "response : " + response.body());
}
@Override
public void onFailure(Throwable t) {
Log.d("tag", "response : " + t.getMessage());
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
感谢任何帮助,在此先感谢!
【问题讨论】:
-
没有抛出异常?请求的状态码是什么?
-
无异常,图片上传,响应200 OK。
-
你说图片上传成功,是不是也对比了md5sum?上传成功后,尝试比较你上传的对象的md5sum。这样你就可以确定对象根本没有改变。你也说
when I try open the image but it is damaged..你想在桌面上查看它吗? -
我也尝试打开浏览器和桌面!
-
@A.Anderson 您是否有您尝试上传的图像/对象的样本(任何公共链接?)?
标签: android rest amazon-s3 retrofit