封裝工具類:上傳/下載下傳檔案+删除檔案+擷取url+擷取流(可預覽PDF或圖檔)
安裝
這裡選擇版本為:<aliyun-oss.version>3.10.2</aliyun-oss.version>
<!-- 阿裡雲OSS -->
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>${aliyun-oss.version}</version>
</dependency>
配置
server:
port: 8081
aliyun:
oss:
# API鑒權
accessKeyId: xxx # 通路身份驗證中用到使用者辨別
accessKeySecret: xxx # 使用者用于加密簽名字元串和oss用來驗證簽名字元串的密鑰
# oss通路域名(内網)
endpoint: oss-cn-shanghai-internal.aliyuncs.com
bucketName: xxx-bucket # oss的存儲空間
policyExpire: 300 # url有效期(S)
maxSize: 10 # 上傳檔案大小(M)
代碼
配置讀取
import lombok.Data;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
/**
* 阿裡雲OSS配置
*/
@Data
@Configuration
@ConfigurationProperties(prefix = "aliyun.oss")
public class AliyunOssConfig implements InitializingBean {
/**
* 阿裡雲 oss 站點
*/
private String endpoint;
/**
* 阿裡雲 oss 公鑰
*/
private String accessKeyId;
/**
* 阿裡雲 oss 私鑰
*/
private String accessKeySecret;
/**
* 阿裡雲 oss 檔案根目錄
*/
private String bucketName;
/**
* url有效期(S)
*/
private Long policyExpire;
/**
* 上傳檔案大小(M)
*/
private Long maxSize;
// 友善直接擷取
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;
public static Long JAVA_POLICY_EXPIRE;
public static Long JAVA_MAX_SIZE;
@Override
public void afterPropertiesSet() {
JAVA_END_POINT = endpoint;
JAVA_ACCESS_KEY_ID = accessKeyId;
JAVA_ACCESS_KEY_SECRET = accessKeySecret;
JAVA_BUCKET_NAME = bucketName;
JAVA_POLICY_EXPIRE = policyExpire;
JAVA_MAX_SIZE = maxSize;
}
}
定義阿裡雲上傳結果響應參數
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* 阿裡雲OSS上傳結果集
*
* @author jason
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class AliyunOssResult {
/**
* 上傳是否成功
*/
private boolean success;
/**
* 上傳的檔案名(如果使用自定義檔案路徑,會傳回完整的路徑+檔案名,例:cf/abc.png)
*/
private String fileName;
/**
* 上傳成功的傳回url(帶過期時間)
*/
private String url;
/**
* 提示資訊
*/
private String msg;
}
工具類
import cn.hutool.core.io.FastByteArrayOutputStream;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.StrUtil;
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.example.aliyunossdemo.oss.AliyunOssConfig;
import com.example.aliyunossdemo.oss.AliyunOssResult;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
* 阿裡雲OSS工具類
*
* @author jason
*/
public class AliyunOSSUtil {
/**
* oss 工具用戶端
*/
private static OSSClient ossClient = null;
/**
* 單例模式
* 初始化 oss 用戶端
*/
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;
}
/**
* 上傳檔案-自定義路徑
*
* @param file 上傳檔案
* @param fileName 上傳至OSS的檔案完整路徑,例:cf/abc.png
* 上傳至根目錄,例:abc.png
* @return
*/
public static AliyunOssResult uploadFile(File file, String fileName) {
// 檔案流
InputStream inputStream = FileUtil.getInputStream(file);
// 擷取檔案類型
String fileType = FileUtil.getType(file);
// 上傳檔案
return uploadInputStream(inputStream, fileType, fileName);
}
/**
* 上傳檔案-自定義路徑
*
* @param file 上傳檔案
* @param fileName 上傳至OSS的檔案完整路徑,例:cf/abc.png
* 上傳至根目錄,例:abc.png
* @return
*/
public static AliyunOssResult uploadFile(MultipartFile file, String fileName) {
// 檔案流
InputStream inputStream;
try {
inputStream = file.getInputStream();
} catch (IOException e) {
e.printStackTrace();
return new AliyunOssResult(false, null, null, e.getMessage());
}
// 擷取檔案類型
String fileType = file.getContentType();
// 上傳檔案
return uploadInputStream(inputStream, fileType, fileName);
}
/**
* 上傳檔案-自定義路徑
*
* @param inputStream 上傳檔案流
* @param fileType 檔案類型,例:png
* @param fileName 上傳至OSS的檔案完整路徑,例:cf/abc.png
* 上傳至根目錄,例:abc.png
* @return
*/
public static AliyunOssResult uploadInputStream(InputStream inputStream, String fileType, String fileName) {
if (inputStream == null) {
return new AliyunOssResult(false, null, null, "檔案不能為空");
}
if (StrUtil.isBlank(fileName)) {
return new AliyunOssResult(false, null, null, "檔案名不能為空");
}
// 上傳檔案最大值 MB->bytes
long maxSize = AliyunOssConfig.JAVA_MAX_SIZE * 1024 * 1024;
// 本次上傳檔案的大小
long fileSize = 0;
try {
fileSize = inputStream.available();
} catch (IOException e) {
e.printStackTrace();
}
if (fileSize <= 0 || fileSize > maxSize) {
return new AliyunOssResult(false, null, null, "檔案超過最大限制");
}
// 上傳檔案
return putFile(inputStream, fileType, fileName);
}
/**
* 上傳檔案
*
* @param input
* @param fileType
* @param fileName
* @return
*/
private static AliyunOssResult putFile(InputStream input, String fileType, String fileName) {
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);
//擷取上傳成功的檔案位址
return new AliyunOssResult(true, fileName, getOssUrl(fileName), "上傳成功");
} catch (OSSException | ClientException e) {
e.printStackTrace();
return new AliyunOssResult(false, fileName, null, e.getMessage());
}
}
/**
* 根據檔案名生成檔案的通路位址(帶過期時間)
*
* @param fileName
* @return
*/
public static String getOssUrl(String fileName) {
ossClient = initOSS();
// 生成過期時間
long expireEndTime = System.currentTimeMillis() + AliyunOssConfig.JAVA_POLICY_EXPIRE * 1000;
Date expiration = new Date(expireEndTime);// 生成URL
GeneratePresignedUrlRequest generatePresignedUrlRequest = new GeneratePresignedUrlRequest(AliyunOssConfig.JAVA_BUCKET_NAME, fileName);
generatePresignedUrlRequest.setExpiration(expiration);
URL url = ossClient.generatePresignedUrl(generatePresignedUrlRequest);
return url.toString();
}
/**
* 通過檔案名下載下傳檔案
*
* @param fileName 要下載下傳的檔案名(OSS伺服器上的)
* 例如:4DB049D0604047989183CB68D76E969D.jpg
* @param localFileName 本地要建立的檔案名(下載下傳到本地的)
* 例如:C:\Users\Administrator\Desktop\test.jpg
*/
public static void downloadFile(String fileName, String localFileName) {
ossClient = initOSS();
// 下載下傳OSS檔案到指定目錄。如果指定的本地檔案存在會覆寫,不存在則建立。
ossClient.getObject(new GetObjectRequest(AliyunOssConfig.JAVA_BUCKET_NAME, fileName), new File(localFileName));
}
/**
* 通過檔案名擷取檔案流
*
* @param fileName 要下載下傳的檔案名(OSS伺服器上的)
* 例如:4DB049D0604047989183CB68D76E969D.jpg
*/
public static InputStream getInputStream(String fileName) {
ossClient = initOSS();
// 下載下傳OSS檔案到本地檔案。如果指定的本地檔案存在會覆寫,不存在則建立。
return ossClient.getObject(new GetObjectRequest(AliyunOssConfig.JAVA_BUCKET_NAME, fileName)).getObjectContent();
}
/**
* 通過檔案名擷取byte[]
*
* @param fileName 要下載下傳的檔案名(OSS伺服器上的)
* 例如:4DB049D0604047989183CB68D76E969D.jpg
*/
public static byte[] getBytes(String fileName) {
InputStream inputStream = getInputStream(fileName);
FastByteArrayOutputStream fastByteArrayOutputStream = IoUtil.read(inputStream);
return fastByteArrayOutputStream.toByteArray();
}
/**
* 根據檔案名删除檔案
*
* @param fileName 需要删除的檔案名
* @return boolean 是否删除成功
* 例如:4DB049D0604047989183CB68D76E969D.jpg
*/
public static boolean deleteFile(String fileName) {
ossClient = initOSS();
try {
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;
}
return true;
}
/**
* 列舉所有的檔案url
*/
public static List<String> urlList() {
ossClient = initOSS();
List<String> list = new ArrayList<>();
// 構造ListObjectsRequest請求
ListObjectsRequest listObjectsRequest = new ListObjectsRequest(AliyunOssConfig.JAVA_BUCKET_NAME);
// 列出檔案
ObjectListing listing = ossClient.listObjects(listObjectsRequest);
// 周遊所有檔案
for (OSSObjectSummary objectSummary : listing.getObjectSummaries()) {
// 把key全部轉化成可以通路的url
String url = getOssUrl(objectSummary.getKey());
list.add(url);
}
return list;
}
}
測試
import cn.hutool.core.codec.Base64;
import cn.hutool.core.io.FileUtil;
import com.example.aliyunossdemo.oss.AliyunOssResult;
import com.example.aliyunossdemo.util.AliyunOSSUtil;
import org.springframework.core.io.InputStreamResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.InputStream;
import java.util.List;
/**
* 阿裡雲OSS測試接口
*
* @author jason
*/
@RestController
@RequestMapping("/oss")
public class OssTestController {
/**
* 測試-上傳
* -自定義檔案
* -自定義OSS存儲路徑
* http://localhost:8081/oss/uploadFile
*/
@GetMapping("/uploadFile")
public AliyunOssResult uploadFile() {
return AliyunOSSUtil.uploadFile(new File("src/main/resources/xxx.png"), "png/重命名.png");
}
/**
* 上傳檔案-指定目錄
*/
@PostMapping("/uploadTest")
public AliyunOssResult uploadTest(MultipartFile file) {
return AliyunOSSUtil.uploadFile(file, "自定義目錄/" + file.getOriginalFilename());
}
/**
* 删除檔案
* http://localhost:8081/oss/deleteFile?fileName=TEST/png/重命名.png
*/
@GetMapping("/deleteFile")
public boolean deleteFile(@RequestParam String fileName) {
return AliyunOSSUtil.deleteFile(fileName);
}
/**
* oss路徑下擷取檔案帶有效期的url,擷取的url可下載下傳
* http://localhost:8081/oss/getOssUrl?fileName=TEST/png/重命名.png
*/
@GetMapping("/getOssUrl")
public String getOssUrl(@RequestParam String fileName) {
return AliyunOSSUtil.getOssUrl(fileName);
}
/**
* 預覽PDF或圖檔
* http://localhost:8081/oss/preview?fileName=TEST/png/重命名.png
*/
@GetMapping("/preview")
public ResponseEntity<InputStreamResource> previewFile(@RequestParam String fileName) {
// 擷取檔案類型
String contentType = FileUtil.extName(fileName);
// 擷取檔案流
InputStream inputStream = AliyunOSSUtil.getInputStream(fileName);
// 預覽
HttpHeaders httpHeaders = new HttpHeaders();
if ("pdf".equalsIgnoreCase(contentType)) {
httpHeaders.add("Content-Type", MediaType.APPLICATION_PDF_VALUE);
} else if ("jpg".equalsIgnoreCase(contentType) || "png".equalsIgnoreCase(contentType) || "jpeg".equalsIgnoreCase(contentType)) {
httpHeaders.add("Content-Type", MediaType.IMAGE_JPEG_VALUE);
}
InputStreamResource inputStreamResource = new InputStreamResource(inputStream);
return new ResponseEntity<>(inputStreamResource, httpHeaders, HttpStatus.OK);
}
/**
* 列舉所有的檔案url
* http://localhost:8081/oss/urlList
*/
@GetMapping("/urlList")
public List<String> urlList() {
return AliyunOSSUtil.urlList();
}
/**
* 圖檔轉base64
* http://localhost:8081/oss/base64
*/
@GetMapping("/base64")
public String base64() {
return Base64.encode(AliyunOSSUtil.getInputStream("png/重命名.png"));
}
/**
* 檔案轉byte[]
* http://localhost:8081/oss/bytes
*/
@GetMapping("/bytes")
public byte[] bytes() {
return AliyunOSSUtil.getBytes("png/重命名.png");
}
}
效果
使用postman上傳一張圖檔
在阿裡雲背景我們可以看到上傳成功的檔案