0-前言
項目中,檔案服務必不可少,常用的有各雲服務商的OSS服務(如阿裡雲OSS,騰訊雲OSS,七牛雲)、自建(fastDFS、minio);
推薦:如果用雲服務的話,阿裡雲OSS很友善,如果自建的話,minio無疑是首選;
這裡我們來簡單介紹阿裡雲OSS的使用,minio我們後面介紹;
1-實作
1-0、開通OSS,并擷取到相關配置參數供程式使用
首先開通阿裡雲OSS,建立bucket、建立AccessKey,幾分鐘就搞定了,不會的具體百度下;
1-1、添加依賴
<!-- 1、內建阿裡雲OSS -->
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>3.6.0</version>
</dependency>
1-2、添加配置
# 阿裡雲存儲參數配置
aliyun:
oss:
endpoint: oss-cn-beijing.aliyuncs.com
accessKeyId: XXX
accessKeySecret: xxx
bucketName: ansonfile
1-3、添加工具類(裡面細節可以自己相應修改完善)
package com.example.oss.utils;
import com.aliyun.oss.OSSClient;
import com.aliyun.oss.model.ObjectMetadata;
import com.aliyun.oss.model.PutObjectResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.*;
/**
* 描述: 阿裡雲OSS工具類
* 版權: Copyright (c) 2020
* 公司: XXX
* 作者: yanghj
* 版本: 4.0
* 建立日期: 2020/9/16 11:38
*/
@Component
public class OssUtil
{
//------------------變量----------
protected static final Logger log = LoggerFactory.getLogger(OssUtil.class);
@Value("${aliyun.oss.endpoint}")
private String endpoint;
@Value("${aliyun.oss.accessKeyId}")
private String accessKeyId;
@Value("${aliyun.oss.accessKeySecret}")
private String accessKeySecret;
@Value("${aliyun.oss.bucketName}")
private String bucketName;
//檔案存儲目錄
private String filedir = "clouFile/";
//-----------------對外功能----------------
/**
* 1、單個檔案上傳
* @param file
* @return 傳回完整URL位址
*/
public String uploadFile(MultipartFile file)
{
String fileUrl = uploadImg2Oss(file);
String str = getFileUrl(fileUrl);
return str.trim();
}
/**
* 1、單個檔案上傳(指定檔案名(帶字尾))
* @param file
* @return 傳回完整URL位址
*/
public String uploadFile(MultipartFile file,String fileName)
{
try
{
InputStream inputStream = file.getInputStream();
this.uploadFile2OSS(inputStream, fileName);
return fileName;
}
catch (Exception e)
{
return "上傳失敗";
}
}
/**
* 2、多檔案上傳
* @param fileList
* @return 傳回完整URL,逗号分隔
*/
public String uploadFile(List<MultipartFile> fileList) {
String fileUrl = "";
String str = "";
String photoUrl = "";
for(int i = 0;i< fileList.size();i++){
fileUrl = uploadImg2Oss(fileList.get(i));
str = getFileUrl(fileUrl);
if(i == 0){
photoUrl = str;
}else {
photoUrl += "," + str;
}
}
return photoUrl.trim();
}
/**
* 3、通過檔案名擷取文完整件路徑
* @param fileUrl
* @return 完整URL路徑
*/
public String getFileUrl(String fileUrl)
{
if (fileUrl !=null && fileUrl.length()>0) {
String[] split = fileUrl.split("/");
String url = this.getUrl(this.filedir + split[split.length - 1]);
return url;
}
return null;
}
//-----------内部輔助功能------------------------
//擷取去掉參數的完整路徑
private String getShortUrl(String url)
{
String[] imgUrls = url.split("\\?");
return imgUrls[0].trim();
}
// 獲得url連結
private String getUrl(String key) {
// 設定URL過期時間為20年 3600l* 1000*24*365*20
Date expiration = new Date(new Date().getTime() + 3600l * 1000 * 24 * 365 * 20);
// 生成URL
OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
URL url = ossClient.generatePresignedUrl(bucketName, key, expiration);
if (url != null)
{
return getShortUrl(url.toString());
}
return null;
}
// 上傳檔案
private String uploadImg2Oss(MultipartFile file)
{
//1、限制最大檔案為20M
if (file.getSize() > 1024 * 1024 *20)
{
return "圖檔太大";
}
//2、重命名檔案
// String originalFilename = file.getOriginalFilename();
// String substring = originalFilename.substring(originalFilename.lastIndexOf(".")).toLowerCase();
// Random random = new Random();
// String name = random.nextInt(10000) + System.currentTimeMillis() + substring;
String fileName = file.getOriginalFilename();
String suffix = fileName.substring(fileName.lastIndexOf(".")).toLowerCase(); //檔案字尾
String uuid = UUID.randomUUID().toString();
String name = uuid + suffix;
try
{
InputStream inputStream = file.getInputStream();
this.uploadFile2OSS(inputStream, name);
return name;
}
catch (Exception e)
{
return "上傳失敗";
}
}
// 上傳檔案(指定檔案名)
private String uploadFile2OSS(InputStream instream, String fileName)
{
String ret = "";
try {
//建立上傳Object的Metadata
ObjectMetadata objectMetadata = new ObjectMetadata();
objectMetadata.setContentLength(instream.available());
objectMetadata.setCacheControl("no-cache");
objectMetadata.setHeader("Pragma", "no-cache");
objectMetadata.setContentType(getcontentType(fileName.substring(fileName.lastIndexOf("."))));
objectMetadata.setContentDisposition("inline;filename=" + fileName);
//上傳檔案
OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
PutObjectResult putResult = ossClient.putObject(bucketName, filedir + 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;
}
private static String getcontentType(String FilenameExtension)
{
if (FilenameExtension.equalsIgnoreCase(".bmp")) {
return "image/bmp";
}
if (FilenameExtension.equalsIgnoreCase(".gif")) {
return "image/gif";
}
if (FilenameExtension.equalsIgnoreCase(".jpeg") ||
FilenameExtension.equalsIgnoreCase(".jpg") ||
FilenameExtension.equalsIgnoreCase(".png")) {
return "image/jpeg";
}
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(".xml")) {
return "text/xml";
}
//PDF
if (FilenameExtension.equalsIgnoreCase(".pdf")) {
return "application/pdf";
}
return "image/jpeg";
}
}
1-4、調用
controller:
/**
* 描述: OSS controller
* 版權: Copyright (c) 2020
* 公司: XXX
* 作者: yanghj
* 版本: 4.0
* 建立日期: 2020/9/16 10:33
*/
@RestController
@RequestMapping("oss")
@Api(value = "OSS",tags = "OSS上傳接口")
public class OssController
{
@Autowired
private OssUtil ossUtil; //1、注入OssUtil
@PostMapping("/uploadfile")
@ApiOperation(value = "上傳", notes = "上傳")
public Object fileUpload(@RequestParam MultipartFile file)
{
try
{
String url = ossUtil.uploadFile(file); //2、調用
Map<String, Object> returnbody = new HashMap<>();
Map<String, Object> returnMap = new HashMap<>();
returnMap.put("url", url);
returnbody.put("data",returnMap);
returnbody.put("code","200");
returnbody.put("message","上傳成功");
return returnbody;
}
catch (Exception e)
{
Map<String, Object> returnbody = new HashMap<>();
returnbody.put("data",null);
returnbody.put("code","400");
returnbody.put("message","上傳失敗");
return returnbody;
}
}
}
運作結果:
運作,可用阿裡雲提供的 OSS Browser直接看到結果;
2、總結
阿裡雲OSS使用簡單友善,官方提供的OSS Browser工具也很友善,按流量計費,費用也還不算貴,如果資料量也不是那麼大,費用可接受,采用它無疑是最友善的;當然,如果不想付費使用,用minio自建檔案服務也是很友善的,這個我們後面來說;