天天看點

SpringBoot+阿裡雲OSS

封裝工具類:上傳/下載下傳檔案+删除檔案+擷取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上傳一張圖檔

SpringBoot+阿裡雲OSS

在阿裡雲背景我們可以看到上傳成功的檔案

SpringBoot+阿裡雲OSS

源碼

點選下載下傳

繼續閱讀