初始化阿里云oss

This commit is contained in:
wr
2026-01-12 14:47:28 +08:00
commit 9b85c51b51
4 changed files with 411 additions and 0 deletions

65
pom.xml Normal file
View File

@@ -0,0 +1,65 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.njcn</groupId>
<artifactId>aliyun-oss-springboot-starter</artifactId>
<version>1.0.0</version>
<distributionManagement>
<repository>
<id>nexus-releases</id>
<name>Nexus Release Repository</name>
<url>http://192.168.1.22:8001/nexus/content/repositories/releases/</url>
</repository>
<snapshotRepository>
<id>nexus-snapshots</id>
<name>Nexus Snapshot Repository</name>
<url>http://192.168.1.22:8001/nexus/content/repositories/snapshots/</url>
</snapshotRepository>
</distributionManagement>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<progressbar.version>0.5.3</progressbar.version>
<okhttp.version>4.8.1</okhttp.version>
<minio.version>8.2.1</minio.version>
</properties>
<description>灿能阿里云oss组件提取的starter模块</description>
<packaging>jar</packaging>
<!-- 依赖配置 -->
<dependencies>
<dependency>
<groupId>com.njcn</groupId>
<artifactId>common-core</artifactId>
<version>1.0.0</version>
<scope>compile</scope>
</dependency>
<!-- 阿里云OSS SDK核心依赖 -->
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>3.18.0</version>
</dependency>
<!-- 日志依赖 -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.36</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
<version>2.3.12.RELEASE</version>
<scope>compile</scope>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,42 @@
package com.njcn.ali.oss.config;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.StringUtils;
/**
* OSS配置类存储连接所需的核心参数
* @author web2023
*/
@Configuration
@ConfigurationProperties(
prefix = "aliyun.io"
)
@Data
public class AliYunOssConfig {
private String endpoint;
private String accessKey;
private String secretKey;
private String bucket;
@Bean(destroyMethod = "shutdown")
public OSS getAliYunClient() {
// 1. 校验配置避免因配置为空导致Bean创建失败
if (!StringUtils.hasText(endpoint) || !StringUtils.hasText(accessKey) || !StringUtils.hasText(secretKey)) {
throw new IllegalArgumentException("OSS配置缺失endpoint/accessKey/secretKey不能为空");
}
return new OSSClientBuilder().build(
this.getEndpoint(),
this.getAccessKey(),
this.getSecretKey()
);
}
}

View File

@@ -0,0 +1,299 @@
package com.njcn.ali.oss.util;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.ObjUtil;
import com.aliyun.oss.OSS;
import com.aliyun.oss.common.comm.ResponseMessage;
import com.aliyun.oss.model.*;
import com.njcn.ali.oss.config.AliYunOssConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import java.io.*;
import java.net.URL;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
/**
* 阿里云OSS核心工具类
* 封装常用操作上传、下载、删除、查询、生成临时访问URL等
*
* @author web2023
*/
@Component
public class AliYunOssUtils {
private static final Logger logger = LoggerFactory.getLogger(AliYunOssUtils.class);
@Resource
private OSS ossClient;
@Resource
private AliYunOssConfig ossConfig;
/**
* 上传文件(字节数组)
*
* @param objectName 文件在OSS中的路径/名称
* @param content 文件字节数组
* @return 上传结果ETag
*/
public String uploadFile(String objectName, byte[] content) {
return uploadFile(objectName, new ByteArrayInputStream(content));
}
/**
* 上传文件InputStream
*
* @param objectName 文件在OSS中的路径/名称
* @param inputStream 文件输入流
* @return 上传结果ETag
*/
public String uploadFile(String objectName, InputStream inputStream) {
try {
PutObjectResult result = ossClient.putObject(
ossConfig.getBucket(),
objectName,
inputStream
);
return result.getETag();
} catch (Exception e) {
logger.error("文件{}上传失败", objectName, e);
throw new RuntimeException("文件上传失败:" + objectName, e);
}
}
/**
* 上传文件MultipartFile
*
* @param objectName 文件在OSS中的路径/名称
* @param multipartFile 文件输入流
* @return 上传结果ETag
*/
public String uploadFile(String objectName, MultipartFile multipartFile) {
try {
PutObjectResult result = ossClient.putObject(
ossConfig.getBucket(),
objectName,
multipartFile.getInputStream()
);
return result.getETag();
} catch (Exception e) {
logger.error("文件{}上传失败", objectName, e);
throw new RuntimeException("文件上传失败:" + objectName, e);
}
}
/**
* 上传本地文件
*
* @param objectName 文件在OSS中的路径/名称
* @param localFilePath 本地文件路径
* @return 上传结果ETag
*/
public String uploadLocalFile(String objectName, String localFilePath) {
File file = new File(localFilePath);
if (!file.exists()) {
throw new RuntimeException("本地文件不存在:" + localFilePath);
}
try {
PutObjectResult result = ossClient.putObject(
ossConfig.getBucket(),
objectName,
file
);
return result.getETag();
} catch (Exception e) {
logger.error("本地文件{}上传失败", localFilePath, e);
throw new RuntimeException("本地文件上传失败:" + localFilePath, e);
}
}
/**
* 下载文件到本地
*
* @param objectName OSS中的文件名称/路径
* @param localFilePath 本地保存路径
*/
public void downloadFile(String objectName, String localFilePath) {
try {
ossClient.getObject(
new GetObjectRequest(ossConfig.getBucket(), objectName),
new File(localFilePath)
);
} catch (Exception e) {
logger.error("文件{}下载失败", objectName, e);
throw new RuntimeException("文件下载失败:" + objectName, e);
}
}
/**
* 下载文件为字节流
*
* @param objectName OSS中的文件名称/路径
* @return 文件字节流
*/
public InputStream downloadStream(String objectName) {
try (OSSObject ossObject = ossClient.getObject(ossConfig.getBucket(), objectName);
InputStream inputStream = ossObject.getObjectContent()) {
return inputStream;
} catch (Exception e) {
logger.error("文件{}下载为字节数组失败", objectName, e);
throw new RuntimeException("文件下载为字节数组失败:" + objectName, e);
}
}
/**
* 下载文件为字节数组
*
* @param objectName OSS中的文件名称/路径
* @return 文件字节数组
*/
public byte[] downloadFileToBytes(String objectName) {
try (OSSObject ossObject = ossClient.getObject(ossConfig.getBucket(), objectName);
InputStream inputStream = ossObject.getObjectContent();
ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
byte[] buffer = new byte[1024];
int len;
while ((len = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, len);
}
return outputStream.toByteArray();
} catch (Exception e) {
logger.error("文件{}下载为字节数组失败", objectName, e);
throw new RuntimeException("文件下载为字节数组失败:" + objectName, e);
}
}
/**
* 下载文件为文件
*
* @param folderPath OSS中的文件名称/路径
* @return 文件
*/
public File getLastFile(String folderPath) {
try {
// 列出文件夹下所有文件(分页处理,避免文件过多)
ObjectListing objectListing = ossClient.listObjects(ossConfig.getBucket(), folderPath);
List<OSSObjectSummary> objectSummaries = objectListing.getObjectSummaries();
// 处理空文件夹
if (objectSummaries.isEmpty()) {
logger.warn("OSS文件夹 {} 下无文件", folderPath);
return null;
}
// 按最后修改时间降序排序,取第一个(最新)
String latestFileName = objectSummaries.stream()
.filter(summary -> !summary.getKey().equals(folderPath))
.max(Comparator.comparing(OSSObjectSummary::getLastModified))
.map(OSSObjectSummary::getKey)
.orElse(null);
if (ObjUtil.isNull(latestFileName)) {
throw new RuntimeException("OSS文件夹 " + folderPath + " 下无可用文件");
}
File file = File.createTempFile(latestFileName.split(".xlsx")[0], ".xlsx");
InputStream inputStream = ossClient.getObject(ossConfig.getBucket(), latestFileName).getObjectContent();
FileUtil.writeFromStream(inputStream, file);
inputStream.close();
return file;
} catch (Exception e) {
logger.error("查找OSS文件夹 {} 最新文件失败", folderPath, e);
throw new RuntimeException("查找最新文件失败:" + folderPath, e);
}finally {
}
}
public static void main(String[] args) {
String latestFileName="latestFileNam.xlsx";
String s = latestFileName.split(".xlsx")[0];
System.out.println();
}
/**
* 删除单个文件
*
* @param objectName OSS中的文件名称/路径
*/
public void deleteFile(String objectName) {
try {
VoidResult voidResult = ossClient.deleteObject(ossConfig.getBucket(), objectName);
ResponseMessage response = voidResult.getResponse();
System.out.println(response);
} catch (Exception e) {
logger.error("文件{}删除失败", objectName, e);
throw new RuntimeException("文件删除失败:" + objectName, e);
}
}
/**
* 批量删除文件
*
* @param objectNames 文件名称列表
*/
public void deleteFiles(List<String> objectNames) {
try {
// 静默删除,不返回删除结果
DeleteObjectsRequest request = new DeleteObjectsRequest(ossConfig.getBucket())
.withKeys(objectNames);
ossClient.deleteObjects(request);
} catch (Exception e) {
logger.error("批量删除文件失败", e);
throw new RuntimeException("批量删除文件失败", e);
}
}
/**
* 判断文件是否存在
*
* @param objectName OSS中的文件名称/路径
* @return true-存在false-不存在
*/
public boolean isFileExist(String objectName) {
try {
boolean exists = ossClient.doesObjectExist(ossConfig.getBucket(), objectName);
return exists;
} catch (Exception e) {
logger.error("判断文件{}是否存在失败", objectName, e);
throw new RuntimeException("判断文件是否存在失败:" + objectName, e);
}
}
/**
* 生成文件临时访问URL
*
* @param objectName OSS中的文件名称/路径
* @param expireSeconds 过期时间(秒)
* @return 临时访问URL
*/
public String generatePresignedUrl(String objectName, int expireSeconds) {
try {
Date expiration = new Date(System.currentTimeMillis() + expireSeconds * 1000L);
URL url = ossClient.generatePresignedUrl(
ossConfig.getBucket(),
objectName,
expiration
);
String urlStr = url.toString();
logger.info("文件{}生成临时访问URL成功过期时间{}秒", objectName, expireSeconds);
return urlStr;
} catch (Exception e) {
logger.error("生成文件{}临时访问URL失败", objectName, e);
throw new RuntimeException("生成临时访问URL失败" + objectName, e);
}
}
/**
* 关闭OSS客户端
*/
public void close() {
if (ossClient != null) {
ossClient.shutdown();
logger.info("OSS客户端已关闭");
}
}
}

View File

@@ -0,0 +1,5 @@
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.njcn.ali.oss.config.AliYunOssConfig,\
com.njcn.ali.oss.util.AliYunOssUtils