带有 Android Retrofit V2 库的 AWS S3 Rest API,上传的图像已损坏 [英] AWS S3 Rest API with Android Retrofit V2 library, uploaded image is damaged

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

问题描述

我正在尝试将 Image 从我的 Android APP 上传到 Amazon AWS S3,我需要使用 AWS Restful API.

I'm trying upload a Image from my Android APP to Amazon AWS S3 and I need use AWS Restful API.

我正在使用 Retrofit 2 来满足请求.

I'm using Retrofit 2 to make to the request.

我的应用程序与 Amazon S3 成功连接并按预期执行请求,但是当我尝试从 Bucket 查看Image 时,图片打不开.我将 Image 下载到我的电脑并尝试打开,但一直收到图像已损坏的消息.

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.

下面让我们看看我的完整代码.

Lets see my complete code bellow.

我的 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);
}

用于挂载凭据的实用程序类

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" + "

" + contentType + "
" + formattedDate + "
" + 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("
", "");

        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();
        }
    }

感谢您的帮助,提前致谢!

I appreciate any helps, thanks in advance!

推荐答案

RequestBody avatarBody = RequestBody.create(MediaType.parse("image"),file);
MultipartBody.Part filePart = MultipartBody.Part.createFormData("file", file.getName(), avatarBody);


@Multipart
@POST(url)
Call<ResponseBody> uploadImageAmazon(
            @Part MultipartBody.Part filePart);

我有同样的经历,通过 https://github.com/square/解决了改造/问题/2424这个解决方案

I had same experience, and solved it by https://github.com/square/retrofit/issues/2424 this solution

这篇关于带有 Android Retrofit V2 库的 AWS S3 Rest API,上传的图像已损坏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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