android 阿里云oss上传
购买了阿里云的oss空间,于是用它来存储图片,不过中间的使用算是出了些问题,导致很长的才成功。
不得不说,阿里云文档真的是无力吐槽。。。乱七八糟的。我完全是东拼西凑,才完成的图片上传功能。
走了很多的弯路,今天来记录下。
服务器上传:
阿里云上传分服务器上传和客户端上传,首先要分清,因为两边有差别的,服务器的上传简单很多,官方给的下载下来,输入配置的参数accessKeyId 和 accessKeySecret 还有bucketName 就能够上传成功,很简单,这里也就不细说了。
客户端上传:
这里着重来讲下客户端上传,因为它更加的麻烦 和繁琐一些。
教程的全篇都会讲一句话,移动端是不受信任的环境,我的个人理解是,apk是个比较好被反编译的,所有,如果将很多秘钥写到APP中,就会存在泄露的问题。所以,像上面服务器上传那样,直接在代码里面写accessKeyId 和 accessKeySecret,肯定是不安全的。所以,客户端上传,有两个东西子知识点要去了解。
1.访问用户RAM管理
这里需要进行用户的分配,分配一个专门操作阿里云 OSS的用户,并给予该用户应有的权限。
2.STS鉴权模式
OSS可以通过阿里云STS服务,临时进行授权访问。阿里云STS (Security Token Service) 是为云计算用户提供临时访问令牌的Web服务。通过STS,您可以为第三方应用或联邦用户(用户身份由您自己管理)颁发一个自定义时效和权限的访问凭证
我的理解就是:用分配的用户的秘钥去操作单个步骤,实现权限的分配管理。
开始准备工作
1:用户RAM管理
创建RAM:步骤参考文档。就是到《访问控制RAM》去设置子用户,并分配给子用户权限。
https://ram.console.aliyun.com/?spm=5176.2020520153.aliyun_sidebar.11.7f5a43f7vo9spw&accounttraceid=dfef632a-67d6-4f51-a3ff-beea37b5db73#/overview
2.进入对象储存的控制台,创建对应的AK。
对象储存 - 安全令牌-安全令牌快捷配置 - 开始授权,
授权成功后,会出来一系列参数AccessKeyID 和 AccessKeySecret 和 RoleArn ,这些比较重要,需要在请求中用于授权,不要泄露。
3.准备STS服务器,用于请求阿里云OSS 分发出Token,然后客户端通过token进行访问和上传下载。
去阿里云上下载一个sts-server作为服务器端,专门用来分发token,这个直接去阿里云下载代码,部署到服务器上运行就行。
返回的一个json数据,里面包含了SecurityToken.
4.开始编写客户端的代码
首先加入依赖包
implementation 'com.aliyun.dpa:oss-android-sdk:+' implementation 'com.squareup.okhttp3:okhttp:3.4.1' implementation 'com.squareup.okio:okio:1.9.0'
加入权限设置:
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
加入混淆设置;注意,这里是重点,一定要加入,不然会出各种奇怪的问题。
加入到文件proguard-rules.pro中
-keep class com.alibaba.sdk.android.oss.** { *; } -dontwarn okio.** -dontwarn org.apache.commons.codec.binary.**
初始化对象OSSCLIENT
String endpoint = "http://oss-cn-shenzhen.aliyuncs.com"; String stsServer = "../sts-server/sts-server/sts.php"; String callbackAddress = "http://oss-demo.aliyuncs.com:23450"; //推荐使用OSSAuthCredentialsProvider。token过期可以及时更新 OSSCredentialProvider credentialProvider = new OSSAuthCredentialsProvider(stsServer); //该配置类如果不设置,会有默认配置,具体可看该类 ClientConfiguration conf = new ClientConfiguration(); conf.setConnectionTimeout(15 * 1000); // 连接超时,默认15秒 conf.setSocketTimeout(15 * 1000); // socket超时,默认15秒 conf.setMaxConcurrentRequest(5); // 最大并发请求数,默认5个 conf.setMaxErrorRetry(2); // 失败后最大重试次数,默认2次 oss = new OSSClient(getApplicationContext(), endpoint, credentialProvider,conf);
上传图片代码:
{
// 构造上传请求
PutObjectRequest put = new PutObjectRequest("hzltest1", "333333333333333333333333", FilePath);
//PutObjectRequest put = new PutObjectRequest("<bucketName>", "<objectKey>", "<uploadFilePath>");
// 异步上传时可以设置进度回调 put.setProgressCallback(new OSSProgressCallback<PutObjectRequest>() { @Override public void onProgress(PutObjectRequest request, long currentSize, long totalSize) { Log.d("PutObject", "currentSize: " + currentSize + " totalSize: " + totalSize); } }); OSSAsyncTask task = oss.asyncPutObject(put, new OSSCompletedCallback<PutObjectRequest, PutObjectResult>() { @Override public void onSuccess(PutObjectRequest request, PutObjectResult result) { Log.d("PutObject", "UploadSuccess"); Log.d("ETag", result.getETag()); Log.d("RequestId", result.getRequestId()); } @Override public void onFailure(PutObjectRequest request, ClientException clientExcepion, ServiceException serviceException) { // 请求异常 if (clientExcepion != null) { // 本地异常如网络异常等 clientExcepion.printStackTrace(); } if (serviceException != null) { // 服务异常 Log.e("ErrorCode", serviceException.getErrorCode()); Log.e("RequestId", serviceException.getRequestId()); Log.e("HostId", serviceException.getHostId()); Log.e("RawMessage", serviceException.getRawMessage()); } } }); }
到底,文件能够上传成功就是OK的。
这里上传的代码还是比较简单的,主要难在配置,和阿里云本身的文档写的很分散,东一块西一块,你需要首先了解很多技术才能很快的上手,否则,对于一个刚购买OSS的人来说,用起来着实是麻烦。