本文介紹GitClub小程序後端的服務器文件的遷移以及更新圖片上傳至阿里雲OSS存儲服務器,若是不瞭解GitClub小程序的朋友能夠看下個人上篇文章關於Android開源庫分享平臺,(GitClub)微信小程序的開發體驗,在此特別糾正下,當前版本暫時只有Android的開源庫分享,後續會增長Java、iOS、前端等不一樣語言的分類,感興趣的能夠去關注下咱們的小程序,源碼地址:GitClub。鋪墊結束,請使用掃描這個二維碼登錄GitClub小程序參觀。 html
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>2.8.3</version>
</dependency>
複製代碼
一、添加oss.properties配置文件,內容以下:
#阿里雲OSS配置
#原服務器地址
bucketUrl = https://bucketName.oss-cn-shenzhen.aliyuncs.com
#自定義解析後服務器地址
baseUrl = https://xxx.502tech.com
#能夠選擇其餘的地址
endpoint = https://oss-cn-qingdao.aliyuncs.com
#已經在控制檯建立的bucket
bucketName = bucketName
#你上傳文件的保存路徑,若是bucket中不存在則建立(其實原理並非文件夾,只是文件名,詳情請先閱讀官方文檔)
picLocation = GitClub/image/
#相應的id和key值,請填寫你具體的值,這裏不方便展現我本身的。
accessKeyId = 阿里雲OSS的accessKeyId
accessKeySecret = 阿里雲OSS的accessKeySecret
二、建立類OSSConfig
public class OSSConfig {
private String bucketUrl; //原圖片服務器地址
private String baseUrl; //自定義解析後的圖片服務器地址
private String endpoint; //鏈接區域地址
private String accessKeyId; //鏈接keyId
private String accessKeySecret; //鏈接祕鑰
private String bucketName; //須要存儲的bucketName
private String picLocation; //圖片保存路徑
public OSSConfig() {
try {
this.bucketUrl = SystemConfig.getConfigResource("bucketUrl");
this.baseUrl = SystemConfig.getConfigResource("baseUrl");
this.endpoint = SystemConfig.getConfigResource("endpoint");
this.bucketName = SystemConfig.getConfigResource("bucketName");
this.picLocation = SystemConfig.getConfigResource("picLocation");
this.accessKeyId = SystemConfig.getConfigResource("accessKeyId");
this.accessKeySecret = SystemConfig.getConfigResource("accessKeySecret");
} catch (IOException e) {
e.printStackTrace();
}
}
...
省略get、set方法
複製代碼
private static OSSConfig config = null;
/**
*
* @MethodName: uploadFile
* @Description: OSS單文件上傳
* @param file
* @param fileType 文件後綴
* @return String 文件地址
*/
public static String uploadFile(File file,String fileType){
config = config == null ? new OSSConfig():config;
//經過UUID生成文件名
String fileName = config.getPicLocation()
+UUID.randomUUID().toString().toUpperCase()
.replace("-", "")
+"."+fileType;
return putFile(file,fileType,fileName);
}
/**
*
* @MethodName: updateFile
* @Description: 更新文件:只更新內容,不更新文件名和文件地址。
* (由於地址沒變,可能存在瀏覽器原數據緩存,不能及時加載新數據,例如圖片更新,請注意)
* @param file
* @param fileType
* @param oldUrl
* @return String
*/
public static String updateFile(File file,String fileType,String oldUrl){
String fileName = getFileName(oldUrl);
if(fileName==null) return null;
return putFile(file,fileType,fileName);
}
/**
*
* @MethodName: replaceFile
* @Description: 替換文件:刪除原文件並上傳新文件,文件名和地址同時替換
* 解決原數據緩存問題,只要更新了地址,就能從新加載數據)
* @param file
* @param fileType 文件後綴
* @param oldUrl 須要刪除的文件地址
* @return String 文件地址
*/
public static String replaceFile(File file,String fileType,String oldUrl){
boolean flag = deleteFile(oldUrl); //先刪除原文件
if(!flag){
//更改文件的過時時間,讓他到期自動刪除。
}
return uploadFile(file, fileType);
}
/**
*
* @MethodName: deleteFile
* @Description: 單文件刪除
* @param fileUrl 須要刪除的文件url
* @return boolean 是否刪除成功
*/
public static boolean deleteFile(String fileUrl){
config = config == null ? new OSSConfig():config;
String bucketName = OSSUploadUtil.getBucketName(fileUrl); //根據url獲取bucketName
String fileName = OSSUploadUtil.getFileName(fileUrl); //根據url獲取fileName
if(bucketName==null||fileName==null) return false;
OSSClient ossClient = null;
try {
ossClient = new OSSClient(config.getEndpoint(), config.getAccessKeyId(), config.getAccessKeySecret());
GenericRequest request = new DeleteObjectsRequest(bucketName).withKey(fileName);
ossClient.deleteObject(request);
} catch (Exception oe) {
oe.printStackTrace();
return false;
} finally {
ossClient.shutdown();
}
return true;
}
/**
*
* @MethodName: batchDeleteFiles
* @Description: 批量文件刪除(較快):適用於相同endPoint和BucketName
* @param fileUrls 須要刪除的文件url集合
* @return int 成功刪除的個數
*/
public static int deleteFile(List<String> fileUrls){
int deleteCount = 0; //成功刪除的個數
String bucketName = OSSUploadUtil.getBucketName(fileUrls.get(0)); //根據url獲取bucketName
List<String> fileNames = OSSUploadUtil.getFileName(fileUrls); //根據url獲取fileName
if(bucketName==null||fileNames.size()<=0) return 0;
OSSClient ossClient = null;
try {
ossClient = new OSSClient(config.getEndpoint(), config.getAccessKeyId(), config.getAccessKeySecret());
DeleteObjectsRequest request = new DeleteObjectsRequest(bucketName).withKeys(fileNames);
DeleteObjectsResult result = ossClient.deleteObjects(request);
deleteCount = result.getDeletedObjects().size();
} catch (OSSException oe) {
oe.printStackTrace();
throw new RuntimeException("OSS服務異常:", oe);
} catch (ClientException ce) {
ce.printStackTrace();
throw new RuntimeException("OSS客戶端異常:", ce);
} finally {
ossClient.shutdown();
}
return deleteCount;
}
/**
*
* @MethodName: batchDeleteFiles
* @Description: 批量文件刪除(較慢):適用於不一樣endPoint和BucketName
* @param fileUrls 須要刪除的文件url集合
* @return int 成功刪除的個數
*/
public static int deleteFiles(List<String> fileUrls){
int count = 0;
for (String url : fileUrls) {
if(deleteFile(url)){
count++;
}
}
return count;
}
/**
*
* @MethodName: putFile
* @Description: 上傳文件
* @param file
* @param fileType
* @param fileName
* @return String
*/
private static String putFile(File file, String fileType, String fileName){
config = config==null?new OSSConfig():config;
String url = null; //默認null
OSSClient ossClient = null;
try {
ossClient = new OSSClient(config.getEndpoint(), config.getAccessKeyId(), config.getAccessKeySecret());
InputStream input = new FileInputStream(file);
ObjectMetadata meta = new ObjectMetadata(); // 建立上傳Object的Metadata
meta.setContentType(OSSUploadUtil.contentType(fileType)); // 設置上傳內容類型
meta.setCacheControl("no-cache"); // 被下載時網頁的緩存行爲
PutObjectRequest request = new PutObjectRequest(config.getBucketName(), fileName,input,meta); //建立上傳請求
ossClient.putObject(request);
Date expiration = new Date(new Date().getTime() + 3600L * 1000 * 24 * 365 * 10); // 設置URL過時時間爲10年 3600L* 1000*24*365*10
//上傳成功再返回的文件路徑
url = ossClient.generatePresignedUrl(config.getBucketName(), fileName, expiration)
.toString()
.replaceFirst(config.getBucketUrl(), config.getBaseUrl());
} catch (OSSException | FileNotFoundException | ClientException oe) {
oe.printStackTrace();
return null;
} finally {
if (ossClient != null) {
ossClient.shutdown();
}
}
return url;
}
/**
*
* @MethodName: contentType
* @Description: 獲取文件類型
* @param fileType
* @return String
*/
private static String contentType(String fileType){
fileType = fileType.toLowerCase();
String contentType = "";
switch (fileType) {
case "bmp": contentType = "image/bmp";
break;
case "gif": contentType = "image/gif";
break;
case "png":
case "jpeg":
case "jpg": contentType = "image/jpeg";
break;
case "html":contentType = "text/html";
break;
case "txt": contentType = "text/plain";
break;
case "vsd": contentType = "application/vnd.visio";
break;
case "ppt":
case "pptx":contentType = "application/vnd.ms-powerpoint";
break;
case "doc":
case "docx":contentType = "application/msword";
break;
case "xml":contentType = "text/xml";
break;
case "mp4":contentType = "video/mp4";
break;
default: contentType = "application/octet-stream";
break;
}
return contentType;
}
/**
*
* @MethodName: getBucketName
* @Description: 根據url獲取bucketName
* @param fileUrl 文件url
* @return String bucketName
*/
private static String getBucketName(String fileUrl){
String http = "http://";
String https = "https://";
int httpIndex = fileUrl.indexOf(http);
int httpsIndex = fileUrl.indexOf(https);
int startIndex = 0;
if(httpIndex==-1){
if(httpsIndex==-1){
return null;
}else{
startIndex = httpsIndex+https.length();
}
}else{
startIndex = httpIndex+http.length();
}
int endIndex = fileUrl.indexOf(".oss-");
return fileUrl.substring(startIndex, endIndex);
}
/**
*
* @MethodName: getFileName
* @Description: 根據url獲取fileName
* @param fileUrl 文件url
* @return String fileName
*/
private static String getFileName(String fileUrl){
String str = "aliyuncs.com/";
int beginIndex = fileUrl.indexOf(str);
if(beginIndex==-1) return null;
return fileUrl.substring(beginIndex+str.length());
}
/**
*
* @MethodName: getFileName
* @Description: 根據url獲取fileNames集合
* @param fileUrls 文件url
* @return List<String> fileName集合
*/
private static List<String> getFileName(List<String> fileUrls){
List<String> names = new ArrayList<>();
for (String url : fileUrls) {
names.add(getFileName(url));
}
return names;
}
}
複製代碼
//把以前上傳到項目特定目錄下的邏輯修改爲上傳至OSS
@PostMapping("/uploadArticleImg")
public Result<Map<String, String>> uploadArticleImg(@RequestParam(value = "article_img") MultipartFile file) {
if (file == null || file.isEmpty() || file.getSize() == 0) {
return ResultUtils.error(ResultCode.UPLOAD_FILE_EMPTY);
}
if (file.getSize() > 10 * 1024 * 1024) {
return ResultUtils.error(ResultCode.UPLOAD_FILE_LIMIT);
}
Map<String, String> map = new HashMap<>();
String fileType = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf(".")+1);
//OSS單文件上傳,返回上傳成功後的oss存儲服務器中的url
String fileName = OSSUploadUtil.uploadFile(FileUtils.multi2File(file), fileType);
map.put(file.getName(), fileName);
return ResultUtils.ok(map);
}
複製代碼
@PostMapping("/trasform2OSS")
public Result<Boolean> trasformImg2OSS(){
File path = null;
try {
path = new File(ResourceUtils.getURL("classpath:").getPath());
} catch (FileNotFoundException e) {
e.printStackTrace();
}
if (!path.exists()) path = new File("");
System.out.println("path:" + path.getAbsolutePath());
//若是上傳目錄爲/static/images/upload/,則能夠以下獲取:
File upload = new File(path.getAbsolutePath(), "static/images/upload/");
if (!upload.exists()) upload.mkdirs();
System.out.println("upload url:" + upload.getAbsolutePath());
File[] files = upload.listFiles();
//更新圖片的url到oss 並把最新oss的圖片地址保存到數據庫
List<Article> articles = articleRepository.findAll();
articles.forEach(article -> {
if (null != article){
for (File file : files){
if(null != file){
if(null == article.getImg_url() || null == file.getName()){
continue;
}
if(article.getImg_url().contains(file.getName())){
//上傳到oss
String fileType = file.getName().substring(file.getName().lastIndexOf(".")+1);
String url = OSSUploadUtil.uploadFile(file, fileType);
logger.info("上傳到oss地址:"+url);
//更新到服務器
article.setImg_url(url);
articleRepository.saveAndFlush(article);
//更新數據到引擎
articleSearchRepository.save(new ESArticle(article));
}
}
}
}
});
return ResultUtils.ok(true);
}
複製代碼
由於以前咱們的圖片上傳至項目目錄中的指定路徑如:502tech.com/geekdaily/x… 如今須要所有替換成如:xxx.502tech.com/123.png 格式,注意:這裏xxx.502tech.com是咱們的二級域名,上傳文件至OSS以後默認會返回如:bucketName.oss-cn-shenzhen.aliyuncs.com/123.png 格式。須要咱們手動在阿里雲OSS域名管理中去綁定域名,若是想要使用https,則須要申請SSL證書,這裏你能夠申請一個免費的,能夠自行百度,大概15分鐘會申請成功,而後須要在OSS的域名管理中添加SSL證書,這裏切記:下載nginx版本的證書,而後複製粘貼對應的公鑰和私鑰。前端