AWS S3 REST API与Android改造V2库,上传的图片被损坏 [英] AWS S3 Rest API with Android Retrofit V2 library, uploaded image is damaged
问题描述
我想上传图片
从我的 Android应用程序到Amazon AWS S3 ,我需要使用 AWS REST的API
I'm trying upload a Image
from my Android APP to Amazon AWS S3 and I need use AWS Restful API.
我使用改造2 作出的要求。
我的应用程序可以成功地与亚马逊S3 的连接和按预期执行的请求,但是当我尝试从图片 >斗,画面不会打开。我下载了图片
来我的电脑,并试图打开,但继续得到该图像已损坏的消息。
My application is connecting successfully with Amazon S3 and performing the request as expected, but when I try to view the Image
from the Bucket, the picture does not open. I downloaded the Image
to my pc and tried to open but keep getting the message that the image is corrupted.
让我们看看我的完整code波纹管。
Lets see my complete code bellow.
我的摇篮依赖
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();
}
}
我AP preciate任何帮助,在此先感谢!
I appreciate any helps, thanks in advance!
推荐答案
我也有同样的问题,因为我用小提琴手检查HTTP请求的内容,我发现改造2.0.0β1的具有1.9.0不同。
I have the same problem, and as I use Fiddler checked the HTTP request content, I found retrofit 2.0.0 beta1 has a different with 1.9.0.
在我的问题,HTTP请求的内容prevent服务器的不同得到正确的数据。
In my problem, the different of HTTP request content prevent server get the correct data.
为了使同一个HTTP请求的内容,我也用改装2.0.0下一步deta1。
In order to make a same HTTP request content, i do next steps using retrofit 2.0.0 deta1.
在改造服务,添加一个窗体数据报头的HTTP请求;
@Headers("Content-Type: multipart/form-data;boundary=95416089-b2fd-4eab-9a14-166bb9c5788b")
INT改造2.0.0 deta1
,使用的标题 @Multipart
会得到这样的数据:
int retrofit 2.0.0 deta1
, the header using @Multipart
will get a data like this:
内容类型:多重/混合
作为deafult值是混合的,没有边界的称号。
as the deafult value is mixed, and has no boundary title.
不要使用 @Multipart
来上传文件,只需使用 @Body
RequestBody
Do not using @Multipart
to upload file, just using @Body
RequestBody
如果您在使用 @Multipart
来请求服务器,你必须通过
if you using @Multipart
to request Server, you have to pass param(file) through
@Part(键)
,那么一个新的问题,你会得到。可能是改造2.0.0beta1有BUG ... @Multipart
产生不好的http请求编译1.9.0。
@Part(key)
, then a new problem you will get. May be retrofit 2.0.0beta1 has a BUG ..., @Multipart
generate a bad http request compile with 1.9.0.
当你调用该方法,则需要通过MultipartRequestBody到@Body RequestBody
使用 MultipartBuilder
来创建一个 MultipartRequestBody
,当你新的 MultipartBuilder
,称此consturt:
Using MultipartBuilder
to create a MultipartRequestBody
, when you new MultipartBuilder
, call this consturt:
new MultipartBuilder("95416089-b2fd-4eab-9a14-166bb9c5788b")
该参数是将 INT @headers(边界=)
builder.addFormDataPart(String name, String filename, RequestBody value)
此方法将有助于形成象下面这样的数据INT HTTP请求的内容:
This method will help form a data like below int HTTP request content:
内容处置:表格数据; NAME =imgFile; 文件名=IMG_20150911_113029.jpg内容类型:image / JPG 内容长度:1179469
Content-Disposition: form-data; name="imgFile"; filename="IMG_20150911_113029.jpg" Content-Type: image/jpg Content-Length: 1179469
RequestBody
值是你在你的code已经产生。
RequestBody
value is what you has generate in your code.
我刚刚解决这个问题是暂时的。
I just resolve this problem temporary.
希望能帮助你!
这篇关于AWS S3 REST API与Android改造V2库,上传的图片被损坏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!