我想使用REST API将媒体数据上传到S3存储桶,而不使用Amazon SDK。我在文件上传到s3存储桶时收到“403 Forbidden Access Denied Error”,请提出合适的操作。如果还需要其他任何东西我也可以分享。
String bucket = getString(R.string.s3_bucket);
RestAdapter.Builder builder = new RestAdapter.Builder()
.setEndpoint("http://" + bucket + ".s3.amazonaws.com")
.setLogLevel(RestAdapter.LogLevel.FULL)
.setClient(new OkClient(new OkHttpClient()));
AwsS3 aws = builder.build().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 dateTime = dt.withZone(DateTimeZone.forID(ZONE)).plusHours(1);
String formattedDate = dateTime.toString(fmt);
try {
Bitmap bm = BitmapFactory.decodeFile(mCurrentPhotoPath);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bm.compress(Bitmap.CompressFormat.JPEG, 100, baos); //bm is the bitmap object
byte[] b = baos.toByteArray();
TypedInput body = new TypedByteArray("image/jpg", b);
String imageName = "files_" + System.currentTimeMillis();
String oauth = AWSOauth.getOAuthAWS(getApplicationContext(), imageName.trim());
String host = bucket + ".s3.amazonaws.com";
String mimeType = body.mimeType();
long length = body.length();
File file = new File(mCurrentPhotoPath);
RequestBody bb = RequestBody.create(MediaType.parse("image/jpeg"), file);
aws.upload(imageName.trim(),length,"/**",host,formattedDate,mimeType,oauth,bb,new Callback<String>(){
@Override
public void success(String s, Response response) {
Log.d("tag","S = " + s);
Log.d("tag","getHeaders = " + response.getHeaders());
Log.d("tag","Status = " + response.getStatus());
}
@Override
public void failure(RetrofitError error) {
Log.d("tag","error: S = " + error.getMessage());
}
});
}catch (Exception e){
}
@PUT("/{Key}")
void 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,
@Body RequestBody body,Callback<String> mCallback);
答案 0 :(得分:1)
如果您的应用有关联的后端服务,您可以在Android应用中使用Amazon SDK上传到S3,如果您获得后端生成的上传的预先指定的网址,并通过API调用将其发送到应用。以下是亚马逊针对不同语言的一些文档:https://docs.aws.amazon.com/AmazonS3/latest/dev/PresignedUrlUploadObject.html
以下是使用后端预先签名的网址的Android代码示例:
public interface AmazonService {
@Multipart
@POST
Call<ResponseBody> upload(@Url String url, @PartMap Map<String,RequestBody> params, @Part MultipartBody.Part file);
}
public class AmazonS3Client {
private static final String EMPTY_URL_TO_MAKE_RETROFIT_HAPPY = "";
public boolean uploadMoment(Map<String, String> fields, String filePath, String s3BaseUrl) {
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.NONE);
OkHttpClient okClient = new OkHttpClient.Builder().addInterceptor(interceptor).build();
Retrofit retrofit = new Retrofit.Builder().client(okClient).baseUrl(s3BaseUrl + "/").build();
RequestBody requestFile = RequestBody.create(MediaType.parse("image/*"), new File(filePath));
MultipartBody.Part body = MultipartBody.Part.createFormData("file", fields.get("key"), requestFile);
Map<String, RequestBody> parameters = new HashMap<>();
for (Map.Entry<String, String> entry : fields.entrySet()) {
parameters.put(entry.getKey(), createPartFromString(entry.getValue()));
}
AmazonService service = retrofit.create(AmazonService.class);
Call<ResponseBody> call = service.upload(EMPTY_URL_TO_MAKE_RETROFIT_HAPPY, parameters, body);
try {
Response<ResponseBody> execute = call.execute();
if (execute.code() == 204) {
return true;
} else {
Log.e("AmazonS3Client", "unexpected http response: " + execute.code());
}
} catch (IOException e) {
Log.e("AmazonS3Client", "upload error", e);
}
return false;
}
private RequestBody createPartFromString(String descriptionString) {
return RequestBody.create(okhttp3.MultipartBody.FORM, descriptionString);
}
}
答案 1 :(得分:0)
RestAdapter.Builder builder = new RestAdapter.Builder()
.setEndpoint("http://" + bucket + ".s3.amazonaws.com")
.setLogLevel(RestAdapter.LogLevel.FULL)
*<add this line>>>>>*.setRequestInterceptor(new AuthToken())
.setClient(new OkClient(new OkHttpClient()));
你的AuthToken就像: -
public class AuthToken implements RequestInterceptor
{
@Override
public void apply(RequestFacade request)
{
var authTokenString = AWS <Name>:<Key>
request.addHeader("Authorization", authTokenString);
}
}