基本概念
七牛云OSS对象存储(Kodo):七牛云海量存储系统(Kodo)是自主研发的非结构化数据存储管理平台,支持中心和边缘存储。 平台经过多年大规模用户验证已跻身先进技术行列,并广泛应用于海量数据管理的各类场景。
官方文档
对象存储 Java SDK 更新时间:-12-16 17:24:24
Gradle
compile 'com.qiniu:qiniu-java-sdk:7.2.27'
Maven
<dependencies><dependency><groupId>com.qiniu</groupId><artifactId>qiniu-java-sdk</artifactId><version>[7.2.0, 7.2.99]</version></dependency><dependency><groupId>com.squareup.okhttp3</groupId><artifactId>okhttp</artifactId><version>3.14.2</version><scope>compile</scope></dependency><dependency><groupId>com.google.code.gson</groupId><artifactId>gson</artifactId><version>2.8.5</version><scope>compile</scope></dependency><dependency><groupId>com.qiniu</groupId><artifactId>happy-dns-java</artifactId><version>0.1.6</version><scope>test</scope></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version><scope>test</scope></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.2</version><scope>provided</scope></dependency></dependencies>
准备工作
1、七牛云注册账号
七牛云官网:/
2、创建bucket
3、记下仓库名字和访问域名
七牛融合 CDN 测试域名(以 ///qbox.me 结尾),每个域名每日限总流量 10GB,每个测试域名自创建起30个自然日后系统会自动回收,仅供测试使用并且不支持 Https 访问,详情查看七牛测试域名使用规范。点击下列域名可查看每个域名剩余回收时间。
4、设置页面记录AK和SK.
配置文件
application.properties
#QiNiu Config# 七牛云密钥AK、SKqiniu.access-key=cuMAM_AWSSU2zNqc3VIIJdebyeYJqiniu.secret-key=QmGmKdqiWJ6bHaGR3bj5Jdky2WOua# 七牛云空间名qiniu.bucket-name=stzg# 外链访问路径qiniu.domain=cdn.shentuzhigang.top# 机房qiniu.region=huadong
application.yml
# 七牛云配置------------------------------------# 七牛云密钥AK、SKqiniuAccessKey: 0CQcXKb0Mjti_WrxZTjxxSUNpbhtSecretKey: fWGgBM8ddddEgVR9JYqYHXjffdxx9V# 七牛云空间名Bucket: domain# 外链访问路径domain: region: huadong
解决方案
配置类
package cn.edu.zstu.shihua.xihu.config;import com.google.gson.Gson;import com.qiniu.http.Client;import com.qiniu.storage.BucketManager;import com.qiniu.storage.Region;import com.qiniu.storage.UploadManager;import com.qiniu.util.Auth;import org.springframework.beans.factory.annotation.Value;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import java.lang.reflect.Field;import java.lang.reflect.InvocationTargetException;/*** @author ShenTuZhiGang* @version 1.0.0* @date -07-29 20:27*/@Configurationpublic class CustomQiNiuKodoConfig {@Value("${qiniu.access-key}")private String accessKey ;@Value("${qiniu.secret-key}")private String secretKey ;@Value("${qiniu.region}")private String region;/*** 华东机房,配置自己空间所在的区域*/@Beanpublic com.qiniu.storage.Configuration qiniuConfig()throws IllegalAccessException, NoSuchMethodException, InvocationTargetException {Field[] fields = QiNiuRegion.class.getDeclaredFields();for(Field field:fields){String r = (String)field.get(QiNiuRegion.class);System.out.println(r);if(r.equals(region)){com.qiniu.storage.Configuration c = new com.qiniu.storage.Configuration((Region)Region.class.getMethod(r,null).invoke(null,null));return c;}}return new com.qiniu.storage.Configuration(Region.huadong());}/*** 构建一个七牛上传工具实例*/@Beanpublic UploadManager uploadManager(com.qiniu.storage.Configuration c) {return new UploadManager(c);}/*** 认证信息实例* @return*/@Beanpublic Auth auth() {return Auth.create(accessKey, secretKey);}/**** @param c com.qiniu.storage.Configuration* @return*/@Beanpublic Client client(com.qiniu.storage.Configuration c){return new Client(c);}/*** 构建七牛空间管理实例* @param auth 认证信息* @param c com.qiniu.storage.Configuration* @return*/@Beanpublic BucketManager bucketManager(Auth auth,com.qiniu.storage.Configuration c) {return new BucketManager(auth, c);}/*** Gson* @return*/@Beanpublic Gson gson() {return new Gson();}}interface QiNiuRegion{String REGION_0 = "region0";String REGION_1 = "region1";String REGION_2 = "region2";String REGION_Na = "regionNa";String REGION_AS = "regionAs";String HUA_DONG = "huadong";String HUA_BEI = "huabei";String HUA_NAN = "huanan";String BRI_MEI = "beimei";String XIN_JIA_PO = "xinijipo";}
Provider
package cn.edu.zstu.shihua.xihu.provider;import com.google.gson.Gson;import mon.QiniuException;import com.qiniu.http.Client;import com.qiniu.http.Response;import com.qiniu.storage.BucketManager;import com.qiniu.storage.Configuration;import com.qiniu.storage.UploadManager;import com.qiniu.storage.model.DefaultPutRet;import com.qiniu.util.Auth;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.beans.factory.annotation.Value;import org.ponent;import java.io.IOException;import java.io.InputStream;import .URLEncoder;/*** FileName: QiNiuProvider** @author ShenTuZhiGang* @version 1.0.0* @date /7/19 21:20*/@Componentpublic class QiNiuProvider {@Value("${qiniu.bucket-name}")private String bucketName ;@Value("${qiniu.domain}")private String fileDomain;@Autowiredprivate Configuration c;@Autowiredprivate UploadManager uploadManager;@Autowiredprivate BucketManager bucketManager;@Autowiredprivate Client client;@Autowiredprivate Gson gson;// 密钥配置@Autowiredprivate Auth auth;//简单上传模式的凭证public String getUpToken() {return auth.uploadToken(bucketName);}//覆盖上传模式的凭证public String getUpToken(String fileKey) {return auth.uploadToken(bucketName, fileKey);}/*** 将本地文件上传* @param filePath 本地文件路径* @param fileKey 上传到七牛后保存的文件路径名称* @return* @throws IOException*/public DefaultPutRet upload(String filePath, String fileKey) throws IOException {Response res = uploadManager.put(filePath, fileKey, getUpToken(fileKey));// 解析上传成功的结果DefaultPutRet putRet = gson.fromJson(res.bodyString(), DefaultPutRet.class);System.out.println(putRet.key);System.out.println(putRet.hash);return putRet;}/*** 上传二进制数据* @param data* @param fileKey* @return* @throws IOException*/public DefaultPutRet upload(byte[] data, String fileKey) throws IOException {Response res = uploadManager.put(data, fileKey, getUpToken(fileKey));// 解析上传成功的结果DefaultPutRet putRet = gson.fromJson(res.bodyString(), DefaultPutRet.class);System.out.println(putRet.key);System.out.println(putRet.hash);return putRet;}/*** 上传输入流* @param inputStream* @param fileKey* @return* @throws IOException*/public DefaultPutRet upload(InputStream inputStream, String fileKey) throws IOException {Response res = uploadManager .put(inputStream, fileKey, getUpToken(fileKey),null,null);// 解析上传成功的结果DefaultPutRet putRet = gson.fromJson(res.bodyString(), DefaultPutRet.class);System.out.println(putRet.key);System.out.println(putRet.hash);return putRet ;}/*** 删除文件* @param fileKey* @return* @throws QiniuException*/public boolean delete(String fileKey) throws QiniuException {Response response = bucketManager.delete(bucketName, fileKey);return response.statusCode == 200 ? true:false;}/*** 获取公共空间文件* @param fileKey* @return*/public String getFile(String fileKey) throws Exception{String encodedFileName = URLEncoder.encode(fileKey, "utf-8").replace("+", "%20");String url = String.format("%s/%s", fileDomain, encodedFileName);return url;}/*** 获取私有空间文件* @param fileKey* @return*/public String getPrivateFile(String fileKey) throws Exception{String encodedFileName = URLEncoder.encode(fileKey, "utf-8").replace("+", "%20");String publicUrl = String.format("%s/%s", "http://"+fileDomain, encodedFileName);long expireInSeconds = 3600;//1小时,可以自定义链接过期时间String finalUrl = auth.privateDownloadUrl(publicUrl, expireInSeconds);return finalUrl;}}
Controller
package cn.edu.zstu.shihua.xihu.controller;import cn.edu.zstu.shihua.xihu.dto.ResponseBean;import cn.edu.zstu.shihua.xihu.entity.StatusCode;import cn.edu.zstu.shihua.xihu.provider.QiNiuProvider;import com.fasterxml.jackson.databind.ObjectMapper;import com.qiniu.storage.model.DefaultPutRet;import lombok.extern.slf4j.Slf4j;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.*;import org.springframework.web.multipart.MultipartFile;import javax.servlet.http.HttpServletResponse;import java.io.FileInputStream;import java.text.SimpleDateFormat;import java.util.Date;import java.util.HashMap;import java.util.Map;import java.util.UUID;/*** FileName: QiniuController** @author ShenTuZhiGang* @version 1.0.0* @date /7/29 21:27*/@RestController@RequestMapping("/qiniu")@Slf4jpublic class QiNiuController {@Autowiredprivate QiNiuProvider qiNiuProvider;@Autowiredprivate ObjectMapper objectMapper;/*** 七牛云文件上传** @param file 文件* @return*/@RequestMapping(value = "/upload",method = {RequestMethod.POST})//@ResponseBodypublic ResponseBean upload(MultipartFile[] file) {ResponseBean response = new ResponseBean(StatusCode.SC_INTERNAL_SERVER_ERROR);if (file.length <= 0 || file[0].isEmpty()) {return new ResponseBean(StatusCode.SC_EXPECTATION_FAILED,"上传文件不能为空");}try {FileInputStream fileInputStream = (FileInputStream) file[0].getInputStream();String originalFilename = file[0].getOriginalFilename();String fileExtend = originalFilename.substring(originalFilename.lastIndexOf("."));String yyyyMMddHHmmss = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());//默认不指定key的情况下,以文件内容的hash值作为文件名String fileKey = UUID.randomUUID().toString().replace("-", "") + "-" + yyyyMMddHHmmss + fileExtend;Map<String, Object> map = new HashMap<>();DefaultPutRet uploadInfo = qiNiuProvider.upload(fileInputStream, fileKey);map.put("fileName", uploadInfo.key);map.put("originName", originalFilename);map.put("size", file[0].getSize());//七牛云文件私有下载地址(看自己七牛云公开还是私有配置)map.put("url", "http://cdn.shentuzhigang.top/" + uploadInfo.key);// map.put("url", "/linfen/qiniu/file/" + uploadInfo.key);//七牛云公开下载地址//String json = objectMapper.writeValueAsString(map);response.setStatus(0);response.setMsg("成功");response.setData(map);log.info("文件:" + map);return response;} catch (Exception e) {e.printStackTrace();return response;}}/*** 七牛云私有文件下载** @param filename 文件名* @return*/@RequestMapping(value = "/private/file/{filename}",method = {RequestMethod.GET})public void privateDownload(@PathVariable("filename") String filename, HttpServletResponse response) {if (filename.isEmpty()) {return;}try {String privateFile = qiNiuProvider.getPrivateFile(filename);log.info("文件下载地址:" + privateFile);response.sendRedirect(privateFile);} catch (Exception e) {e.printStackTrace();}}/*** 七牛云文件下载** @param filename 文件名* @return*/@RequestMapping(value = "/file/{filename}",method = {RequestMethod.GET})public void download(@PathVariable("filename") String filename, HttpServletResponse response) {if (filename.isEmpty()) {return;}try {String privateFile = qiNiuProvider.getFile(filename);System.out.println("文件下载地址:" + privateFile);response.sendRedirect("http://"+privateFile);} catch (Exception e) {e.printStackTrace();}}}
参考文章
springmvc整合七牛云存储实现文件上传(java篇)
springboot项目集成七牛云OSS对象存储, 实现文件上传
七牛云java(服务端)通用工具类
Java中定义常量的几种方法
Postman Post请求上传文件
JAVA——实现七牛云对象存储Region对象采用配置方式生成解决方案