AWS S3 REST API与Android改造V2库,上传的图片被损坏 [英] AWS S3 Rest API with Android Retrofit V2 library, uploaded image is damaged

查看:626
本文介绍了AWS S3 REST API与Android改造V2库,上传的图片被损坏的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想上传图片从我的 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆