从零开始,在java中使用七牛云实现文件云存储(一)
此处不讨论七牛云存储的优劣,为何要选择它什么什么的,只介绍使用方法,直接进入正题:
本文只介绍使用七牛云作为云存储的实现步骤,不介绍七牛云的其他功能(直播云,CDN什么的)。若要了解其他,请查看官方文档:
步骤:
从零开始↓
- 第一步,注册一个七牛账号。七牛官方网址:www.qiniu.com。
- 注册好之后,登录->进入控制管理台->选择对象存储->新建存储空间->填写表单->创建完成
说明:存储空间名(Bucket )是全局唯一的,公开空间中的文件可以直接用url访问,但是私有空间中的文件需要在url中加入授权凭证才可以访问。存储区域和访问控制以后是可以修改的,所以不必纠结选哪个。
建立好存储空间,就可以向里边存文件了,下边的内容将介绍如何在java中与存储空间做交互。
步骤:
- 引入jar包。官方提供三种引入方式(笔者使用的maven方式,所以其他两种就不介绍了,如果想要了解可以点击这里查看官方文档)。在pom中加入依赖:
<dependencies> <dependency> <groupId>com.qiniu</groupId> <artifactId>qiniu-java-sdk</artifactId> <version>7.2.6</version> <scope>compile</scope> </dependency> <dependency> <groupId>com.squareup.okhttp3</groupId> <artifactId>okhttp</artifactId> <version>3.3.1</version> <scope>compile</scope> </dependency> <dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> <version>2.6.2</version> <scope>compile</scope> </dependency> <dependency> <groupId>com.qiniu</groupId> <artifactId>happy-dns-java</artifactId> <version>0.1.4</version> <scope>compile</scope> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> </dependencies>
- 查看自己的Access Key和Secret Key,方法如下:进入七牛控制管理台->个人中心->用户管理,即可查看AK(Access Key)和SK(Secret Key),记录下这两个值。
- 正片到了,先上个代码,传个图片上去试试。
private static String accessKey = "你的AK"; private static String secretKey = "你的SK"; private static String bucket = "你的存储空间名"; /** * 获取上传凭证 */ public static String getUploadCredential() { Auth auth = Auth.create(accessKey, secretKey); String upToken = auth.uploadToken(bucket); System.out.println(upToken); return upToken; } /** * 文件上传 * @param zone * 华东 Zone.zone0() * 华北 Zone.zone1() * 华南 Zone.zone2() * 北美 Zone.zoneNa0() * @param upToken 上传凭证 * @param localFilePath 需要上传的文件本地路径 * @return */ public static DefaultPutRet fileUpload(Zone zone,String upToken,String localFilePath) { // 构造一个带指定Zone对象的配置类 Configuration cfg = new Configuration(zone); // ...其他参数参考类注释 UploadManager uploadManager = new UploadManager(cfg); // 默认不指定key的情况下,以文件内容的hash值作为文件名 String key = null; try { Response response = uploadManager.put(localFilePath, key, upToken); // 解析上传成功的结果 DefaultPutRet putRet = new Gson().fromJson(response.bodyString(), DefaultPutRet.class); System.out.println(putRet.key); System.out.println(putRet.hash); return putRet; } catch (QiniuException ex) { Response r = ex.response; System.err.println(r.toString()); try { System.err.println(r.bodyString()); } catch (QiniuException ex2) { // ignore } } return null; }
说明:上边的代码有两个方法,getUploadCredential()根据ak、sk和bucket生成一个上传凭证; fileUpload()实现文件上传,然后介绍一下fileUpload()的参数:zone:每个大区对应一个zone对象,对应关系如下:
* 华东 Zone.zone0() * 华北 Zone.zone1() * 华南 Zone.zone2() * 北美 Zone.zoneNa0()
upToken:getUploadCredential()生成的凭证
localFilePath:需要上传的文件本地路径,如果是Linux环境,使用类似"/home/qiniu/test.png";如果是Windows环境,使用类似"D:\\qiniu\\test.png",注意:字符串中不要有空格,笔者就被这个坑过。
返回值:DefaultPutRet对象,其中包含了已经上传文件的新文件名和文件hash值。
- 写个main()测试一下上边的上传方法:
public static void main(String[] args) { fileUpload(Zone.zone0(),CredentialsManager.getUploadCredential(),"D:\\qiniu\\test.jpg"); }
执行,打开七牛控制管理台->对象存储->你创建的空间名->内容管理,看看你的文件是不是传上去了!!
是不是很奇怪,我都还没有提供url,怎么就传上去了呢。没错了,七牛的SDK通过全局唯一的Bucket 直接拼接出了你空间对应的url,所以你只需要提供ak、sk和Bucket 就可以上传文件了。
但是在实际开发中,这些只能上传文件还远远不够,下面我们介绍七牛 SDK的其他功能
- 生成文件下载链接。仅仅把文件上传上去当然不行了,我们还要想办法访问它,下边分别介绍公有空间和私有空间生成文件下载链接的方法。废话不多说,直接上代码:
private static String accessKey = "你的AK"; private static String secretKey = "你的SK"; private static String bucket = "你的存储空间名"; public static Auth getAuth() { return Auth.create(accessKey, secretKey); } /** * 公有空间返回文件URL * @param fileName * @param domainOfBucket * @return */ public static String publicFile(String fileName,String domainOfBucket) { String encodedFileName=null; try { encodedFileName = URLEncoder.encode(fileName, "utf-8"); } catch (UnsupportedEncodingException e) { // TODO Auto-generated catch block e.printStackTrace(); } String finalUrl = String.format("%s/%s", domainOfBucket, encodedFileName); System.out.println(finalUrl); return finalUrl; } /** * 私有空间返回文件URL * @param auth * @param fileName * @param domainOfBucket * @param expireInSeconds * @return */ public static String privateFile(Auth auth,String fileName,String domainOfBucket,long expireInSeconds) { String encodedFileName=null; try { encodedFileName = URLEncoder.encode(fileName, "utf-8"); } catch (UnsupportedEncodingException e) { // TODO Auto-generated catch block e.printStackTrace(); } String publicUrl = String.format("%s/%s", domainOfBucket, encodedFileName); String finalUrl = auth.privateDownloadUrl(publicUrl, expireInSeconds); System.out.println(finalUrl); return finalUrl; } public static void main(String[] args) { publicFile("文件名","你的domainOfBucket"); //privateFile(CredentialsManager.getAuth(),"文件名","你的domainOfBucket",3600); }
说一下参数:fileName:没错,就是上传文件时,返回的DefaultPutRet对象中的key属性,也就是七牛控制管理台中看到的文件名。domainOfBucket:你的存储空间对应的domain,可以在控制台中查看,就是下边这个。
auth:私有空间文件的访问凭证,通过getAuth()生成的值
expireInSeconds:私有空间文件的访问链接超时时间,单位(秒)
执行一下,直接在浏览器中粘贴生成的地址,看能不能访问到文件。该链接即为文件固定连接,可以放在html中的<img src=" ">中哦(公有空间),注意私有空间的地址是有寿命的。
- 上传文件还支持字节流、字符流上传和断点续传哦,直接上代码了:
/** * 字符组上传 * @param zone * @param upToken * @return */ public static DefaultPutRet charArrayUpload(Zone zone,String upToken) { // 构造一个带指定Zone对象的配置类 Configuration cfg = new Configuration(zone); // ...其他参数参考类注释 UploadManager uploadManager = new UploadManager(cfg); // 默认不指定key的情况下,以文件内容的hash值作为文件名 String key = null; try { byte[] uploadBytes = "hello qiniu cloud".getBytes("utf-8"); try { Response response = uploadManager.put(uploadBytes, key, upToken); // 解析上传成功的结果 DefaultPutRet putRet = new Gson().fromJson(response.bodyString(), DefaultPutRet.class); System.out.println(putRet.key); System.out.println(putRet.hash); return putRet; } catch (QiniuException ex) { Response r = ex.response; System.err.println(r.toString()); try { System.err.println(r.bodyString()); } catch (QiniuException ex2) { // ignore } } } catch (UnsupportedEncodingException ex) { // ignore } return null; } /** * 数据流上传 * @param zone * @param upToken * @return */ public static DefaultPutRet streamUpload(Zone zone,String upToken) { // 构造一个带指定Zone对象的配置类 Configuration cfg = new Configuration(zone); // ...其他参数参考类注释 UploadManager uploadManager = new UploadManager(cfg); // ...生成上传凭证,然后准备上传 // 默认不指定key的情况下,以文件内容的hash值作为文件名 String key = null; try { byte[] uploadBytes = "test streamUpload \n hello qiniu cloud".getBytes("utf-8"); ByteArrayInputStream byteInputStream = new ByteArrayInputStream(uploadBytes); try { Response response = uploadManager.put(byteInputStream, key, upToken, null, null); // 解析上传成功的结果 DefaultPutRet putRet = new Gson().fromJson(response.bodyString(), DefaultPutRet.class); System.out.println(putRet.key); System.out.println(putRet.hash); return putRet; } catch (QiniuException ex) { Response r = ex.response; System.err.println(r.toString()); try { System.err.println(r.bodyString()); } catch (QiniuException ex2) { // ignore } } } catch (UnsupportedEncodingException ex) { // ignore } return null; } /** * 断点续传 * @param zone * @param upToken * @param localFilePath * @return */ public static DefaultPutRet breakPointUpload(Zone zone,String upToken,String localFilePath) { // 构造一个带指定Zone对象的配置类 Configuration cfg = new Configuration(zone); // ...其他参数参考类注释 // 如果是Windows情况下,格式是 D:\\qiniu\\test.png // 默认不指定key的情况下,以文件内容的hash值作为文件名 String key = null; String localTempDir = Paths.get(System.getenv("java.io.tmpdir"), bucket).toString(); try { // 设置断点续传文件进度保存目录 FileRecorder fileRecorder = new FileRecorder(localTempDir); UploadManager uploadManager = new UploadManager(cfg, fileRecorder); try { Response response = uploadManager.put(localFilePath, key, upToken); // 解析上传成功的结果 DefaultPutRet putRet = new Gson().fromJson(response.bodyString(), DefaultPutRet.class); System.out.println(putRet.key); System.out.println(putRet.hash); return putRet; } catch (QiniuException ex) { Response r = ex.response; System.err.println(r.toString()); try { System.err.println(r.bodyString()); } catch (QiniuException ex2) { // ignore } } } catch (IOException ex) { ex.printStackTrace(); } // MyPutRet myPutRet=response.jsonToObject(MyPutRet.class); return null; } public static void main(String[] args) { //fileUpload(Zone.zone0(),CredentialsManager.getUploadCredential(),"D:\\qiniu\\test.jpg"); //charArrayUpload(Zone.zone0(),CredentialsManager.getUploadCredential()); //streamUpload(Zone.zone0(),CredentialsManager.getUploadCredential()); breakPointUpload(Zone.zone0(),CredentialsManager.getUploadCredential(),"D:\\qiniu\\test.jpg"); }
你是否注意到了下边这个变量,// 默认不指定key的情况下,以文件内容的hash值作为文件名 String key = null;
不错,上传文件的时候是可以自定义文件名的,默认是以hash值作为文件名,如果你有这方面需求,可以把该变量放到方法的参数里,像这样:
public static DefaultPutRet streamUpload(Zone zone,String upToken,String key) { //...... }
好了,今天先写到这,qiniu SDK的其他功能请期待
从零开始,在java中使用七牛云实现文件云存储(二)
上一篇: Next3 for Linux宣布
下一篇: Struts 2.0拦截器