From fd8c0dfd2cf590b5bded1b23ce222ba53c9cbeb4 Mon Sep 17 00:00:00 2001 From: huliguo <2023611923@qq.com> Date: 星期四, 17 七月 2025 11:46:00 +0800 Subject: [PATCH] 增加oss --- ruoyi-common/src/main/java/com/ruoyi/common/utils/file/OSSUtil.java | 484 +++++++++++++++++++++++++++++++++++++++++++++++++++++ ruoyi-common/pom.xml | 5 2 files changed, 489 insertions(+), 0 deletions(-) diff --git a/ruoyi-common/pom.xml b/ruoyi-common/pom.xml index 12920cc..0e7407f 100644 --- a/ruoyi-common/pom.xml +++ b/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> \ No newline at end of file diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/file/OSSUtil.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/file/OSSUtil.java new file mode 100644 index 0000000..2937312 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/file/OSSUtil.java @@ -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(); + } + + +} \ No newline at end of file -- Gitblit v1.7.1