huliguo
2025-07-17 fd8c0dfd2cf590b5bded1b23ce222ba53c9cbeb4
增加oss
1个文件已添加
1个文件已修改
489 ■■■■■ 已修改文件
ruoyi-common/pom.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/utils/file/OSSUtil.java 484 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/pom.xml
@@ -168,6 +168,11 @@
            <artifactId>easypoi-annotation</artifactId>
            <version>4.4.0</version>
        </dependency>
        <dependency>
            <groupId>com.aliyun.oss</groupId>
            <artifactId>aliyun-sdk-oss</artifactId>
            <version>3.15.1</version>
        </dependency>
    </dependencies>
</project>
ruoyi-common/src/main/java/com/ruoyi/common/utils/file/OSSUtil.java
New file
@@ -0,0 +1,484 @@
package com.ruoyi.common.utils.file;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpMethod;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URL;
import java.net.URLEncoder;
import java.security.SecureRandom;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
@Slf4j
@Component
public class OSSUtil {
    private static final String endpoint = "oss-cn-chengdu.aliyuncs.com";
    private static final String accessKeyId = "LTAI5tHYSpwifc3rqLYJoETo";
    private static final String accessKeySecret = "xrDyQ89h8P0alWW7rrLIW2D2rt7Eig";
    private static final String bucketName = "yizhengcheng";
    private static final String FOLDER = "https://yizhengcheng.oss-cn-chengdu.aliyuncs.com/";
    /**
     * 获取oss
     *
     * @return
     */
    public static OSS getOSSClient() {
        return new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
    }
    /**
     * 上传图片
     *
     * @param url
     * @throws
     */
    public void uploadImg2Oss(String url) throws IOException {
        File fileOnServer = new File(url);
        FileInputStream fin;
        try {
            fin = new FileInputStream(fileOnServer);
            String[] split = url.split("/");
            this.uploadFile2OSS(fin, split[split.length - 1]);
        } catch (FileNotFoundException e) {
            throw new IOException("图片上传失败");
        }
    }
    public String uploadImg2Oss(MultipartFile file) throws IOException {
        if (file.getSize() > 5 * 1024 * 1024) {
            throw new IOException("上传图片大小不能超过5M!");
        }
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        // 获取文件名
        String originalFilename = file.getOriginalFilename();
        // 获取文件后缀名
        String suffixName  = originalFilename.substring(originalFilename.lastIndexOf(".")).toLowerCase();
        // 最后上传生成的文件名
        String finalFileName = System.currentTimeMillis() + "" + new SecureRandom().nextInt(0x0400) + suffixName;
        // oss中的文件夹名
        String objectName = sdf.format(new Date()) + "/" + finalFileName;
//        name = DateUtils.dateStr(new Date(), "yyyy/MM/dd") + "/" + System.currentTimeMillis() + substring;
        try {
            InputStream inputStream = file.getInputStream();
            this.uploadFile2OSS(inputStream, objectName);
            return objectName;
        } catch (Exception e) {
            e.printStackTrace();
            throw new IOException("图片上传失败");
        }
    }
    /**
     * 获得图片路径
     *
     * @param fileUrl
     * @return
     */
    public String getImgUrl(String fileUrl) {
        System.out.println(fileUrl);
        if (!StringUtils.isEmpty(fileUrl)) {
//            String[] split = fileUrl.split("/");
            return this.getUrl(this.FOLDER + fileUrl);
        }
        return "";
    }
    /**
     * 上传到OSS服务器 如果同名文件会覆盖服务器上的
     *
     * @param instream 文件流
     * @param fileName 文件名称 包括后缀名
     * @return 出错返回"" ,唯一MD5数字签名
     */
    public String uploadFile2OSS(InputStream instream, String fileName) {
        String ret = "";
        try {
            OSS ossClient = getOSSClient();
            // 创建上传Object的Metadata
            ObjectMetadata objectMetadata = new ObjectMetadata();
            objectMetadata.setContentLength(instream.available());
            objectMetadata.setCacheControl("no-cache");
            objectMetadata.setContentType(getContentType(fileName.substring(fileName.lastIndexOf("."))));
            objectMetadata.setHeader("Pragma", "no-cache");
//            objectMetadata.setContentDisposition("inline;filename=" + fileName);
            // 上传文件
            PutObjectResult putResult = ossClient.putObject(bucketName, FOLDER + fileName, instream, objectMetadata);
            ret = putResult.getETag();
        } catch (IOException e) {
            log.error(e.getMessage(), e);
        } finally {
            try {
                if (instream != null) {
                    instream.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return ret;
    }
    /**
     * 通过文件名判断并获取OSS服务文件上传时文件的contentType
     *
     * @param filenameExtension 文件名
     * @return 文件的contentType
     */
    public static final String getContentType(String filenameExtension) {
        if (filenameExtension.equalsIgnoreCase(".bmp")) {
            return "application/x-bmp";
        }
        if (filenameExtension.equalsIgnoreCase(".gif")) {
            return "image/gif";
        }
        if (filenameExtension.equalsIgnoreCase(".jpeg") ||
                filenameExtension.equalsIgnoreCase(".jpg") ||
                filenameExtension.equalsIgnoreCase(".png")) {
            return "image/jpg";
        }
        if (filenameExtension.equalsIgnoreCase(".html")) {
            return "text/html";
        }
        if (filenameExtension.equalsIgnoreCase(".txt")) {
            return "text/plain";
        }
        if (filenameExtension.equalsIgnoreCase(".vsd")) {
            return "application/vnd.visio";
        }
        if (filenameExtension.equalsIgnoreCase(".pptx") ||
                filenameExtension.equalsIgnoreCase(".ppt")) {
            return "application/vnd.ms-powerpoint";
        }
        if (filenameExtension.equalsIgnoreCase(".docx") ||
                filenameExtension.equalsIgnoreCase(".doc")) {
            return "application/msword";
        }
        if (filenameExtension.equalsIgnoreCase(".xla") ||
                filenameExtension.equalsIgnoreCase(".xlc") ||
                filenameExtension.equalsIgnoreCase(".xlm") ||
                filenameExtension.equalsIgnoreCase(".xls") ||
                filenameExtension.equalsIgnoreCase(".xlt") ||
                filenameExtension.equalsIgnoreCase(".xlw")) {
            return "application/vnd.ms-excel";
        }
        if (filenameExtension.equalsIgnoreCase(".xlsx")) {
            return "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
        }
        if (filenameExtension.equalsIgnoreCase(".xml")) {
            return "text/xml";
        }
        if (filenameExtension.equalsIgnoreCase(".pdf")) {
            return "application/pdf";
        }
        if (filenameExtension.equalsIgnoreCase(".zip")) {
            return "application/zip";
        }
        if (filenameExtension.equalsIgnoreCase(".tar")) {
            return "application/x-tar";
        }
        if (filenameExtension.equalsIgnoreCase(".avi")) {
            return "video/avi";
        }
        if (filenameExtension.equalsIgnoreCase(".mp4")) {
            return "video/mpeg4";
        }
        if (filenameExtension.equalsIgnoreCase(".mp3")) {
            return "audio/mp3";
        }
        if (filenameExtension.equalsIgnoreCase(".mp2")) {
            return "audio/mp2";
        }
        // 默认下载
//        return "application/octet-stream";
        return "image/jpg";
    }
    /**
     * 获得url链接
     *
     * @param key
     * @return
     */
    public String getUrl(String key) {
        // 设置URL过期时间为10年 3600l* 1000*24*365*10
        OSS ossClient = getOSSClient();
        Date expiration = new Date(System.currentTimeMillis() + 3600L * 1000 * 24 * 365 * 10);
        // 生成URL
        URL url = ossClient.generatePresignedUrl(bucketName, key, expiration);
        System.out.println("url: "+url);
        if (url != null) {
            String host = "https://" + url.getHost() + url.getPath();
            System.out.println("host: "+host);
            // http://wxcall-xiaobanben.oss-cn-shenzhen.aliyuncs.com/image/20220129/1643469496754508.jpg
            return host;
        }
        return "";
    }
    /**
     * 获取文件夹
     *
     * @param fileName
     * @return
     */
    public List<String> fileFolder(String fileName) {
        // 创建OSSClient实例。
        OSS ossClient = getOSSClient();
        // 构造ListObjectsRequest请求。
        ListObjectsRequest listObjectsRequest = new ListObjectsRequest(bucketName);
        // 设置正斜线(/)为文件夹的分隔符。
        listObjectsRequest.setDelimiter("/");
        // 设置prefix参数来获取fun目录下的所有文件。
        if (!StringUtils.isEmpty(fileName)) {
            listObjectsRequest.setPrefix(fileName + "/");
        }
        // 列出文件
        ObjectListing listing = ossClient.listObjects(listObjectsRequest);
        // 遍历所有commonPrefix
        List<String> list = new ArrayList<>();
        for (String commonPrefix : listing.getCommonPrefixes()) {
            String newCommonPrefix = commonPrefix.substring(0, commonPrefix.length() - 1);
            String[] s = newCommonPrefix.split("/");
            if (!StringUtils.isEmpty(fileName)) {
                list.add(s[s.length - 1]);
            } else {
                list.add(s[0]);
            }
        }
        // 关闭OSSClient
        ossClient.shutdown();
        return list;
    }
    /**
     * 列举文件下所有的文件url信息
     */
    public ObjectListing listFile2(String fileHost, String nextMarker) {
        // 创建OSSClient实例。
        OSS ossClient = getOSSClient();
        // 构造ListObjectsRequest请求。
        ListObjectsRequest listObjectsRequest = new ListObjectsRequest(bucketName);
        // 设置正斜线(/)为文件夹的分隔符。
        listObjectsRequest.setDelimiter("/");
        // 列出fun目录下的所有文件和文件夹。
        listObjectsRequest.setPrefix(fileHost + "/");
        ObjectListing listing = ossClient.listObjects(listObjectsRequest);
        // 遍历所有文件。
        System.out.println("Objects:");
        // objectSummaries的列表中给出的是fun目录下的文件。
        for (OSSObjectSummary objectSummary : listing.getObjectSummaries()) {
            System.out.println(objectSummary.getKey());
        }
        // 遍历所有commonPrefix。
        System.out.println("\nCommonPrefixes:");
        // commonPrefixs列表中显示的是fun目录下的所有子文件夹。由于fun/movie/001.avi和fun/movie/007.avi属于fun文件夹下的movie目录,因此这两个文件未在列表中。
        for (String commonPrefix : listing.getCommonPrefixes()) {
            System.out.println(commonPrefix);
        }
        // 关闭OSSClient。
        ossClient.shutdown();
        return listing;
    }
    /**
     * 列举文件下所有的文件url信息
     */
    public List<String> listFile(String fileHost, String nextMarker) {
        // 创建OSSClient实例。
        OSS ossClient = getOSSClient();
        // 构造ListObjectsRequest请求
        ListObjectsRequest listObjectsRequest = new ListObjectsRequest(bucketName);
        // 设置prefix参数来获取fun目录下的所有文件。
        listObjectsRequest.setPrefix(fileHost + "/");
        listObjectsRequest.setMarker(nextMarker);
        // 列出文件。
        ObjectListing listing = ossClient.listObjects(listObjectsRequest);
        // 遍历所有文件。
        List<String> list = new ArrayList<>();
        for (int i = 0; i < listing.getObjectSummaries().size(); i++) {
            String FILE_URL = "http://" + bucketName + "." + endpoint + "/" + listing.getObjectSummaries().get(i).getKey();
            list.add(FILE_URL);
        }
        // 关闭OSSClient。
        ossClient.shutdown();
//        ObjectListing objectListing = null;
//        int total = 0;
//        HashMap<Integer, String> markerMap = new HashMap<>();
//        try {
//            ObjectListing objectListing2 = null;
//            do {
//                String nextMarker2 = objectListing2 != null ? objectListing2.getNextMarker() : null;
//                ListObjectsRequest listObjectsRequest2 = new ListObjectsRequest(bucketName).withMarker(nextMarker2).withMaxKeys(100);
//                listObjectsRequest2.setPrefix(fileHost + "/");
//                objectListing2 = ossClient.listObjects(listObjectsRequest2);
//                total += (objectListing2 != null && objectListing2.getObjectSummaries() != null ? objectListing2.getObjectSummaries().size() : 0);
//                markerMap.put(markerMap.size() + 1, nextMarker2);
//            } while (objectListing2 != null && !StringUtils.isEmpty(objectListing2.getNextMarker()));
//
//            ListObjectsRequest listObjectsRequest = new ListObjectsRequest(bucketName).withMarker(nextMarker).withMaxKeys(100);
//
//            listObjectsRequest.setPrefix(fileHost + "/");
//
//            objectListing = ossClient.listObjects(listObjectsRequest);
//            for (int i = 0; i < objectListing.getObjectSummaries().size(); i++) {
//                String FILE_URL = "https://" + bucketName + "." + endpoint + "/" + objectListing.getObjectSummaries().get(i).getKey();
//                list.add(FILE_URL);
//            }
//
//        } catch (Exception e) {
//
//        } finally {
//            // 关闭client
//            ossClient.shutdown();
//        }
        return list;
    }
    /**
     * 删除文件
     * objectName key 地址
     *
     * @param filePath
     */
    public Boolean delFile(String filePath) {
        // 创建OSSClient实例。
        OSS ossClient = getOSSClient();
        // 删除Object.
        boolean exist = ossClient.doesObjectExist(bucketName, filePath);
        if (!exist) {
            return false;
        }
        ossClient.deleteObject(bucketName, filePath);
        ossClient.shutdown();
        return true;
    }
    /**
     * 批量删除
     *
     * @param keys
     */
    public Boolean delFileList(List<String> keys) {
        // 创建OSSClient实例。
        OSS ossClient = getOSSClient();
        try {
            // 删除文件。
            DeleteObjectsResult deleteObjectsResult = ossClient.deleteObjects(new DeleteObjectsRequest(bucketName).withKeys(keys));
            List<String> deletedObjects = deleteObjectsResult.getDeletedObjects();
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        } finally {
            ossClient.shutdown();
        }
        return true;
    }
    /**
     * 创建文件夹
     *
     * @param folder
     * @return
     */
    public String createFolder(String folder) {
        // 创建OSSClient实例。
        OSS ossClient = getOSSClient();
        // 文件夹名
        final String keySuffixWithSlash = folder;
        // 判断文件夹是否存在,不存在则创建
        if (!ossClient.doesObjectExist(bucketName, keySuffixWithSlash)) {
            // 创建文件夹
            ossClient.putObject(bucketName, keySuffixWithSlash, new ByteArrayInputStream(new byte[0]));
            // 得到文件夹名
            OSSObject object = ossClient.getObject(bucketName, keySuffixWithSlash);
            String fileDir = object.getKey();
            ossClient.shutdown();
            return fileDir;
        }
        return keySuffixWithSlash;
    }
    /**
     * 通过文件名下载文件
     *
     * @param objectName    要下载的文件名
     * @param localFileName 本地要创建的文件名
     */
    public void downloadFile(HttpServletResponse response, String objectName, String localFileName) throws Exception {
        // 创建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();
        }
    }
    public String onlineSee(String key) {
        // 创建OSSClient实例。
        OSS ossClient = getOSSClient();
        // 设置URL过期时间为1小时
        Date expiration = new Date(new Date().getTime() + 3600 * 1000);
        // 临时地址
        URL url = ossClient.generatePresignedUrl(bucketName, key, expiration);
        // 关闭OSSClient。
        ossClient.shutdown();
        return url.toString();
    }
}