Java使用百度云存储BCS-让你的数据下载飞起来
一、简介
云也不是一个新概念了,云到底是什么东西,你叫我说个明明白白的我也说不出来,姑且算作联网的就叫做云。国内的云服务商还是有很多了,主要有两大类,一类是类似于阿里云的类主机型的云提供商,比如万网等传统空间商转过来的;还有一类是应用应用托管平台,比如BAE,SAE。相对于阿里云等空间商之类的来说,应用托管平台的入门更低,为广大的苦逼程序猿提供了一个好的测试平台。
我最近负责的软件升级程序,多平台多文件多版本,如果是自己架构文件服务器带宽肯定不能满足业务需求,于是上手百度云存储BCS服务,现在使用正常,但是偶尔的间歇性抽风让我不得不转向阿里云存储,毕竟商业的东西还是要商业化的专业,至少出问题了,不像百度云存储一样,客服都没有找到。但是作为技术使用,还是讲一讲云存储的使用。
二、使用步骤
1、 注册百度帐号
这个就不用我说了。
2、 称为开发者
进入“百度开放云平台”(不知道自己百度),登录后如果不是开发者,会提示让你注册称为开发者,填完资料就ok。
3、 创建应用
进入百度开放云首页,创建一个BAE应用引擎,创建的时候解决方案不要选择:使用BAE,除非你还有网站要挂上去。没事可以试一试。然后进入之后选择云存储,创建一个Bucket(后面会说明)。
4、 下载SDK
5、 测试代码
三、难点与注意
1、没有API或者API不详细的SDK需要花费你大量的精力去阅读,甚至不如看别人的博客来的方便。
2、概念的理解
Bucket:创建应用的之后,会创建一个Bucket,什么是Bucket,你把它想成是Windows下的一个盘符,就像是你创建了一个D盘,可以放文件,可以放文件夹,你还可以创建其他的Bucket。前面说Bucket是一个盘符其实是不准确的,因为它更像是Linux下的根目录,在读取你的文件的时候,你不能说我的文件是:1.txt。而是:/1.txt。代码中已申明。
Object:一个Object代表一个文件,他有很多元信息和文件块组成(参考文件系统),元信息包括文件名,文件大小,时间等等。使用Object前,一定要记得"/";
3、下载鉴权
使用http请求下载私有文件需要带上鉴权参数,如果你阅读官方的API,他只说明了授权的加密过程,但是没有Java版本,授权的步骤我不特别说明,我也给出了Java的实现,因为在SDK中已经实现了,只是有一个小问题。SDK生成的下载地址在Bucket与文件名之间的“/”被编码,会导致部分下载器下载失败,比如手机qq里面不能下载。需要再处理一下。
4、API key与Secret Key
通过这个访问该应用。
四、详细实现
1、 导包
2、 部分代码
授权:
1 public class BCSHelper { 2 private String host = "";//主机名字:bcs.duapp.com 3 private String accessKey = "";//在你创建的应用中可以看到 4 private String secretKey = ""; 5 private String bucket = "";//你创建的Bucket名字 6 private BaiduBCS baiduBCS = null; 7 8 public BCSHelper() { 9 this.host = Configuration.getHost(); 10 this.accessKey = Configuration.getAccessKey(); 11 this.secretKey = Configuration.getSecretKey(); 12 this.bucket = Configuration.getBucket(); 13 BCSCredentials credentials = new BCSCredentials(accessKey, secretKey); 14 baiduBCS = new BaiduBCS(credentials, host); 15 baiduBCS.setDefaultEncoding("UTF-8"); // Default UTF-8 16 }
上传与删除文件:
1 /** 2 * 上传文件到BCS 3 * 4 * @return boolean true表示上传成功 5 * @param file 6 * 需要上传的文件 7 * 8 * ******/ 9 public boolean putObject(File file) { 10 boolean result = true; 11 try { 12 // 必须有“/”开头 13 PutObjectRequest request = new PutObjectRequest(bucket, "/" + file.getName(), file); 14 // 设置Object的元信息 15 ObjectMetadata metadata = new ObjectMetadata(); 16 request.setMetadata(metadata); 17 baiduBCS.putObject(request); 18 LoggerService.addLoggerByOperate("BCS:上传文件到BCS:"+file.getName()); 19 } catch (Exception e) { 20 result = false; 21 LoggerService.addLoggerByError(e.getMessage()); 22 e.printStackTrace(); 23 } 24 return result; 25 } 26 27 /** 28 * 通过Object名删除BCS上面的文件 29 * 30 * @param object 31 * Object的名字 32 * @return boolean true删除成功 33 * *****/ 34 public boolean deleteObject(String object) { 35 boolean result = true; 36 try { 37 if (existObject(object)) { 38 baiduBCS.deleteObject(bucket, "/" + object); 39 LoggerService.addLoggerByOperate("BCS:删除BCS上的文件:"+object); 40 } 41 } catch (Exception e) { 42 result = false; 43 e.printStackTrace(); 44 LoggerService.addLoggerByError(e.getMessage()); 45 } 46 return result; 47 }
判断是否存在Object:
1 /** 2 * 判断该文件是否存在于BCS 3 * 4 * @param object 5 * object名 6 * @return boolean true表示存在 7 * ***/ 8 public boolean existObject(String object) { 9 boolean result = false; 10 try { 11 result = baiduBCS.doesObjectExist(bucket, "/" + object); 12 } catch (Exception e) { 13 e.printStackTrace(); 14 } 15 return result; 16 }
自己写的生成下载地址:
1 /** 2 * 获取Object的下载地址 3 * 4 * @param object 5 * Object名字 6 * @return String 返回下载的url 7 *******/ 8 public String getUrl(String object) { 9 // 需要加密的内容 10 String data = "MBO" + "\n" + "Method=GET" + "\n" + "Bucket=" + bucket + "\n" + "Object=/" + object + "\n"; 11 // 加密的结果 12 String hmacsha1 = getHmacSHA1(secretKey, data); 13 // 构造sign参数 14 String sign = "MBO:" + accessKey + ":" + hmacsha1; 15 // url 16 StringBuilder builder = new StringBuilder(); 17 builder.append("http://"); 18 builder.append(host); 19 builder.append("/"); 20 builder.append(bucket); 21 builder.append("/"); 22 builder.append(object); 23 builder.append("?sign="); 24 builder.append(sign); 25 return builder.toString(); 26 } 27 28 // 签名加密 29 private String getHmacSHA1(String secretKey, String data) { 30 String result = ""; 31 try { 32 SecretKeySpec signingKey = new SecretKeySpec(secretKey.getBytes(), "HmacSHA1"); 33 Mac mac = Mac.getInstance("HmacSHA1"); 34 mac.init(signingKey); 35 byte[] rawHmac = mac.doFinal(data.getBytes()); 36 Base64 base64 = new Base64(); 37 @SuppressWarnings("static-access") 38 byte[] enbytes = base64.encodeBase64Chunked(rawHmac); 39 result = new String(enbytes, "utf-8"); 40 } catch (Exception e) { 41 e.printStackTrace(); 42 } 43 return result; 44 }
修改过的SDK生成地址:
1 * 获取Object的下载地址 2 * 3 * @param object 4 * Object名字 5 * @return String 返回下载的url 6 *******/ 7 public String getUrl(String object) { 8 String result = ""; 9 GenerateUrlRequest generateUrlRequest = new GenerateUrlRequest(HttpMethodName.GET, bucket, "/" + object); 10 generateUrlRequest.setBcsSignCondition(new BCSSignCondition()); 11 result = baiduBCS.generateUrl(generateUrlRequest); 12 result=result.replaceFirst("%2F", "/"); 13 return result; 14 }
还有很多测试代码官方已经提供了,我也给出来的,需要的下载自己研究,再封装一下就可以用在实际项目中了,我没有发现上传文件的进度,希望看到的给我说说,毕竟也是菜鸟一个。