SpringBoot整合OSS文件服务器(文件上传、下载及在线地址)

pom引入依赖包

		<!--阿里云oss-->
        <dependency>
            <groupId>com.aliyun.oss</groupId>
            <artifactId>aliyun-sdk-oss</artifactId>
            <version>3.8.0</version>
        </dependency>

阿里云OSS配置(yml)

#阿里云oss
aliyun:
  endpoint: http://oss-cn-beijing.aliyuncs.com  # oss对外服务的访问域名
  access-key-id: *****njArc******3s # 访问身份验证中用到用户标识
  access-key-secret: *******WB9**** # 用户用于加密签名字符串和oss用来验证签名字符串的密钥
  bucket: *** #桶名(文件目录)
  dir:

工具类,复制即用

/**
 * 阿里云-OSS文件类
 */
@Slf4j
@Configuration
@PropertySource("classpath:/application.yml")
@Component
public class AliOssCloudUtil {

    @Value("${aliyun.endpoint:#{null}}")
    private String endpoint;

    @Value("${aliyun.access-key-id:#{null}}")
    private String accessKeyId;

    @Value("${aliyun.access-key-secret:#{null}}")
    private String accessKeySecret;

    @Value("${aliyun.bucket:#{null}}")
    private String bucketName;

    @Value("${aliyun.dir:#{null}}")
    private String dir;


    public String getDir() {
        return dir;
    }

    /**
     * 获取OSS
     * @return
     */
    public OSS getOSSClient(){
        return new OSSClientBuilder().build(endpoint,accessKeyId,accessKeySecret);
    }


    /**
     * 上传到OSS服务器
     *
     * @param instream 文件流
     * @param fileName 文件名称 包括后缀名
     * @return 出错返回"" ,唯一MD5数字签名
     */
    public String uploadFile2OSS(InputStream instream, String fileName) {
        OSS ossClient = getOSSClient();
        String ret = "";
        // 判断bucket是否已经存在,不存在进行创建
        if (!doesBucketExist(ossClient)) {
            createBucket(ossClient);
        }
        try {
            //创建上传Object的Metadata
            ObjectMetadata objectMetadata = new ObjectMetadata();
            objectMetadata.setContentLength(instream.available());
            objectMetadata.setCacheControl("no-cache");
            objectMetadata.setHeader("Pragma", "no-cache");
            objectMetadata.setContentType(getcontentType(fileName.substring(fileName.lastIndexOf("."))));
            objectMetadata.setContentDisposition("inline;filename=" + fileName);

            // 指定上传文件操作时是否覆盖同名Object。
            // 不指定x-oss-forbid-overwrite时,默认覆盖同名Object。
            // 指定x-oss-forbid-overwrite为false时,表示允许覆盖同名Object。
            // 指定x-oss-forbid-overwrite为true时,表示禁止覆盖同名Object,如果同名Object已存在,程序将报错。
            objectMetadata.setHeader("x-oss-forbid-overwrite", "false");
            String objectName = dir + fileName;

            //上传文件
            ossClient.putObject(bucketName, objectName, instream, objectMetadata);
            // 设置URL过期时间(7天)
            Date expiration = new Date(System.currentTimeMillis() + 3600 * 1000 * 24 * 7);
            URL url = ossClient.generatePresignedUrl(bucketName, objectName,expiration);
            log.info(objectName);
            ret = url.toString().split("\\?")[0];
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            ossClient.shutdown();
            try {
                if (instream != null) {
                    instream.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return ret;
    }

    /**
     * 获取文件在线地址
     * @param objectName 文件路径 filePath
     * @param expiration  过期时间
     * @return 返回文件在线路径
     */
    public String getOnlineAddress(String objectName,Date expiration){
        OSS ossClient = getOSSClient();
        String ret = null;
        try {
            URL url = ossClient.generatePresignedUrl(bucketName, objectName,expiration);
            ret = url.toString().split("\\?")[0];
        } catch (ClientException e) {
            e.printStackTrace();
        }finally {
            ossClient.shutdown();
        }
        return ret;
    }


    /**
     * 判断文件是否存在。doesObjectExist还有一个参数isOnlyInOSS,
     * 如果为true则忽略302重定向或镜像;如果为false,则考虑302重定向或镜像。
     * yourObjectName 表示上传文件到OSS时需要指定包含文件后缀在内的完整路径,例如abc/efg/123.jpg。
     *
     * @return 存在返回true
     */
    public boolean doesObjectExist(OSS ossClient,String objectName) {
        boolean exists = ossClient.doesObjectExist(bucketName, dir + objectName);
        return exists;
    }

    /**
     * 判断Bucket是否存在
     *
     * @return 存在返回true
     */
    public boolean doesBucketExist(OSS ossClient) {
        boolean exists = ossClient.doesBucketExist(bucketName);
        return exists;
    }

    /**
     * 创建Bucket
     */
    public void createBucket(OSS ossClient) {
        CreateBucketRequest createBucketRequest = new CreateBucketRequest(bucketName);
        // 设置bucket权限为公共读,默认是私有读写
        createBucketRequest.setCannedACL(CannedAccessControlList.PublicRead);
        // 设置bucket存储类型为低频访问类型,默认是标准类型
        createBucketRequest.setStorageClass(StorageClass.IA);
        boolean exists = ossClient.doesBucketExist(bucketName);
        if (!exists) {
            try {
                ossClient.createBucket(createBucketRequest);
                // 关闭client
//                ossClient.shutdown();
            } catch (Exception e) {
                log.error(e.getMessage());
            }
        }
    }

    /**
     * 判断OSS服务文件上传时文件的contentType
     * @param FilenameExtension 文件后缀
     * @return String
     */
    public static String getcontentType(String FilenameExtension) {
        if ("bmp".equalsIgnoreCase(FilenameExtension)) {
            return "image/bmp";
        }
        if ("gif".equalsIgnoreCase(FilenameExtension)) {
            return "image/gif";
        }
        if ("jpeg".equalsIgnoreCase(FilenameExtension) ||
                "jpg".equalsIgnoreCase(FilenameExtension) ||
                "png".equalsIgnoreCase(FilenameExtension)) {
            return "image/jpeg";
        }
        if ("html".equalsIgnoreCase(FilenameExtension)) {
            return "text/html";
        }
        if ("txt".equalsIgnoreCase(FilenameExtension)) {
            return "text/plain";
        }
        if ("vsd".equalsIgnoreCase(FilenameExtension)) {
            return "application/vnd.visio";
        }
        if ("pptx".equalsIgnoreCase(FilenameExtension) ||
                "ppt".equalsIgnoreCase(FilenameExtension)) {
            return "application/vnd.ms-powerpoint";
        }
        if ("docx".equalsIgnoreCase(FilenameExtension) ||
                "doc".equalsIgnoreCase(FilenameExtension)) {
            return "application/msword";
        }
        if ("xml".equalsIgnoreCase(FilenameExtension)) {
            return "text/xml";
        }
        return "image/jpeg";
    }


    /**
     * 通过文件名下载文件
     *
     * @param objectName    要下载的文件名
     * @param localFileName 本地要创建的文件名
     */
    public void downloadFile(HttpServletResponse response, String objectName, String localFileName){
        // 创建OSSClient实例。
        OSS ossClient = getOSSClient();
        try {
            // ossObject包含文件所在的存储空间名称、文件名称、文件元信息以及一个输入流。
            OSSObject ossObject = ossClient.getObject(bucketName, objectName);
            // 读去Object内容  返回
            BufferedInputStream in = new BufferedInputStream(ossObject.getObjectContent());

            BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream());
            //通知浏览器以附件形式下载
            response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(objectName, "utf-8"));
            //BufferedOutputStream out=new BufferedOutputStream(new FileOutputStream(new File("f:\\a.txt")));
            byte[] car = new byte[1024];
            int L = 0;
            while ((L = in.read(car)) != -1) {
                out.write(car, 0, L);

            }
            if (out != null) {
                out.flush();
                out.close();
            }
            if (in != null) {
                in.close();
            }

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 关闭OSSClient。
            ossClient.shutdown();
        }
    }

    /**
     *  批量下载为zip
     * @param response
     * @param fileName  oss文件路径集合
     * @param fileName 下载出来的zip文件名(一般以合同名命名) 如:测试合同,zip
     */
    public void downForZip( HttpServletResponse response,List<String> filePath,String fileName){
        // 创建临时文件
        File zipFile = null;
        try {
            zipFile = File.createTempFile("test", ".zip");

            FileOutputStream f = new FileOutputStream(zipFile);
            /**
             * 作用是为任何OutputStream产生校验和
             * 第一个参数是制定产生校验和的输出流,第二个参数是指定Checksum的类型 (Adler32(较快)和CRC32两种)
             */
            CheckedOutputStream csum = new CheckedOutputStream(f, new Adler32());
            // 用于将数据压缩成Zip文件格式
            ZipOutputStream zos = new ZipOutputStream(csum);
            OSS ossClient=  getOSSClient();
            for (String ossFile : filePath) {
                // 获取Object,返回结果为OSSObject对象

                OSSObject ossObject = ossClient.getObject(bucketName, ossFile);
                // 读去Object内容  返回
                InputStream inputStream = ossObject.getObjectContent();
                // 对于每一个要被存放到压缩包的文件,都必须调用ZipOutputStream对象的putNextEntry()方法,确保压缩包里面文件不同名
                String name=ossFile.substring(ossFile.lastIndexOf("/")+1);
                zos.putNextEntry(new ZipEntry(name));
                int bytesRead = 0;
                // 向压缩文件中输出数据
                while ((bytesRead = inputStream.read()) != -1) {
                    zos.write(bytesRead);
                }
                inputStream.close();
                zos.closeEntry(); // 当前文件写完,定位为写入下一条项目
            }
            zos.close();
            response.reset();
            response.setContentType("text/plain");
            response.setContentType("application/octet-stream; charset=utf-8");
            response.setHeader("Location", fileName);
            response.setHeader("Cache-Control", "max-age=0");
            response.setHeader("Content-Disposition", "attachment; filename=" + fileName);

            FileInputStream fis = new FileInputStream(zipFile);
            BufferedInputStream buff = new BufferedInputStream(fis);
            BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream());
            byte[] car = new byte[1024];
            int l = 0;
            while (l < zipFile.length()) {
                int j = buff.read(car, 0, 1024);
                l += j;
                out.write(car, 0, j);
            }
            // 关闭流
            fis.close();
            buff.close();
            out.close();

            ossClient.shutdown();
            // 删除临时文件
            zipFile.delete();
        }  catch (IOException e1) {
            e1.printStackTrace();
        }catch (Exception e) {
            e.printStackTrace();
        }

    }



}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值