七牛云对象存储 Kodo 是七牛云提供的高可靠、强安全、低成本、可扩展的存储服务。您可通过控制台、API、SDK 等方式简单快速地接入七牛存储服务,实现海量数据的存储和管理。通过 Kodo 可以进行文件的上传、下载和管理。
此外,Kodo 的姊妹产品融合 CDN可以对文件下载进行加速,智能多媒体 API更是提供了丰富的基于海量数据深度学习算法的计算机视觉服务,如人脸技术、场景物体识别、OCR 文字识别和内容审核等。
七牛云对象存储提供高可用和高可靠的对象存储服务,您可以放心的将各种内容存储在云端。利用七牛云对象存储的扩展性和按需付费的优势,可以满足您持续快速增长的存储需求。您也可以搭配使用七牛云的对象存储和融合 CDN服务,实现全球覆盖、快速高效的内容分发。
七牛云对象存储支持镜像存储,这是一种快速的数据迁移和加速服务。可以帮助您实现无缝数据迁移,迁移过程中并不影响原有业务系统的访问。镜像存储适用于迁移原有业务系统的已有数据。
七牛云对象存储提供高可用和高可靠的存储解决方案来备份和归档您的关键数据。通过七牛云的身份验证机制可以设置不同的访问权限和级别,保障您数据的访问安全。相比传统自建的备份和归档存储系统,您无需在业务初期采购高昂硬件,无需担心数据增长带来的扩容问题,从而节省更多的存储成本、维护成本和人力资源成本。
针对海量的用户生成内容,七牛云对象存储能够提供跨地域、高并发的内容上传和访问服务。同时结合七牛云提供的数据处理服务,可以在云端实现图片裁剪、格式转化和水印,以及视频转码、切片和拼接等富媒体处理功能,满足移动网络场景下多终端设备的访问需求。
七牛云对象存储无缝集合各类第三方扩展插件,如 WordPress、Discuz、Emlog 等,并支持一键将各类插件里的静态资源托管到七牛云对象存储。
整合七牛云SDK
在Maven中添加七牛云SDK依赖包:
com.qiniu
qiniu-java-sdk
7.2.11
compile
com.squareup.okhttp3
okhttp
3.3.1
compile
com.google.code.gson
gson
2.6.2
compile
com.qiniu
happy-dns-java
0.1.4
compile
junit
junit
4.12
test
最新官方SDK开发文档地址:https://developer.qiniu.com/kodo/sdk/1239/java#3
上传文件原理
根据官方的开发手册可以知道,七牛云服务器接受从客户端直接上传文件,之后再通过回调地址发送回调,对于返回的数据也给了我们很大的自由,我们完全可以自定义需要返回的数据。
也可以从本地直接上传文件,原理与从客户端上传相似,这里不再赘述。
七牛云上传文件开发手册链接:https://developer.qiniu.com/kodo/manual/1272/form-upload
七牛云的仓库有两种,公开仓库和私有仓库,这两种仓库上传的原理相似。
七牛云的对象存储类似于java中的Map,使用的是键-值的存储方式,键是唯一的,我们可以通过键来改变它所对应的值,所以我们在上传的时候一定要注意保证键的唯一。
那么七牛云是怎么知道是谁在上传,他应该把上传的文件放在哪里呢?很简单,通过密钥
我们需要先设置七牛云的密钥,在使用的时候通过密钥生成一个通行证,也就是七牛云的上传凭证,这个上传凭证中包含了你上传文件所需要的所有信息,七牛云可以通过这个通行证得到他所需要的信息。
首先,我们来设置密钥:
这里我封装了七牛云上传工具类,直接看工具类吧
package com.kude.controller;
import com.qiniu.util.Auth;
import com.qiniu.util.StringMap;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
public class Qiniu {
// accessKey
private static String accessKey = "access key";
// secretKey
private static String secretKey = "secret key";
// public Bucket
private static String publicBucket = "bucket name";
// private Bucket
private static String privateBucket= "privateBucket";
// 回调地址
private static String callbackURL = "callBackURL";
//publicIMGURL
private static String publicIMGURL = "IMGURL";
// priviteIMGURL
private static String priviteIMGURL = "priviteIMGURL";
// 静态加载配置文件中的数据
static{
try {
FileInputStream in = new FileInputStream("D:\\demo\\svn\\cloud_demo\\cloud_demo\\src\\main\\resources\\datasource.properties");
Properties properties = new Properties();
properties.load(in);
accessKey = properties.getProperty("AccessKey");
secretKey = properties.getProperty("SecretKey");
publicBucket = properties.getProperty("publicBucket");
privateBucket = properties.getProperty("privateBucket");
callbackURL = properties.getProperty("CallBackURL");
publicIMGURL = properties.getProperty("publicIMGURL");
priviteIMGURL = properties.getProperty("priviteIMGURL");
in.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
*
* 得到上传凭证和资源下载路径
* @param bocket 指定是在共有仓库还是私有仓库中,0为私有仓库,非0为共有仓库
* @param key 资源的key
* @return 一个存有上传凭证
*/
public static Map getUploadToken(int bocket, String key){
Map data = new HashMap<>();
// 将上传凭证放入map中
data.put("token",getuplodTokenByKey(key));
// 图片地址
data.put("url",getUrl(bocket,key));
return data;
}
/**
* 得到资源的访问地址,也是下载地址
* @param bocket 指定是在共有仓库还是私有仓库中,0为私有仓库,非0为共有仓库
* @param key 资源的key
* @return 资源的访问地址
*/
private static String getUrl(int bocket,String key){
if(bocket == 0){
return getstaticDownloadToken(priviteIMGURL+key);
}else{
return publicIMGURL+key;
}
}
public static String getuplodTokenByKey(String key){
// 第一步: 先生成一个Auth验证
Auth auth = Auth.create(accessKey, secretKey);
// 第二步: 使用StringMap工具类拼装参数
StringMap putPolicy = new StringMap();
/*
* 指定上传的目标资源空间 Bucket 和资源键 Key(最大为 750 字节)。有三种格式:
* 1. ,表示允许用户上传文件到指定的 bucket。在这种格式下文件只能新增
* (分片上传需要指定insertOnly为1才是新增,否则也为覆盖上传),若已存在同名资源(且文件内容/etag不一致),
* 上传会失败;若已存在资源的内容/etag一致,则上传会返回成功。
*
*
* 2. :,表示只允许用户上传指定 key 的文件。
* 在这种格式下文件默认允许修改,若已存在同名资源则会被覆盖。
* 如果只希望上传指定 key 的文件,并且不允许修改,那么可以将下面的 insertOnly 属性值设为 1。
*
*
* 3. :,表示只允许用户上传指定以 keyPrefix 为前缀的文件,
* 当且仅当 isPrefixalScope 字段为 1 时生效,isPrefixalScope 为 1 时无法覆盖上传。
*
* type : String
* */
putPolicy.put("scope",publicBucket);
// 上传凭证有效截止时间。Unix时间戳,单位为秒。该截止时间为上传完成后,在七牛空间生成文件的校验时间,
// 而非上传的开始时间,一般建议设置为上传开始时间 + 3600s
// type : uint32
putPolicy.put("deadline",(System.currentTimeMillis()/1000L + 3600));
// Web 端文件上传成功后,浏览器执行 303 跳转的 URL。通常用于表单上传。文件上传成功后会跳转到
// ?upload_ret=,包含 returnBody 内容。
// 如不设置 returnUrl,则直接将 returnUrlnBody 的内容返回给客户端。
// type : String
// putPolicy.put("returnUrl","");
/*
*上传成功后,自定义七牛云最终返回給上传端(在指定 returnUrl 时是携带在跳转路径参数中)的数据。
* 支持魔法变量和自定义变量。returnBody 要求是合法的 JSON 文本。
* 例如 {"key": $(key), "hash": $(etag), "w": $(imageInfo.width), "h": $(imageInfo.height)}。
*/
// type : String
putPolicy.put("returnBody","{\"key\": $(key), \"hash\": $(etag), \"w\": $(imageInfo.width), \"h\": $(imageInfo.height)}");
/*
*
* 上传成功后,七牛云向业务服务器发送 Content-Type: application/x-www-form-urlencoded 的 POST 请求。
* 业务服务器可以通过直接读取请求的 query 来获得该字段,支持魔法变量和自定义变量。
* callbackBody 要求是合法的 url query string。
* 例如key=$(key)&hash=$(etag)&w=$(imageInfo.width)&h=$(imageInfo.height)。
* 如果callbackBodyType指定为application/json,则callbackBody应为json格式,
* 例如:{"key":"$(key)","hash":"$(etag)","w":"$(imageInfo.width)","h":"$(imageInfo.height)"}。
* */
// type : String
putPolicy.put("callbackBody","{\"key\":\"$(key)\",\"hash\":\"$(etag)\",\"w\":\"$(imageInfo.width)\",\"h\":\"$(imageInfo.height)\"}");
//上传成功后,七牛云向业务服务器发送回调通知 callbackBody 的 Content-Type。
// 默认为 application/x-www-form-urlencoded,也可设置为 application/json。
// type : String
putPolicy.put("callbackBodyType","application/json");
// 第三步: 生成一个上传凭证
return auth.uploadToken(publicBucket,key,(System.currentTimeMillis()/1000L+3600),putPolicy);
}
/**
* 获得一个私有空间下载的凭证,传入的参数是按照公开仓库访问方式生成的URL
* @param baseUrl 按照公开仓库生成URL的方式生成的URL
* @return
*/
public static String getstaticDownloadToken(String baseUrl){
Auth auth = Auth.create(accessKey, secretKey);
return auth.privateDownloadUrl(baseUrl);
}
/**
* 指定在七牛云上面的存储路径
* @return
*/
public String getDynamicUpToken(String resporties){
Auth auth = Auth.create(accessKey, secretKey);
StringMap putPolicy = new StringMap();
putPolicy.put("scope",resporties);
putPolicy.put("deadline",(System.currentTimeMillis()/1000L + 3600));
putPolicy.put("returnBody","{\"key\": $(key), \"hash\": $(etag), \"w\": $(imageInfo.width), \"h\": $(imageInfo.height)}");
putPolicy.put("callbackBody","{\"key\":\"$(key)\",\"hash\":\"$(etag)\",\"w\":\"$(imageInfo.width)\",\"h\":\"$(imageInfo.height)\"}");
putPolicy.put("callbackBodyType","application/json");
return auth.uploadToken(publicBucket,null,(System.currentTimeMillis()/1000L+3600),putPolicy);
}
/**
* 可以根据需求自己封装要生成的凭证
* 默认得到一个6分钟后过期的动态上传凭证,这个凭证可以让文件上传到默认仓库中
*
* 这个是所有上传凭证的原型,不能动
*
* @return
*/
public static String getDefaultDynamicUpToken(){
// 第一步: 先生成一个Auth验证
Auth auth = Auth.create(accessKey, secretKey);
// 第二步: 使用StringMap工具类拼装参数
StringMap putPolicy = new StringMap();
/*
* 指定上传的目标资源空间 Bucket 和资源键 Key(最大为 750 字节)。有三种格式:
* 1. ,表示允许用户上传文件到指定的 bucket。在这种格式下文件只能新增
* (分片上传需要指定insertOnly为1才是新增,否则也为覆盖上传),若已存在同名资源(且文件内容/etag不一致),
* 上传会失败;若已存在资源的内容/etag一致,则上传会返回成功。
*
*
* 2. :,表示只允许用户上传指定 key 的文件。
* 在这种格式下文件默认允许修改,若已存在同名资源则会被覆盖。
* 如果只希望上传指定 key 的文件,并且不允许修改,那么可以将下面的 insertOnly 属性值设为 1。
*
*
* 3. :,表示只允许用户上传指定以 keyPrefix 为前缀的文件,
* 当且仅当 isPrefixalScope 字段为 1 时生效,isPrefixalScope 为 1 时无法覆盖上传。
*
* type : String
* */
putPolicy.put("scope",publicBucket);
// 若为 1,表示允许用户上传以 scope 的 keyPrefix 为前缀的文件。
// type : int
// putPolicy.put("isPrefixalScope",1);
// 上传凭证有效截止时间。Unix时间戳,单位为秒。该截止时间为上传完成后,在七牛空间生成文件的校验时间,
// 而非上传的开始时间,一般建议设置为上传开始时间 + 3600s
// type : uint32
putPolicy.put("deadline",(System.currentTimeMillis()/1000L + 3600));
// 限定为新增语意。如果设置为非 0 值,则无论 scope 设置为什么形式,仅能以新增模式上传文件。
// type : int
// putPolicy.put("insertOnly",0);
// 唯一属主标识。特殊场景下非常有用,例如根据 App-Client 标识给图片或视频打水印。
// type : String
// putPolicy.put("endUser","");
// Web 端文件上传成功后,浏览器执行 303 跳转的 URL。通常用于表单上传。文件上传成功后会跳转到
// ?upload_ret=,包含 returnBody 内容。
// 如不设置 returnUrl,则直接将 returnUrlnBody 的内容返回给客户端。
// type : String
// putPolicy.put("returnUrl","");
/*
*上传成功后,自定义七牛云最终返回給上传端(在指定 returnUrl 时是携带在跳转路径参数中)的数据。
* 支持魔法变量和自定义变量。returnBody 要求是合法的 JSON 文本。
* 例如 {"key": $(key), "hash": $(etag), "w": $(imageInfo.width), "h": $(imageInfo.height)}。
*/
// type : String
putPolicy.put("returnBody","{\"key\": $(key), \"hash\": $(etag), \"w\": $(imageInfo.width), \"h\": $(imageInfo.height)}");
/*
* 上传成功后,七牛云向业务服务器发送 POST 请求的 URL。
* 必须是公网上可以正常进行 POST 请求并能响应 HTTP/1.1 200 OK 的有效 URL。
* 另外,为了给客户端有一致的体验,我们要求 callbackUrl 返回包 Content-Type 为 "application/json",
* 即返回的内容必须是合法的 JSON 文本。出于高可用的考虑,本字段允许设置多个 callbackUrl(用英文符号 ; 分隔),
* 在前一个 callbackUrl 请求失败的时候会依次重试下一个 callbackUrl。
*
* 一个典型例子是:http:///callback;http:///callback,并同时指定下面的 callbackHost 字段。
* 在 callbackUrl 中使用 ip 的好处是减少对 dns 解析的依赖,可改善回调的性能和稳定性。
* 指定 callbackUrl,必须指定 callbackbody,且值不能为空。
* */
// type : String
// putPolicy.put("callbackUrl","");
//上传成功后,七牛云向业务服务器发送回调通知时的 Host 值。与 callbackUrl 配合使用,仅当设置了 callbackUrl 时才有效。
// putPolicy.put("callbackHost","");
/*
*
* 上传成功后,七牛云向业务服务器发送 Content-Type: application/x-www-form-urlencoded 的 POST 请求。
* 业务服务器可以通过直接读取请求的 query 来获得该字段,支持魔法变量和自定义变量。
* callbackBody 要求是合法的 url query string。
* 例如key=$(key)&hash=$(etag)&w=$(imageInfo.width)&h=$(imageInfo.height)。
* 如果callbackBodyType指定为application/json,则callbackBody应为json格式,
* 例如:{"key":"$(key)","hash":"$(etag)","w":"$(imageInfo.width)","h":"$(imageInfo.height)"}。
* */
// type : String
putPolicy.put("callbackBody","{\"key\":\"$(key)\",\"hash\":\"$(etag)\",\"w\":\"$(imageInfo.width)\",\"h\":\"$(imageInfo.height)\"}");
//上传成功后,七牛云向业务服务器发送回调通知 callbackBody 的 Content-Type。
// 默认为 application/x-www-form-urlencoded,也可设置为 application/json。
// type : String
putPolicy.put("callbackBodyType","application/json");
/*
* 资源上传成功后触发执行的预转持久化处理指令列表。支持魔法变量和自定义变量。
* 每个指令是一个 API 规格字符串,多个指令用;分隔。请参阅persistenOps详解与示例。
* 同时添加 persistentPipeline 字段,使用专用队列处理,请参阅persistentPipeline。
* */
// type : String
// putPolicy.put("persistentOps","");
/*
* 接收持久化处理结果通知的 URL。必须是公网上可以正常进行 POST 请求并能响应 HTTP/1.1 200 OK 的有效 URL。
* 该 URL 获取的内容和持久化处理状态查询的处理结果一致。
* 发送 body 格式是 Content-Type 为 application/json 的 POST 请求,
* 需要按照读取流的形式读取请求的body才能获取
* */
// type : String
// putPolicy.put("persistentNotifyUrl","");
//转码队列名。资源上传成功后,触发转码时指定独立的队列进行转码。为空则表示使用公用队列,处理速度比较慢。建议使用专用队列。
// type : String
// putPolicy.put("persistentPipeline","");
//saveKey的优先级设置。为 true 时,saveKey不能为空,会忽略客户端指定的key,强制使用saveKey进行文件命名。参数不设置时,默认值为false
// type : String
// putPolicy.put("forceSaveKey",false);
//自定义资源名。支持魔法变量和自定义变量。forceSaveKey 为false时,这个字段仅当用户上传的时候没有主动指定 key 时起作用;
// forceSaveKey 为true时,将强制按这个字段的格式命名。
// type : String
// putPolicy.put("saveKey","");
// 限定上传文件大小最小值,单位Byte。
// type : int64
// putPolicy.put("fsizeMin",1024);
// 限定上传文件大小最大值,单位Byte。超过限制上传文件大小的最大值会被判为上传失败,返回 413 状态码。
// type : int64
// putPolicy.put("fsizeLimit",2048);
/*
* 开启 MimeType 侦测功能。设为非 0 值,则忽略上传端传递的文件 MimeType 信息,使用七牛服务器侦测内容后的判断结果。
* 默认设为 0 值,如上传端指定了 MimeType 则直接使用该值,否则按如下顺序侦测 MimeType 值:
* 1. 检查文件扩展名;
* 2. 检查 Key 扩展名;
* 3. 侦测内容。
* 如不能侦测出正确的值,会默认使用 application/octet-stream。
*/
// type : int
// putPolicy.put("detectMime",1);
/*
* 限定用户上传的文件类型。指定本字段值,七牛服务器会侦测文件内容以判断 MimeType,再用判断值跟指定值进行匹配,匹配成功则允许上传,匹配失败则返回 403 状态码。示例:
* image/*表示只允许上传图片类型
* image/jpeg;image/png表示只允许上传jpg和png类型的图片
* !application/json;text/plain表示禁止上传json文本和纯文本。注意最前面的感叹号!
*/
// type : String
// putPolicy.put("mimeLimit","");
// 文件存储类型。0 为普通存储(默认),1 为低频存储。
// type : int
// putPolicy.put("fileType",0);
// 第三步: 生成一个上传凭证
return auth.uploadToken(publicBucket,null,(System.currentTimeMillis()/1000L+3600),putPolicy);
}
public static void main(String[] args) {
System.out.println(Qiniu.getUploadToken(1, "test"));
}
}
在这里面,我将我的数据源配置到了配置文件中,从配置文件中读取。
这里再放上一个简陋的测试页面:
客户端表单上传文件
下载:下载
这个是我使用js将后台传过来的token和key填入表单的代码:
系统设置-广告设置