小二是新來的實習生,作為技術 leader,我給他安排了一個非常簡單的練手任務,把前端 markdown 編輯器里上傳的圖片保存到服務器端,結果他真的就把圖片直接保存到了服務器上,這下可把我氣壞了,就不能搞個物件存盤服務,比如說 OSS、MinIO?
他理直氣壯地反駁道:“誰讓你不講清楚,我去找老板把你開掉!”我瞬間就慫了,說,“來來來,我手把手教你怎么把圖片保存到 OSS 上,好不好?”
“不用了,還是我來教你吧,”小二非常自信,下面是他在 Spring Boot 應用中整合 OSS 做的記錄,
特此宣告:阿里云 OSS 的產品負責人看到后請自覺過來結算下推廣費用(狗頭),真心講:Spring Boot+OSS 在實際開發中挺常見的,
一、開通 OSS
OSS 也就是 Object Storage Service,是阿里云提供的一套物件存盤服務,國內的競品還有七牛云的 Kodo和騰訊云的COS,
第一步,登錄阿里云官網,搜索“OSS”關鍵字,進入 OSS 產品頁,
第二步,如果是 OSS 新用戶的話,可以享受 6 個月的新人專享優惠價,不過續費的時候還是會肉疼,
第三步,進入 OSS 管理控制臺,點擊「Bucket 串列」,點擊「創建 Bucket」,

Bucket 的詞面意思是桶,這里指存盤空間,就是用于存盤物件的容器,注意讀寫權限為“公共讀”,也就是允許互聯網用戶訪問云空間上的圖片,
第四步,點擊「確定」就算是開通成功了,
二、整合 OSS
第一步,在 pom.xml 檔案中添加 OSS 的依賴,
<!-- 阿里云 OSS -->
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>3.10.2</version>
</dependency>
第二步,在 application.yml 檔案中添加 OSS 配置項,
aliyun:
oss:
# oss對外服務的訪問域名
endpoint: oss-cn-beijing.aliyuncs.com
# 訪問身份驗證中用到用戶標識
accessKeyId: LTAI5
# 用戶用于加密簽名字串和oss用來驗證簽名字串的密鑰
accessKeySecret: RYN
# oss的存盤空間
bucketName: itwanger-oss1
# 上傳檔案大小(M)
maxSize: 3
# 上傳檔案夾路徑前綴
dir:
prefix: codingmore/images/
第三步,新增 OssClientConfig.java 配置類,主要就是通過 @Value 注解從組態檔中獲取配置項,然后創建 OSSClient,
@Configuration
public class OssClientConfig {
@Value("${aliyun.oss.endpoint}")
String endpoint ;
@Value("${aliyun.oss.accessKeyId}")
String accessKeyId ;
@Value("${aliyun.oss.accessKeySecret}")
String accessKeySecret;
@Bean
public OSSClient createOssClient() {
return (OSSClient)new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
}
}
第四步,新增檔案上傳介面 OssController.java,引數為 MultipartFile,
@Controller
@Api(tags = "上傳")
@RequestMapping("/ossController")
public class OssController {
@Autowired
private IOssService ossService;
@RequestMapping(value = "https://www.cnblogs.com/upload",method=RequestMethod.POST)
@ResponseBody
@ApiOperation("上傳")
public ResultObject<String> upload(@RequestParam("file") MultipartFile file, HttpServletRequest req) {
return ResultObject.success(ossService.upload(file));
}
}
第五步,新增 Service,將檔案上傳到 OSS,并回傳檔案保存路徑,
@Service
public class OssServiceImpl implements IOssService{
@Value("${aliyun.oss.maxSize}")
private int maxSize;
@Value("${aliyun.oss.bucketName}")
private String bucketName;
@Value("${aliyun.oss.dir.prefix}")
private String dirPrefix;
@Autowired
private OSSClient ossClient;
@Override
public String upload(MultipartFile file) {
try {
return upload(file.getInputStream(), file.getOriginalFilename());
} catch (IOException e) {
LOGGER.error(e.getMessage());
}
return null;
}
@Override
public String upload(InputStream inputStream,String name) {
String objectName = getBucketName(name);
// 創建PutObject請求,
ossClient.putObject(bucketName, objectName, inputStream);
return formatPath(objectName);
}
private String getBucketName(String url){
String ext = "";
for(String extItem:imageExtension){
if(url.indexOf(extItem) != -1){
ext = extItem;
break;
}
}
return dirPrefix+ DateUtil.today()+"/"+ IdUtil.randomUUID()+ext;
}
private String formatPath(String objectName){
return "https://" +bucketName+"."+ ossClient.getEndpoint().getHost() + "/" + objectName;
}
}
第六步,打開 Apipost,測驗 OSS 上傳介面,注意引數選擇檔案,點擊發送后可以看到服務器端回傳的圖片鏈接,

第七步,進入阿里云 OSS 后臺管理,可以確認圖片確實已經上傳成功,

三、拉取前端代碼來測驗 OSS 上傳介面
codingmore-admin-web 是編程喵(Codingmore)的前端管理專案,可以通過下面的地址拉取到本地,
https://github.com/itwanger/codingmore-admin-web
執行 yarn run dev 命令后就可以啟動 Web 管理端了,進入到文章編輯頁面,選擇一張圖片進行上傳,可以確認圖片是可以正常從前端上傳到服務器端,服務器端再上傳到 OSS,之后再回傳前端圖片訪問鏈接的,

四、利用 OSS 進行自動轉鏈
第一步,在 PostsServiceImpl.java 中添加圖片轉鏈的方法,主要利用正則運算式找出文章內容中的外鏈,然后將外鏈的圖片上傳到 OSS,然后再替換掉原來的外鏈圖片,
// 匹配圖片的 markdown 語法
// 
// 
public static final String IMG_PATTERN = "\\!\\[.*\\]\\((.*)\\)";
private void handleContentImg(Posts posts) {
String content = posts.getPostContent();
Pattern p = Pattern.compile(IMG_PATTERN, Pattern.CASE_INSENSITIVE);
Matcher m = p.matcher(content);
Map<String, Future<String>> map = new HashMap<>();
while (m.find()) {
String imageTag = m.group();
LOGGER.info("使用分組進行替換{}", imageTag);
String imageUrl = imageTag.substring(imageTag.indexOf("(") + 1, imageTag.indexOf(")"));
// 確認是本站鏈接,不處理
if (imageUrl.indexOf(iOssService.getEndPoint()) != -1) {
continue;
}
// 通過執行緒池將圖片上傳到 OSS
Future<String> future = ossUploadImageExecutor.submit(() -> {
return iOssService.upload(imageUrl);
});
map.put(imageUrl, future);
}
for (String oldUrl : map.keySet()) {
Future<String> future = map.get(oldUrl);
try {
String imageUrl = future.get();
content = content.replace(oldUrl, imageUrl);
} catch (InterruptedException | ExecutionException e) {
LOGGER.error("獲取圖片鏈接出錯{}", e.getMessage());
}
}
posts.setPostContent(content);
}
第二步,在 OssServiceImpl.java 中添加根據外鏈地址上傳圖片到 OSS 的方法,
public String upload(String url) {
String objectName = getFileName(url);
try (InputStream inputStream = new URL(url).openStream()) {
ossClient.putObject(bucketName, objectName, inputStream);
} catch (IOException e) {
LOGGER.error(e.getMessage());
}
return formatOSSPath(objectName);
}
第三步,通過 Web 管理端來測驗外鏈是否轉鏈成功,先找兩張外鏈的圖片,可以看到 markdown 在預覽的時候就不顯示,

然后我們點擊發布,可以看到兩張圖片都正常顯示了,因為轉成了 OSS 的圖片訪問地址,

五、小結
綜上來看,實習生小二在 Spring Boot 中整合 OSS 的代碼還是挺靠譜的,也許 OSS+CDN 才是圖床的最好解決方案,不過阿里云的 HTTPS CDN 在 GitHub 上無法回源導致圖片不顯示的問題仍然沒有得到有效的解決,
需要原始碼的小伙伴可以直接到編程喵??原始碼路徑拉取:
https://github.com/itwanger/coding-more
本篇已收錄至 GitHub 上星標 1.8k+ star 的開源專欄《Java 程式員進階之路》,據說每一個優秀的 Java 程式員都喜歡她,風趣幽默、通俗易懂,內容包括 Java 基礎、Java 并發編程、Java 虛擬機、Java 企業級開發、Java 面試等核心知識點,學 Java,就認準 Java 程式員進階之路??,
https://github.com/itwanger/toBeBetterJavaer
star 了這個倉庫就等于你擁有了成為了一名優秀 Java 工程師的潛力,也可以戳下面的鏈接跳轉到《Java 程式員進階之路》的官網網址,開始愉快的學習之旅吧,
https://tobebetterjavaer.com/

沒有什么使我停留——除了目的,縱然岸旁有玫瑰、有綠蔭、有寧靜的港灣,我是不系之舟,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/447028.html
標籤:其他
