<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          崩潰!我?guī)У膶?shí)習(xí)生竟然把圖片直接存到了服務(wù)器上!

          共 5750字,需瀏覽 12分鐘

           ·

          2022-03-10 21:48

          小二是新來的實(shí)習(xí)生,作為技術(shù) leader,我給他安排了一個(gè)非常簡單的練手任務(wù),把前端 markdown 編輯器里上傳的圖片保存到服務(wù)器端,結(jié)果他真的就把圖片直接保存到了服務(wù)器上,這下可把我氣壞了,就不能搞個(gè)對象存儲服務(wù),比如說 OSS、MinIO?

          他理直氣壯地反駁道:“誰讓你不講清楚,我去找老板把你開掉!”我瞬間就慫了,說,“來來來,我手把手教你怎么把圖片保存到 OSS 上,好不好?”

          “不用了,還是我來教你吧?!毙《浅W孕?,下面是他在 Spring Boot 應(yīng)用中整合 OSS 做的記錄。

          一、開通 OSS

          OSS 也就是 Object Storage Service,是阿里云提供的一套對象存儲服務(wù),國內(nèi)的競品還有七牛云的 Kodo和騰訊云的COS。

          第一步,登錄阿里云官網(wǎng),搜索“OSS”關(guān)鍵字,進(jìn)入 OSS 產(chǎn)品頁。

          第二步,如果是 OSS 新用戶的話,可以享受 6 個(gè)月的新人專享優(yōu)惠價(jià),不過續(xù)費(fèi)的時(shí)候還是會肉疼。

          第三步,進(jìn)入 OSS 管理控制臺,點(diǎn)擊「Bucket 列表」,點(diǎn)擊「創(chuàng)建 Bucket」。

          Bucket 的詞面意思是桶,這里指存儲空間,就是用于存儲對象的容器。注意讀寫權(quán)限為“公共讀”,也就是允許互聯(lián)網(wǎng)用戶訪問云空間上的圖片。

          第四步,點(diǎn)擊「確定」就算是開通成功了。

          二、整合 OSS

          第一步,在 pom.xml 文件中添加 OSS 的依賴。



          ????com.aliyun.oss
          ????aliyun-sdk-oss
          ????3.10.2

          第二步,在 application.yml 文件中添加 OSS 配置項(xiàng)。

          aliyun:
          ??oss:
          ??????#?oss對外服務(wù)的訪問域名
          ????endpoint:?oss-cn-beijing.aliyuncs.com
          ??????#?訪問身份驗(yàn)證中用到用戶標(biāo)識
          ????accessKeyId:?LTAI5
          ??????#?用戶用于加密簽名字符串和oss用來驗(yàn)證簽名字符串的密鑰
          ????accessKeySecret:?RYN
          ??????#?oss的存儲空間
          ????bucketName:?itwanger-oss1
          ??????#?上傳文件大小(M)
          ????maxSize:?3
          ??????#?上傳文件夾路徑前綴
          ????dir:
          ??????prefix:?codingmore/images/

          第三步,新增 OssClientConfig.java 配置類,主要就是通過 ?@Value 注解從配置文件中獲取配置項(xiàng),然后創(chuàng)建 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,參數(shù)為 MultipartFile。

          @Controller
          @Api(tags?=?"上傳")
          @RequestMapping("/ossController")
          public?class?OssController?{
          ????@Autowired
          ????private?IOssService?ossService;

          ????@RequestMapping(value?=?"/upload",method=RequestMethod.POST)
          ????@ResponseBody
          ????@ApiOperation("上傳")
          ????public?ResultObject?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);
          ????????//?創(chuàng)建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 上傳接口,注意參數(shù)選擇文件,點(diǎn)擊發(fā)送后可以看到服務(wù)器端返回的圖片鏈接。

          第七步,進(jìn)入阿里云 OSS 后臺管理,可以確認(rèn)圖片確實(shí)已經(jīng)上傳成功。

          三、拉取前端代碼來測試 OSS 上傳接口

          codingmore-admin-web 是編程喵(Codingmore)的前端管理項(xiàng)目,可以通過下面的地址拉取到本地。

          https://github.com/itwanger/codingmore-admin-web

          執(zhí)行 yarn run dev 命令后就可以啟動 Web 管理端了,進(jìn)入到文章編輯頁面,選擇一張圖片進(jìn)行上傳,可以確認(rèn)圖片是可以正常從前端上傳到服務(wù)器端,服務(wù)器端再上傳到 OSS,之后再返回前端圖片訪問鏈接的。

          四、利用 OSS 進(jìn)行自動轉(zhuǎn)鏈

          第一步,在 PostsServiceImpl.java 中添加圖片轉(zhuǎn)鏈的方法,主要利用正則表達(dá)式找出文章內(nèi)容中的外鏈,然后將外鏈的圖片上傳到 OSS,然后再替換掉原來的外鏈圖片。

          //?匹配圖片的?markdown?語法
          //?![](hhhx.png)
          //?![xx](hhhx.png?ax)
          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>?map?=?new?HashMap<>();

          ????while?(m.find())?{
          ????????String?imageTag?=?m.group();
          ????????LOGGER.info("使用分組進(jìn)行替換{}",?imageTag);

          ????????String?imageUrl?=?imageTag.substring(imageTag.indexOf("(")?+?1,?imageTag.indexOf(")"));

          ????????//?確認(rèn)是本站鏈接,不處理
          ????????if?(imageUrl.indexOf(iOssService.getEndPoint())?!=?-1)?{
          ????????????continue;
          ????????}

          ????????//?通過線程池將圖片上傳到?OSS
          ????????Future?future?=?ossUploadImageExecutor.submit(()?->?{
          ????????????return?iOssService.upload(imageUrl);
          ????????});
          ????????map.put(imageUrl,?future);
          ????}

          ????for?(String?oldUrl?:?map.keySet())?{
          ????????Future?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 中添加根據(jù)外鏈地址上傳圖片到 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 管理端來測試外鏈?zhǔn)欠褶D(zhuǎn)鏈成功。先找兩張外鏈的圖片,可以看到 markdown 在預(yù)覽的時(shí)候就不顯示。

          然后我們點(diǎn)擊發(fā)布,可以看到兩張圖片都正常顯示了,因?yàn)檗D(zhuǎn)成了 OSS 的圖片訪問地址。

          五、小結(jié)

          綜上來看,實(shí)習(xí)生小二在 Spring Boot 中整合 OSS 的代碼還是挺靠譜的。也許 OSS+CDN 才是圖床的最好解決方案,不過阿里云的 HTTPS CDN 在 GitHub 上無法回源導(dǎo)致圖片不顯示的問題仍然沒有得到有效的解決。

          需要源碼的小伙伴可以直接到編程喵??源碼路徑拉?。?/p>

          https://github.com/itwanger/coding-more


          沒有什么使我停留——除了目的,縱然岸旁有玫瑰、有綠蔭、有寧靜的港灣,我是不系之舟。

          推薦閱讀

          瀏覽 74
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  青青草原在线 | 色婷婷激情视频 | 中文字幕在线一区 | 日韩毛片儿。 | 激情五月色情在线播放 |