阿里云Oss图像存储

package com.lcx.test.utils;

import com.alibaba.fastjson.JSON;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClient;
import com.aliyun.oss.model.Bucket;
import com.aliyun.oss.model.PutObjectResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.io.InputStream;
import java.util.Date;

//import static com.project.lddproject.Authentication.constans.OSSClientConstants.BACKET_NAME;

/**
 *       阿里云OSS工具类
 * @author   Liu...cx..
 * @date 2019/11/16  14:10
 */
@Slf4j
@Component
public class AliYunOssUtil {

    private static String key;

    private static String secret;

    /** 形如: http://oss-cn-shenzhen.aliyuncs.com */
    private static String endpoint;

    /** 提示:官方文档里面介绍,OSSClient可以并发使⽤。即:线程安全。 */
    private static OSS ossClient;

    //阿里云API的文件夹名称
    private static String folder;

    /** 重试次数 */
    private static int tryTimesUpperLimit = 3;

    /** 此参数值随意,但【必须要遵循bucket的命名规则】。此参数主要用于 帮助 判断连接池是否开启着。 */
    private static final String IS_CONNECTION_POOL_OPEN_HELPER = "Liu_chunxi";

    /**
     * 初始化
     *
     * @param key
     *            通行key
     * @param secret
     *            通行secret
     * @param endpoint
     *            数据存储区域断点(region)
     */
    public static void init(String endpoint, String key, String secret ) {
        log.info(" AliYunOssUtil.init been invoked, endpoint -> {}, key -> {}, secret -> {} ",
                endpoint, key, secret);
        AliYunOssUtil.endpoint = endpoint;
        AliYunOssUtil.key = key;
        AliYunOssUtil.secret = secret;
        initOssClient();
    }


    /**
     * 客户端的初始化
     *
     * 注:不能判断为null, 当shutdown时,ossClient实例仍然存在
     *
     * @date 2019/11/18  9:44    之前出现二次上传连接池关闭  下面这个判断逻辑要注释掉
     */
    private synchronized static void initOssClient() {

//  **********干掉 *************************
        //if (isConnectionPoolOpen()) {
        //    log.info("Connection pool Has been open!");
        //    return;
       // }
//  **********干掉 *************************


        log.info(" initOssClient been invoked, params endpoint -> {}, key -> {}, "
                + " secret -> {}",  endpoint, key, secret);
//        ossClient = new OSSClientBuilder().build(endpoint, key, secret);
        ossClient = new OSSClient(endpoint, key, secret);
    }

    /**
     * 创建存储空间(如果不存在名为bucketName的存储空间的话)
     *
     * 注: 存储空间(Bucket)是存储对象(Object)的容器。对象都⾪属于存储空间。
     *
     * @param bucketName
     *            存储空间名
     * @return 创建的存储空间对象
     */
    public static Bucket createBucketIfNecessary(String bucketName) {
        if (ossClient.doesBucketExist(bucketName)) {
            return ossClient.getBucketInfo(bucketName).getBucket();
        }
        // 如果不存在, 那么直接创建
        Bucket bucket = ossClient.createBucket(bucketName);
        log.info(" created Bucket -> {}", JSON.toJSONString(bucket));
        return bucket;
    }

    /**
     * 直接创建存储空间
     *
     * 注: 存储空间(Bucket)是存储对象(Object)的容器。对象都⾪属于存储空间。
     *
     * @param bucketName
     *            存储空间名
     */
    private static void createBucket(String bucketName) {
        Bucket bucket = ossClient.createBucket(bucketName);
        log.info(" created Bucket -> {}", JSON.toJSONString(bucket));
    }

    /**
     * 简单文件上传
     *
     * 注:同一个bucketName下,objectName不要一样,否者会覆盖前面的文件
     *    追注:对某个Object而言,其的objectName即为其key, 而key需要具有唯一性
     *
     * @param bucketName
     *            bucket介绍:存储空间是您⽤于存储对象(Object)的容 器,所有的对象都必须⾪属于某个存储空间。
     * @param objectName
     *            自定义上传后的文件名
     * @param inputStream
     *            (流的形式)Object
     *
     */
    public static void uploadFileByInputStream(String bucketName,
                                                 String objectName,
                                                 InputStream inputStream)  {
        uploadFileByInputStream(bucketName, objectName, inputStream, 1);
    }

    /**
     * 简单文件上传
     * 注:同一个bucketName下,objectName不要一样,否者会覆盖前面的文件
     *    追注:对某个Object而言,其的objectName即为其key, 而key需要具有唯一性
     *
     * @param bucketName
     *            bucket介绍:存储空间是您⽤于存储对象(Object)的容 器,所有的对象都必须⾪属于某个存储空间。
     * @param objectName
     *            自定义上传后的文件名
     * @param inputStream
     *            (流的形式)Object
     * @param tryTimes
     *            第几次调用
     */
    private static void uploadFileByInputStream(String bucketName,
                                                  String objectName,
                                                  InputStream inputStream,
                                                  int tryTimes)  {
        PutObjectResult result;
        try {
            // 如果存储空间不存在,那么直接创建
            if (!ossClient.doesBucketExist(bucketName)) {
                createBucket(bucketName);
            }
            result = ossClient.putObject(bucketName, objectName, inputStream);
            log.info(" uploadFileByInputStream result is -> {}", JSON.toJSONString(result));
        } catch (Exception e) {
            if (isConnectionPoolOpen(e) || tryTimes > tryTimesUpperLimit) {
                throw e;
            }
            // 如果客户端已关闭,那么再次初始化即可
            initOssClient();
            uploadFileByInputStream(bucketName, objectName, inputStream, ++tryTimes);
        }
        // 关闭OSSClient。
        ossClient.shutdown();
    }

    /**
     * 连接池是否开启(即:连接池是否还未shutdown)
     *
     * @param e
     *            客户端异常
     * @return  连接池是否仍然开启着
     *            -true,连接池开启着(即:连接池未关闭),
     *            -false连接池已关闭
     */
    private static boolean isConnectionPoolOpen(Exception e) {
        String message = e.getMessage();
        if (message == null) {
            return true;
        }
        return !message.contains("Connection pool shut down");
    }

    /**
     * 连接池是否开启(即:连接池是否还未shutdown)
     *
     * @return  连接池是否仍然开启着
     *            -true,连接池开启着(即:连接池未关闭),
     *            -false连接池已关闭
     */
    private static boolean isConnectionPoolOpen() {
        if (ossClient == null) {
            return false;
        }
        try {
            ossClient.doesBucketExist(IS_CONNECTION_POOL_OPEN_HELPER);
        } catch (Exception e) {
            return isConnectionPoolOpen(e);
        }
        return true;
    }

    /**
     * 关闭客户端
     *
     * 注:此方法只是提供提供出来。因为是多线程共用的同一个客户端,
     *    所以一般情况下不关闭客户端即可。
     */
    public static void closeClient() {
        ossClient.shutdown();
    }
    
    /**
     * 获取文件可访问URL
     *
     * @param bucketName
     *            文件所在的bucket名
     * @param key
     *            文件的key(即:文件上传时,自定义的文件名objectName)
     * @param expirationTime
     *            此连接的有效时长(单位毫秒)
     * @return  文件的URL
     * @date 2019/9/8 2:34
     */
    public static String getFileUrl(String bucketName, String key, long expirationTime){
        String url = getFileUrl(bucketName, key, expirationTime, 1);
        log.info(" this file's address is -> {}", url);
        return url;
    }

    /**
     * 获取文件可访问URL
     *
     * @param bucketName
     *            文件所在的bucket名
     * @param key
     *            文件的key(即:文件上传时,自定义的文件名objectName)
     * @param expirationTime
     *            此连接的有效时长(单位毫秒)
     * @param tryTimes
     *            第几次调用
     *
     * @return  文件的URL
     */
    private static String getFileUrl(String bucketName, String key, long expirationTime, int tryTimes){
        long now = System.currentTimeMillis();
        try {
            return ossClient.generatePresignedUrl(bucketName, key, new Date(now + expirationTime)).toString();
        } catch (Exception e) {
            if (isConnectionPoolOpen(e) || tryTimes > tryTimesUpperLimit) {
                throw e;
            }
            // 如果客户端已关闭,那么再次初始化即可
            initOssClient();
            return getFileUrl(bucketName, key, expirationTime, ++tryTimes);
        }
    }


    /**
     * main直接测试
     */
/*    public static void main(String[] args) throws FileNotFoundException {

        init("http://oss-cn-shenzhen.aliyuncs.com", "XXXX", "XXXX");
        isConnectionPoolOpen();
        String fileurl = "timg.jpg";
        InputStream is = new FileInputStream("C:\\Users\\Administrator\\Desktop\\图片\\"+fileurl);
        uploadFileByInputStream("lcx-0316", fileurl, is);
        long oneHundredYears =  24 * 60 * 60 * 1000L;
        System.out.println(
                getFileUrl(BACKET_NAME, fileurl, oneHundredYears)
        );
    }*/
}
 

 

 因为在项目中许多地方有用到上传,所以单独拆出复用

 

package com.project.lddproject.Authentication.utils;


import com.project.lddproject.Authentication.constans.OSSClientConstants;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.security.SecureRandom;
import java.text.SimpleDateFormat;
import java.util.Calendar;

import static com.project.lddproject.Authentication.constans.OSSClientConstants.FILESIZE;

/**
 * @Author:    Liuchunxi
 * @Description:  图片上传【OSS图像存储上传抽取】
 * @Date: 2019/11/17 16:12
 * @Modified:
 */
@Component
public class CommonUpload {

    @Value("${aliyun.oss.key}")
    private String ACCESS_KEY_ID;

    @Value("${aliyun.oss.secret}")
    private String ACCESS_KEY_SECRET;

    @Value("${aliyun.oss.endpoint}")
    private String ENDPOINT;

    @Value("${aliyun.oss.bucket-name}")
    private String BACKET_NAME;

    public String uploadFile(MultipartFile file,String objectAttendance) throws IOException {

        AliYunOssUtil.init(ENDPOINT,ACCESS_KEY_ID,ACCESS_KEY_SECRET);

            // 图片大小限制于上一步拦截
            InputStream is = file.getInputStream();
            // 时间戳 + 随机数, 防止文件重名
            SecureRandom random = new SecureRandom();
            String fileName = file.getOriginalFilename();
            //获取文件后缀
            String suffix = fileName.substring(fileName.lastIndexOf("."));
            //在OSS Bucket下 以日期为界限创建虚拟文件夹分类保存文件(存在直接插入,不存在的话会创建后插入)
            Calendar calendar = Calendar.getInstance();
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            //因为里面要嵌套一个虚拟文件夹,这里是认证相关的图片上传所以写死auth
//            String folder = "auth/"+sdf.format(calendar.getTime()) + "/";

            String folder = objectAttendance + "/" + sdf.format(calendar.getTime()) + "/";
            //(使用这个的话就不用添加后缀了,fileName有后缀)
//         String newFileName = "cmd/"+System.currentTimeMillis() + "_" + random.nextInt(1000) + "_" + fileName;

            //新建 上传OSS的文件名   random.nextInt(1000) 为时间戳+随机数截取三位
            String newFileName = folder + System.currentTimeMillis() + "_" + random.nextInt(1000) + suffix ;

            AliYunOssUtil.uploadFileByInputStream(BACKET_NAME,newFileName,is);
            long oneHundredYears = 24*60*60*1000L;
            String fileUrl = AliYunOssUtil.getFileUrl(BACKET_NAME, newFileName, oneHundredYears);
            file.getInputStream().close();
            return fileUrl;
        }
}
 

使用到的依赖:

<!--Oss-->
<dependency>
    <groupId>com.aliyun.oss</groupId>
    <artifactId>aliyun-sdk-oss</artifactId>
    <version>2.8.1</version>
</dependency>

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值