Springboot集成阿里云OSS

原创
2020/06/12 18:19
阅读数 1.7K

1.导入pom文件

<!--阿里云oss-->
		<dependency>
			<groupId>com.aliyun.oss</groupId>
			<artifactId>aliyun-sdk-oss</artifactId>
			<version>3.4.2</version>
			<exclusions>
				<exclusion>
					<groupId>org.apache.httpcomponents</groupId>
					<artifactId>httpclient</artifactId>
				</exclusion>
			</exclusions>
		</dependency>

		<!-- https://mvnrepository.com/artifact/org.apache.httpcomponents/httpclient -->
		<dependency>
			<groupId>org.apache.httpcomponents</groupId>
			<artifactId>httpclient</artifactId>
			<version>4.4.1</version>
		</dependency>

2.在yml上配置配置文件

# 阿里云oss
oss:
  endpoint: http://oss-cn-beijing.aliyuncs.com
  accessKeyId: *
  accessKeySecret: *
  bucketName: *

3.编写配置文件 AliyunOssConfig.java

package com.un.common.utils.oss;

import org.springframework.beans.factory.InitializingBean;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;

/**
 * @author shiye
 * @create 2020-06-12 17:18
 */
@Configuration
@ConfigurationProperties(prefix = "oss")
public class AliyunOssConfig implements InitializingBean {

    /**
     * 阿里云 oss 站点
     */
    private String endpoint;

    /**
     * 阿里云 oss 公钥
     */
    private String accessKeyId;

    /**
     * 阿里云 oss 私钥
     */
    private String accessKeySecret;

    /**
     * 阿里云 oss 文件根目录
     */
    private String bucketName;

    //文件最大上传大小
    public static long FILE_MAX_SIZE = 1024 * 1024 * 10l;

    //图片过期时间 100年
    public static long FILE_EXPIRATION_TIME = 1000 * 3600 * 24 * 365 * 100;

    public static String JAVA_END_POINT;
    public static String JAVA_ACCESS_KEY_ID;
    public static String JAVA_ACCESS_KEY_SECRET;
    public static String JAVA_BUCKET_NAME;

    @Override
    public void afterPropertiesSet() throws Exception {
        JAVA_END_POINT = endpoint;
        JAVA_ACCESS_KEY_ID = accessKeyId;
        JAVA_ACCESS_KEY_SECRET = accessKeySecret;
        JAVA_BUCKET_NAME = bucketName;
    }


    public String getEndpoint() {
        return endpoint;
    }

    public void setEndpoint(String endpoint) {
        this.endpoint = endpoint;
    }

    public String getAccessKeyId() {
        return accessKeyId;
    }

    public void setAccessKeyId(String accessKeyId) {
        this.accessKeyId = accessKeyId;
    }

    public String getAccessKeySecret() {
        return accessKeySecret;
    }

    public void setAccessKeySecret(String accessKeySecret) {
        this.accessKeySecret = accessKeySecret;
    }

    public String getBucketName() {
        return bucketName;
    }

    public void setBucketName(String bucketName) {
        this.bucketName = bucketName;
    }
}

4.编写请求参数和返回结果集

package com.un.common.utils.oss;

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;

import javax.validation.constraints.NotNull;
import java.io.Serializable;

/**
 * 主要是为了经过编码的文件上传
 *
 * @author shiye
 * @create 2020-06-10 16:37
 */
@ApiModel
public class FileUploadParam implements Serializable {

    @NotNull(message = "文件名称不能为空")
    @ApiModelProperty(value = "文件名称")
    private String fileName;

    @NotNull(message = "文件类型不能为空")
    @ApiModelProperty(value = "文件类型")
    private String fileType;

    /**
     * 经过base64编码后的文件
     */
    @NotNull(message = "文件内容不能为空")
    @ApiModelProperty(value = "文件内容")
    private String data;

    @ApiModelProperty(value = "文件夹,如:opendoor/ ")
    private String filePath = "opendoor/";

    public String getFileName() {
        return fileName;
    }

    public void setFileName(String fileName) {
        this.fileName = fileName;
    }

    public String getFileType() {
        return fileType;
    }

    public void setFileType(String fileType) {
        this.fileType = fileType;
    }

    public String getData() {
        return data;
    }

    public void setData(String data) {
        this.data = data;
    }

    public String getFilePath() {
        return filePath;
    }

    public void setFilePath(String filePath) {
        this.filePath = filePath;
    }

    @Override
    public String toString() {
        return "FileUploadParam{" +
                "fileName='" + fileName + '\'' +
                ", fileType='" + fileType + '\'' +
                ", data='" + data + '\'' +
                ", filePath='" + filePath + '\'' +
                '}';
    }
}

 

package com.un.common.utils.oss;

/**
 * 阿里云上传结果集
 *
 * @author shiye
 * @create 2020-06-10 15:35
 */
public class AliyunOssResult {

    /**
     * code:200长传成功
     * code: 400上传失败
     */
    private int code;

    /**
     * 上传成功的返回url
     */
    private String url;

    /**
     * 错误提示
     */
    private String errMsg;

    public AliyunOssResult() {
    }

    public AliyunOssResult(int code, String url, String errMsg) {
        this.code = code;
        this.url = url;
        this.errMsg = errMsg;
    }

    public int getCode() {
        return code;
    }

    public void setCode(int code) {
        this.code = code;
    }

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    public String getErrMsg() {
        return errMsg;
    }

    public void setErrMsg(String errMsg) {
        this.errMsg = errMsg;
    }

    @Override
    public String toString() {
        return "AliyunOssResult{" +
                "code=" + code +
                ", url='" + url + '\'' +
                ", errMsg='" + errMsg + '\'' +
                '}';
    }
}

工具类

package com.un.common.utils.oss;

import com.aliyun.oss.ClientConfiguration;
import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSSClient;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.common.auth.DefaultCredentialProvider;
import com.aliyun.oss.model.*;
import com.un.common.utils.StringUtils;
import org.springframework.context.annotation.Bean;
import org.springframework.web.multipart.MultipartFile;
import sun.misc.BASE64Decoder;

import java.io.*;
import java.net.URL;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;

/**
 * 阿里云oss工具类
 *
 * @author shiye
 * @create 2020-06-10 14:09
 */
public class AliyunOSSUtil {

    /**
     * oss 工具客户端
     */
    private volatile static OSSClient ossClient = null;


    /**
     * 上传文件至阿里云 OSS
     * 文件上传成功,返回文件完整访问路径
     *
     * @param file 上传文件
     * @return
     */
    public static AliyunOssResult upload(MultipartFile file) {
        if (file == null) {
            return new AliyunOssResult(400, null, "文件不能为空");
        }
        System.out.println(file.getSize());

        if (file.getSize() <= 0 || file.getSize() > AliyunOssConfig.FILE_MAX_SIZE) {
            return new AliyunOssResult(400, null, "文件不能大于10M");
        }


        //文件名称
        String oldName = file.getOriginalFilename();
        //文件后缀
        String postfix = oldName.substring(oldName.lastIndexOf(".") + 1, oldName.length());
        //新文件名称
        String fileName = UUID.randomUUID().toString().toUpperCase()
                .replace("-", "")
                + "." + postfix;
        //获取文件类型
        String fileType = file.getContentType();

        InputStream inputStream = null;
        try {
            inputStream = file.getInputStream();
        } catch (IOException e) {
            e.printStackTrace();
            return new AliyunOssResult(400, null, e.getMessage());
        }

        //上传文件
        AliyunOssResult resoult = putFile(inputStream, fileType, fileName);
        return resoult;
    }

    /**
     * 上传文件
     * 主要兼容客户端经过base64位编码的文件
     *
     * @param param
     * @return
     */
    public static AliyunOssResult upload(FileUploadParam param) {

        if (param == null || StringUtils.isEmpty(param.getData())) {
            return new AliyunOssResult(400, null, "文件不能为空");
        }
        //文件大小判断
        if (param.getData().length() <= 0 || param.getData().length() > AliyunOssConfig.FILE_MAX_SIZE) {
            return new AliyunOssResult(400, null, "文件不能大于10M");
        }

        //老文件名
        String oldName = param.getFileName();
        //文件类型
        String fileType = param.getFileType();
        //新文件名
        String fileName = UUID.randomUUID().toString().toUpperCase()
                .replace("-", "")
                + oldName.substring(oldName.lastIndexOf("."), oldName.length());

        InputStream inputStream = null;
        try {
            //将字符串转换为byte数组,这里的content是那一串base64密文
            byte[] bytes = new BASE64Decoder().decodeBuffer(param.getData());
            inputStream = new ByteArrayInputStream(bytes);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            return new AliyunOssResult(400, null, e.getMessage());
        } catch (IOException e) {
            e.printStackTrace();
            return new AliyunOssResult(400, null, e.getMessage());
        }

        //上传文件
        AliyunOssResult resoult = putFile(inputStream, fileType, fileName);
        return resoult;
    }


    /**
     * 上传文件
     *
     * @param input
     * @param fileType
     * @param fileName
     * @return
     */
    private static AliyunOssResult putFile(InputStream input, String fileType, String fileName) {
        AliyunOssResult resoult = null;

        //初始化客户端
        ossClient = ossClient == null ? initOSS() : ossClient;
        try {
            // 创建上传Object的Metadata
            ObjectMetadata meta = new ObjectMetadata();
            // 设置上传内容类型
            meta.setContentType(fileType);
            //被下载时网页的缓存行为
            meta.setCacheControl("no-cache");
            //创建上传请求
            PutObjectRequest request = new PutObjectRequest(AliyunOssConfig.JAVA_BUCKET_NAME, fileName, input, meta);
            //上传文件
            ossClient.putObject(request);

            //获取上传成功的文件地址
            resoult = new AliyunOssResult(200, getOssUrl(ossClient, fileName), null);
            System.out.println(resoult);
        } catch (OSSException | ClientException e) {
            e.printStackTrace();
            resoult = new AliyunOssResult(400, null, e.getMessage());
            return resoult;
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
        return resoult;
    }

    /**
     * 根据文件名生成文件的访问地址
     *
     * @param ossClient
     * @param key
     * @return
     */
    private static String getOssUrl(OSSClient ossClient, String key) {
        Date expiration = new Date(new Date().getTime() + AliyunOssConfig.FILE_EXPIRATION_TIME);// 生成URL
        GeneratePresignedUrlRequest generatePresignedUrlRequest;
        generatePresignedUrlRequest = new GeneratePresignedUrlRequest(AliyunOssConfig.JAVA_BUCKET_NAME, key);
        generatePresignedUrlRequest.setExpiration(expiration);
        URL url = ossClient.generatePresignedUrl(generatePresignedUrlRequest);
        return url.toString();
    }


    /**
     * 通过文件名下载文件
     *
     * @param fileNmae      要下载的文件名
     *                      例如:4DB049D0604047989183CB68D76E969D.jpg
     * @param localFileName 本地要创建的文件名
     *                      例如:C:\Users\Administrator\Desktop\test.jpg
     */
    public static void downloadFile(String fileNmae, String localFileName) {
        ossClient = ossClient == null ? initOSS() : ossClient;

        try {
            // 下载OSS文件到本地文件。如果指定的本地文件存在会覆盖,不存在则新建。
            ossClient.getObject(new GetObjectRequest(AliyunOssConfig.JAVA_BUCKET_NAME, fileNmae), new File(localFileName));
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
    }

    /**
     * @param file
     * @param fileType
     * @param oldUrl
     * @return String
     * @MethodName: updateFile
     * @Description: 更新文件:只更新内容,不更新文件名和文件地址。
     * (因为地址没变,可能存在浏览器原数据缓存,不能及时加载新数据,例如图片更新,请注意)
     */
//    public static String updateFile(File file, String fileType, String oldUrl) {
//        String fileName = getFileName(oldUrl);
//        if (fileName == null) return null;
//        return putFile(file, fileType, fileName);
//    }

    /**
     * @param file
     * @param fileType 文件后缀
     * @param oldUrl   需要删除的文件地址
     * @return String 文件地址
     * @MethodName: replaceFile
     * @Description: 替换文件:删除原文件并上传新文件,文件名和地址同时替换
     * 解决原数据缓存问题,只要更新了地址,就能重新加载数据)
     */
//    public static String replaceFile(File file, String fileType, String oldUrl) {
//        boolean flag = deleteFile(oldUrl);        //先删除原文件
//        if (!flag) {
//            //更改文件的过期时间,让他到期自动删除。
//        }
//        return uploadFile(file, fileType);
//    }

    /**
     * 列举 test 文件下所有的文件
     */
    public static List<String> listFile() {
        List<String> list = new ArrayList<>();
        ossClient = ossClient == null ? initOSS() : ossClient;
        try {
            // 构造ListObjectsRequest请求。
            ListObjectsRequest listObjectsRequest = new ListObjectsRequest(AliyunOssConfig.JAVA_BUCKET_NAME);

            // 设置prefix参数来获取fun目录下的所有文件。
//            listObjectsRequest.setPrefix("test/");
            // 列出文件。
            ObjectListing listing = ossClient.listObjects(listObjectsRequest);
            // 遍历所有文件。
            for (OSSObjectSummary objectSummary : listing.getObjectSummaries()) {
                //System.out.println(objectSummary.getKey());
                //把key全部转化成可以访问的url
                String url = getOssUrl(ossClient, objectSummary.getKey());
                list.add(url);
            }
            // 遍历所有commonPrefix。
//            for (String commonPrefix : listing.getCommonPrefixes()) {
//                System.out.println(commonPrefix);
//            }
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
        return list;
    }

    /**
     * @param fileUrls 需要删除的文件url集合
     * @return int 成功删除的个数
     * @MethodName: batchDeleteFiles
     * @Description: 批量文件删除(较慢):适用于不同endPoint和BucketName
     */
    private int deleteFiles(List<String> fileUrls) {
        int count = 0;
        for (String url : fileUrls) {
            if (deleteFile(url)) {
                count++;
            }
        }
        return count;
    }

    /**
     * @param fileUrls 需要删除的文件url集合
     * @return int 成功删除的个数
     * @MethodName: batchDeleteFiles
     * @Description: 批量文件删除(较快):适用于相同endPoint和BucketName
     */
    private int deleteFile(List<String> fileUrls) {
        ossClient = ossClient == null ? initOSS() : ossClient;
        int deleteCount = 0;    //成功删除的个数
        try {
            //根据url获取fileName
            List<String> fileNames = getFileName(fileUrls);
            if (AliyunOssConfig.JAVA_BUCKET_NAME == null || fileNames.size() <= 0) return 0;

            DeleteObjectsRequest request = new DeleteObjectsRequest(AliyunOssConfig.JAVA_BUCKET_NAME).withKeys(fileNames);
            DeleteObjectsResult result = ossClient.deleteObjects(request);
            deleteCount = result.getDeletedObjects().size();
        } catch (OSSException oe) {
            oe.printStackTrace();
            throw new RuntimeException("OSS服务异常:", oe);
        } catch (ClientException ce) {
            ce.printStackTrace();
            throw new RuntimeException("OSS客户端异常:", ce);
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
        return deleteCount;

    }

    /**
     * @param fileUrl 需要删除的文件url
     * @return boolean 是否删除成功
     * @MethodName: deleteFile
     * @Description: 单文件删除
     * 例如:http://*.oss-cn-beijing.aliyuncs.com/4DB049D0604047989183CB68D76E969D.jpg
     */
    public static boolean deleteFile(String fileUrl) {
        ossClient = ossClient == null ? initOSS() : ossClient;
        try {
            //根据url获取fileName
            String fileName = getFileName(fileUrl);
            if (AliyunOssConfig.JAVA_BUCKET_NAME == null || fileName == null) return false;
            GenericRequest request = new DeleteObjectsRequest(AliyunOssConfig.JAVA_BUCKET_NAME).withKey(fileName);
            ossClient.deleteObject(request);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
        return true;
    }

    /**
     * @param fileUrl 文件url
     * @return String fileName
     * @MethodName: getFileName
     * @Description: 根据url获取fileName
     */
    private static String getFileName(String fileUrl) {
        String str = "aliyuncs.com/";
        int beginIndex = fileUrl.indexOf(str);
        if (beginIndex == -1)
            return null;
        return fileUrl.substring(beginIndex + str.length());
    }

    /**
     * @param fileUrls 文件url
     * @return List<String>  fileName集合
     * @MethodName: getFileName
     * @Description: 根据url获取fileNames集合
     */
    private List<String> getFileName(List<String> fileUrls) {
        List<String> names = new ArrayList<>();
        for (String url : fileUrls) {
            names.add(getFileName(url));
        }
        return names;
    }


    /**
     * @param fileType
     * @return String
     * @MethodName: contentType
     * @Description: 获取文件类型
     */
    private String contentType(String fileType) {
        fileType = fileType.toLowerCase();
        String contentType = "";
        switch (fileType) {
            case "bmp":
                contentType = "image/bmp";
                break;
            case "gif":
                contentType = "image/gif";
                break;
            case "png":
            case "jpeg":
            case "jpg":
                contentType = "image/jpeg";
                break;
            case "html":
                contentType = "text/html";
                break;
            case "txt":
                contentType = "text/plain";
                break;
            case "vsd":
                contentType = "application/vnd.visio";
                break;
            case "ppt":
            case "pptx":
                contentType = "application/vnd.ms-powerpoint";
                break;
            case "doc":
            case "docx":
                contentType = "application/msword";
                break;
            case "xml":
                contentType = "text/xml";
                break;
            case "mp4":
                contentType = "video/mp4";
                break;
            default:
                contentType = "application/octet-stream";
                break;
        }
        return contentType;
    }


    /**
     * 使用单例模式
     * 初始化 oss 客户端
     *
     * @return
     */
    private static OSSClient initOSS() {
        if (ossClient == null) {
            synchronized (AliyunOSSUtil.class) {
                if (ossClient == null) {
                    ossClient = new OSSClient(AliyunOssConfig.JAVA_END_POINT,
                            new DefaultCredentialProvider(AliyunOssConfig.JAVA_ACCESS_KEY_ID, AliyunOssConfig.JAVA_ACCESS_KEY_SECRET),
                            new ClientConfiguration());
                }
            }
        }
        return ossClient;
    }

}

5.编写测试文件

package com.un.project.system.controller;

import com.un.common.utils.oss.AliyunOSSUtil;
import com.un.common.utils.oss.AliyunOssResult;
import com.un.common.utils.oss.FileUploadParam;
import com.un.framework.aspectj.lang.annotation.Log;
import com.un.framework.aspectj.lang.enums.BusinessType;
import com.un.framework.web.domain.AjaxResult;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.List;

/**
 * @author shiye
 * @create 2020-06-10 16:10
 */
@Api("阿里云oss测试")
@RestController
@RequestMapping("/oss")
public class OssTestController {

    @Log(title = "上传MultipartFile类型的文件", businessType = BusinessType.UPDATE)
    @PostMapping("/uploadFile")
    @ApiOperation("上传MultipartFile类型的文件")
    public AjaxResult uploadFile(MultipartFile file) throws IOException {

        AliyunOssResult result = AliyunOSSUtil.upload(file);
        return AjaxResult.success(result);
    }

    @Log(title = "上传base64编码的文件", businessType = BusinessType.UPDATE)
    @PostMapping("/uploadData")
    @ApiOperation("上传base64编码的文件")
    public AjaxResult uploadData(@RequestBody @Validated FileUploadParam param) throws IOException {

        AliyunOssResult result = AliyunOSSUtil.upload(param);
        return AjaxResult.success(result);
    }

    @Log(title = "下载文件", businessType = BusinessType.UPDATE)
    @PostMapping("/downloadFile")
    @ApiOperation("下载文件")
    public AjaxResult downloadFile(String fileNmae, String localFileName) throws IOException {

        AliyunOSSUtil.downloadFile(fileNmae, localFileName);
        return AjaxResult.success();
    }

    @Log(title = "删除文件", businessType = BusinessType.UPDATE)
    @PostMapping("/deleteFile")
    @ApiOperation("删除文件")
    public AjaxResult deleteFile(String fileUrl) throws IOException {

        AliyunOSSUtil.deleteFile(fileUrl);
        return AjaxResult.success();
    }


    @Log(title = "获取当前系统下所有文件", businessType = BusinessType.UPDATE)
    @PostMapping("/listFile")
    @ApiOperation("获取当前系统下所有文件")
    public AjaxResult listFile() throws IOException {
        List<String> list = AliyunOSSUtil.listFile();
        return AjaxResult.success(list);
    }

}

 

补充:增加阿里云oss多实例,解决并发性问题,并且增加上传文件夹

package com.un.common.utils.oss;

import com.aliyun.oss.ClientConfiguration;
import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSSClient;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.common.auth.DefaultCredentialProvider;
import com.aliyun.oss.model.*;
import com.un.common.utils.StringUtils;
import org.springframework.web.multipart.MultipartFile;
import sun.misc.BASE64Decoder;

import java.io.*;
import java.net.URL;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;

/**
 * 阿里云oss工具类
 *
 * @author shiye
 * @create 2020-06-10 14:09
 */
public class AliyunOSSUtil {

    /**
     * oss 工具客户端
     */
//    private volatile static OSSClient ossClient = null;


    /**
     * 上传文件至阿里云 OSS
     * 文件上传成功,返回文件完整访问路径
     *
     * @param file
     * @param filePath 文件路径,格式如:testPath/
     * @return
     */
    public static AliyunOssResult upload(MultipartFile file, String filePath) {
        if (file == null) {
            return new AliyunOssResult(400, null, "文件不能为空");
        }
        System.out.println(file.getSize());

        if (file.getSize() <= 0 || file.getSize() > AliyunOssConfig.FILE_MAX_SIZE) {
            return new AliyunOssResult(400, null, "文件不能大于10M");
        }


        //文件名称
        String oldName = file.getOriginalFilename();
        //文件后缀
        String postfix = oldName.substring(oldName.lastIndexOf(".") + 1, oldName.length());
        //新文件名称
        String fileName = filePath + UUID.randomUUID().toString().toUpperCase()
                .replace("-", "")
                + "." + postfix;
        //获取文件类型
        String fileType = file.getContentType();

        InputStream inputStream = null;
        try {
            inputStream = file.getInputStream();
        } catch (IOException e) {
            e.printStackTrace();
            return new AliyunOssResult(400, null, e.getMessage());
        }

        //上传文件
        AliyunOssResult resoult = putFile(inputStream, fileType, fileName);
        return resoult;
    }

    /**
     * 上传文件
     * 主要兼容客户端经过base64位编码的文件
     *
     * @param param
     * @return
     */
    public static AliyunOssResult upload(FileUploadParam param) {

        if (param == null || StringUtils.isEmpty(param.getData())) {
            return new AliyunOssResult(400, null, "文件不能为空");
        }
        //文件大小判断
        if (param.getData().length() <= 0 || param.getData().length() > AliyunOssConfig.FILE_MAX_SIZE) {
            return new AliyunOssResult(400, null, "文件不能大于10M");
        }

        //老文件名
        String oldName = param.getFileName();
        //文件类型
        String fileType = param.getFileType();
        //新文件名+指定文件夹
        String fileName = param.getFilePath() + UUID.randomUUID().toString().toUpperCase()
                .replace("-", "")
                + oldName.substring(oldName.lastIndexOf("."), oldName.length());

        InputStream inputStream = null;
        try {
            //将字符串转换为byte数组,这里的content是那一串base64密文
            byte[] bytes = new BASE64Decoder().decodeBuffer(param.getData());
            inputStream = new ByteArrayInputStream(bytes);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            return new AliyunOssResult(400, null, e.getMessage());
        } catch (IOException e) {
            e.printStackTrace();
            return new AliyunOssResult(400, null, e.getMessage());
        }

        //上传文件
        AliyunOssResult resoult = putFile(inputStream, fileType, fileName);
        return resoult;
    }

    /**
     * 直接把输入流传到oss 中
     *
     * @param inputStream 文件流
     * @param fileType    文件类型
     * @param fileName    文件名
     * @param filePath    文件路径,格式如:testPath/
     * @return
     */
    public static AliyunOssResult upload(InputStream inputStream, String fileType, String fileName, String filePath) {
        fileName = filePath + fileName;
        AliyunOssResult result = putFile(inputStream, fileType, fileName);
        return result;
    }

    /**
     * 上传文件
     *
     * @param input
     * @param fileType
     * @param fileName
     * @return
     */
    private static AliyunOssResult putFile(InputStream input, String fileType, String fileName) {
        AliyunOssResult resoult = null;

        //初始化客户端
        OSSClient ossClient = initOSS();
        try {
            // 创建上传Object的Metadata
            ObjectMetadata meta = new ObjectMetadata();
            // 设置上传内容类型
            meta.setContentType(fileType);
            //被下载时网页的缓存行为
            meta.setCacheControl("no-cache");
            //创建上传请求
            PutObjectRequest request = new PutObjectRequest(AliyunOssConfig.JAVA_BUCKET_NAME, fileName, input, meta);
            //上传文件
            ossClient.putObject(request);

            //获取上传成功的文件地址
            resoult = new AliyunOssResult(200, getOssUrl(ossClient, fileName), null);
        } catch (OSSException | ClientException e) {
            e.printStackTrace();
            resoult = new AliyunOssResult(400, null, e.getMessage());
            return resoult;
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
                ossClient = null;
            }
        }
        return resoult;
    }

    /**
     * 根据文件名生成文件的访问地址
     *
     * @param ossClient
     * @param key
     * @return
     */
    private static String getOssUrl(OSSClient ossClient, String key) {
        Date expiration = new Date(new Date().getTime() + AliyunOssConfig.FILE_EXPIRATION_TIME);// 生成URL
        GeneratePresignedUrlRequest generatePresignedUrlRequest;
        generatePresignedUrlRequest = new GeneratePresignedUrlRequest(AliyunOssConfig.JAVA_BUCKET_NAME, key);
        generatePresignedUrlRequest.setExpiration(expiration);
        URL url = ossClient.generatePresignedUrl(generatePresignedUrlRequest);
        return url.toString();
    }


    /**
     * 通过文件名下载文件
     *
     * @param fileNmae      要下载的文件名
     *                      例如:4DB049D0604047989183CB68D76E969D.jpg
     * @param localFileName 本地要创建的文件名
     *                      例如:C:\Users\Administrator\Desktop\test.jpg
     */
    public static void downloadFile(String fileNmae, String localFileName) {
        OSSClient ossClient = initOSS();
        try {
            // 下载OSS文件到本地文件。如果指定的本地文件存在会覆盖,不存在则新建。
            ossClient.getObject(new GetObjectRequest(AliyunOssConfig.JAVA_BUCKET_NAME, fileNmae), new File(localFileName));
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
                ossClient = null;
            }
        }
    }

    /**
     * @param file
     * @param fileType
     * @param oldUrl
     * @return String
     * @MethodName: updateFile
     * @Description: 更新文件:只更新内容,不更新文件名和文件地址。
     * (因为地址没变,可能存在浏览器原数据缓存,不能及时加载新数据,例如图片更新,请注意)
     */
//    public static String updateFile(File file, String fileType, String oldUrl) {
//        String fileName = getFileName(oldUrl);
//        if (fileName == null) return null;
//        return putFile(file, fileType, fileName);
//    }

    /**
     * @param file
     * @param fileType 文件后缀
     * @param oldUrl   需要删除的文件地址
     * @return String 文件地址
     * @MethodName: replaceFile
     * @Description: 替换文件:删除原文件并上传新文件,文件名和地址同时替换
     * 解决原数据缓存问题,只要更新了地址,就能重新加载数据)
     */
//    public static String replaceFile(File file, String fileType, String oldUrl) {
//        boolean flag = deleteFile(oldUrl);        //先删除原文件
//        if (!flag) {
//            //更改文件的过期时间,让他到期自动删除。
//        }
//        return uploadFile(file, fileType);
//    }

    /**
     * 列举 test 文件下所有的文件
     */
    public static List<String> listFile() {
        List<String> list = new ArrayList<>();
        OSSClient ossClient = initOSS();
        try {
            // 构造ListObjectsRequest请求。
            ListObjectsRequest listObjectsRequest = new ListObjectsRequest(AliyunOssConfig.JAVA_BUCKET_NAME);

            // 设置prefix参数来获取fun目录下的所有文件。
//            listObjectsRequest.setPrefix("test/");
            // 列出文件。
            ObjectListing listing = ossClient.listObjects(listObjectsRequest);
            // 遍历所有文件。
            for (OSSObjectSummary objectSummary : listing.getObjectSummaries()) {
                //System.out.println(objectSummary.getKey());
                //把key全部转化成可以访问的url
                String url = getOssUrl(ossClient, objectSummary.getKey());
                list.add(url);
            }
            // 遍历所有commonPrefix。
//            for (String commonPrefix : listing.getCommonPrefixes()) {
//                System.out.println(commonPrefix);
//            }
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
                ossClient = null;
            }
        }
        return list;
    }

    /**
     * @param fileUrls 需要删除的文件url集合
     * @return int 成功删除的个数
     * @MethodName: batchDeleteFiles
     * @Description: 批量文件删除(较慢):适用于不同endPoint和BucketName
     */
    private int deleteFiles(List<String> fileUrls) {
        int count = 0;
        for (String url : fileUrls) {
            if (deleteFile(url)) {
                count++;
            }
        }
        return count;
    }

    /**
     * @param fileUrls 需要删除的文件url集合
     * @return int 成功删除的个数
     * @MethodName: batchDeleteFiles
     * @Description: 批量文件删除(较快):适用于相同endPoint和BucketName
     */
    private int deleteFile(List<String> fileUrls) {
        OSSClient ossClient = initOSS();
        int deleteCount = 0;    //成功删除的个数
        try {
            //根据url获取fileName
            List<String> fileNames = getFileName(fileUrls);
            if (AliyunOssConfig.JAVA_BUCKET_NAME == null || fileNames.size() <= 0) return 0;

            DeleteObjectsRequest request = new DeleteObjectsRequest(AliyunOssConfig.JAVA_BUCKET_NAME).withKeys(fileNames);
            DeleteObjectsResult result = ossClient.deleteObjects(request);
            deleteCount = result.getDeletedObjects().size();
        } catch (OSSException oe) {
            oe.printStackTrace();
            throw new RuntimeException("OSS服务异常:", oe);
        } catch (ClientException ce) {
            ce.printStackTrace();
            throw new RuntimeException("OSS客户端异常:", ce);
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
                ossClient = null;
            }
        }
        return deleteCount;

    }

    /**
     * @param fileUrl 需要删除的文件url
     * @return boolean 是否删除成功
     * @MethodName: deleteFile
     * @Description: 单文件删除
     * 例如:http://*.oss-cn-beijing.aliyuncs.com/4DB049D0604047989183CB68D76E969D.jpg
     */
    public static boolean deleteFile(String fileUrl) {
        OSSClient ossClient = initOSS();
        try {
            //根据url获取fileName
            String fileName = getFileName(fileUrl);
            if (AliyunOssConfig.JAVA_BUCKET_NAME == null || fileName == null) return false;
            GenericRequest request = new DeleteObjectsRequest(AliyunOssConfig.JAVA_BUCKET_NAME).withKey(fileName);
            ossClient.deleteObject(request);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
                ossClient = null;
            }
        }
        return true;
    }

    /**
     * @param fileUrl 文件url
     * @return String fileName
     * @MethodName: getFileName
     * @Description: 根据url获取fileName
     */
    private static String getFileName(String fileUrl) {
        String str = "aliyuncs.com/";
        int beginIndex = fileUrl.indexOf(str);
        if (beginIndex == -1)
            return null;
        return fileUrl.substring(beginIndex + str.length());
    }

    /**
     * @param fileUrls 文件url
     * @return List<String>  fileName集合
     * @MethodName: getFileName
     * @Description: 根据url获取fileNames集合
     */
    private List<String> getFileName(List<String> fileUrls) {
        List<String> names = new ArrayList<>();
        for (String url : fileUrls) {
            names.add(getFileName(url));
        }
        return names;
    }


    /**
     * @param fileType
     * @return String
     * @MethodName: contentType
     * @Description: 获取文件类型
     */
    public static String contentType(String fileType) {
        fileType = fileType.toLowerCase();
        String contentType = "";
        switch (fileType) {
            case "bmp":
                contentType = "image/bmp";
                break;
            case "gif":
                contentType = "image/gif";
                break;
            case "png":
            case "jpeg":
            case "jpg":
                contentType = "image/jpeg";
                break;
            case "html":
                contentType = "text/html";
                break;
            case "txt":
                contentType = "text/plain";
                break;
            case "vsd":
                contentType = "application/vnd.visio";
                break;
            case "ppt":
            case "pptx":
                contentType = "application/vnd.ms-powerpoint";
                break;
            case "doc":
            case "docx":
                contentType = "application/msword";
                break;
            case "xml":
                contentType = "text/xml";
                break;
            case "mp4":
                contentType = "video/mp4";
                break;
            default:
                contentType = "application/octet-stream";
                break;
        }
        return contentType;
    }


    /**
     * 使用单例模式
     * 初始化 oss 客户端
     *
     * @return
     */
    private static OSSClient initOSS() {
        OSSClient ossClient = null;
        if (ossClient == null) {
            synchronized (AliyunOSSUtil.class) {
                if (ossClient == null) {
                    ossClient = new OSSClient(AliyunOssConfig.JAVA_END_POINT,
                            new DefaultCredentialProvider(AliyunOssConfig.JAVA_ACCESS_KEY_ID, AliyunOssConfig.JAVA_ACCESS_KEY_SECRET),
                            new ClientConfiguration());
                }
            }
        }
        return ossClient;
    }

}

 

 

展开阅读全文
打赏
0
0 收藏
分享
加载中
更多评论
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部