Spring Boot——集成七牛云OSS对象存储SDK解决方案

基本概念 

七牛云OSS对象存储(Kodo):七牛云海量存储系统(Kodo)是自主研发的非结构化数据存储管理平台,支持中心和边缘存储。 平台经过多年大规模用户验证已跻身先进技术行列,并广泛应用于海量数据管理的各类场景。

官方文档

对象存储 Java SDK 更新时间:2019-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、七牛云注册账号

七牛云官网:https://www.qiniu.com/

2、创建bucket

imagepng

3、记下仓库名字和访问域名

七牛融合 CDN 测试域名(以 clouddn.com/qiniucdn.com/qnssl.com/qbox.me 结尾),每个域名每日限总流量 10GB,每个测试域名自创建起30个自然日后系统会自动回收,仅供测试使用并且不支持 Https 访问,详情查看七牛测试域名使用规范。点击下列域名可查看每个域名剩余回收时间。

4、设置页面记录AK和SK.

imagepng

配置文件

application.properties

#QiNiu Config
# 七牛云密钥AK、SK
qiniu.access-key=cuMAM_AWSSU2zNqc3VIIJdebyeYJ
qiniu.secret-key=QmGmKdqiWJ6bHaGR3bj5Jdky2WOua
# 七牛云空间名
qiniu.bucket-name=stzg
# 外链访问路径
qiniu.domain=cdn.shentuzhigang.top
# 机房
qiniu.region=huadong

application.yml

# 七牛云配置------------------------------------
# 七牛云密钥AK、SK
qiniu
    AccessKey: 0CQcXKb0Mjti_WrxZTjxxSUNpbht
    SecretKey: fWGgBM8ddddEgVR9JYqYHXjffdxx9V
# 七牛云空间名
    Bucket: domain
# 外链访问路径
    domain: blog.domain.com
    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 2020-07-29 20:27
 */
@Configuration
public class CustomQiNiuKodoConfig {
    @Value("${qiniu.access-key}")
    private String accessKey ;
    @Value("${qiniu.secret-key}")
    private String secretKey ;
    @Value("${qiniu.region}")
    private String region;
    /**
     * 华东机房,配置自己空间所在的区域
     */
    @Bean
    public 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());
    }

    /**
     * 构建一个七牛上传工具实例
     */
    @Bean
    public UploadManager uploadManager(com.qiniu.storage.Configuration c) {
        return new UploadManager(c);
    }


    /**
     * 认证信息实例
     * @return
     */
    @Bean
    public Auth auth() {
        return Auth.create(accessKey, secretKey);
    }

    /**
     *
     * @param c com.qiniu.storage.Configuration
     * @return
     */
    @Bean
    public Client client(com.qiniu.storage.Configuration c){
        return new Client(c);
    }

    /**
     * 构建七牛空间管理实例
     * @param auth 认证信息
     * @param c com.qiniu.storage.Configuration
     * @return
     */
    @Bean
    public BucketManager bucketManager(Auth auth,com.qiniu.storage.Configuration c) {
        return new BucketManager(auth, c);
    }

    /**
     * Gson
     * @return
     */
    @Bean
    public 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 com.qiniu.common.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.springframework.stereotype.Component;

import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;

/**
 * FileName: QiNiuProvider
 *
 * @author ShenTuZhiGang
 * @version 1.0.0
 * @date 2020/7/19 21:20
 */


@Component
public class QiNiuProvider {
    @Value("${qiniu.bucket-name}")
    private String bucketName ;
    @Value("${qiniu.domain}")
    private String fileDomain;

    @Autowired
    private Configuration c;
    @Autowired
    private UploadManager uploadManager;
    @Autowired
    private BucketManager bucketManager;
    @Autowired
    private Client client;
    @Autowired
    private Gson gson;
    // 密钥配置
    @Autowired
    private 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 2020/7/29 21:27
 */
@RestController
@RequestMapping("/qiniu")
@Slf4j
public class QiNiuController {


    @Autowired
    private QiNiuProvider qiNiuProvider;

    @Autowired
    private ObjectMapper objectMapper;
    /**
     * 七牛云文件上传
     *
     * @param file 文件
     * @return
     */
    @RequestMapping(value = "/upload",method = {RequestMethod.POST})
    //@ResponseBody
    public 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对象采用配置方式生成解决方案

©️2020 CSDN 皮肤主题: 1024 设计师:上身试试 返回首页