SpringBoot初探(上傳檔案)
學了Spring,SpringMVC,Mybatis這一套再來看SpringBoot,心裡只有一句握草,好方便
這裡對今天做的東西做個總結,然後在這之間先安利一個熱部署的工具,叫spring-DevTools,用這個的好處就是省去了我們以往改動程式碼
還要重啟專案才能測試效果的麻煩,專案比較小的時候倒還不要緊,萬一專案大了,編譯要好一會,那麼重啟會佔用我們大量時間
引入方式用maven即可
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-devtools --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <version>2.1.1.RELEASE</version> </dependency>
進入正題:這個隨筆包括上傳到自己伺服器(以本機localhost做測試)和七牛雲端儲存檔案(沒錯,是跟著牛客葉神來做的)
上傳檔案其實非常簡單,因為Spring裡面就是MultiPartFile一個引數就行,然後後臺在相應做一些命名處理和規定路徑即可
第一種,
寫好業務服務類:
package com.nowcoder.toutiao.service.Impl; import com.nowcoder.toutiao.Utils.ToutiaoUtil; import com.nowcoder.toutiao.service.NewsService; import org.springframework.stereotype.Service; import org.springframework.web.multipart.MultipartFile; import java.io.File; import java.io.IOException; import java.nio.file.Files; import java.nio.file.StandardCopyOption; import java.util.UUID; @Service public class NewsServiceImpl implements NewsService { @Override public String saveLoadedFile(MultipartFile file) { int pos = file.getOriginalFilename().lastIndexOf("."); //判斷點的位置 if (pos<0) return null; //獲得檔案的副檔名,png,jpg等 String fileExt = file.getOriginalFilename().substring(pos+1).toLowerCase(); if (!ToutiaoUtil.isFileAllowed(fileExt)){//判斷是否為規定格式 return null; } String fileName = UUID.randomUUID().toString().replaceAll("-","")+"."+fileExt; try { //複製到路徑下面 Files.copy(file.getInputStream(),new File(ToutiaoUtil.saveDir+fileName).toPath(),StandardCopyOption.REPLACE_EXISTING); }catch (IOException e){ } return ToutiaoUtil.TOUTIAO_DOMAIN+"image?name="+fileName; } }
然後ToutiaoUtil是一個工具類
package com.nowcoder.toutiao.Utils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class ToutiaoUtil { //七牛雲檔案儲存空間的域名,作為訪問該圖片用的url的字首 public static String PREFIX = "http://pji43w60m.bkt.clouddn.com/"; //logger private static final Logger logger = LoggerFactory.getLogger(ToutiaoUtil.class); //副檔名 private static String[] IMAGE_FILE_EXT = {"png","bmp","jpg","jpeg"}; //本地存放檔案的資料夾 public static String saveDir = "D:/UpLoad/"; //本地域名 localhost:8080 public static String TOUTIAO_DOMAIN = "http://127.0.0.1:8080/"; /** * 判斷副檔名是否符合 * */ public static boolean isFileAllowed(String fileExt){ for (String ext:IMAGE_FILE_EXT){ if (ext.equals(fileExt)) return true; } return false; } }
之後到控制器裡面寫介面:
@RequestMapping(path = "/uploadImage",method = {RequestMethod.POST}) @ResponseBody public String upLoad(@RequestParam("file")MultipartFile file){ try { String fileUrl = newsService.saveLoadedFile(file); if (fileUrl==null){ JSONObject json= new JSONObject(); json.put("result", JSONObject.toJSON("上傳失敗")); return json.toJSONString(); } JSONObject json= new JSONObject(); json.put("result", JSONObject.toJSON("上傳圖片成功")); return json.toJSONString(); }catch (Exception e){ JSONObject json= new JSONObject(); json.put("result", JSONObject.toJSON("上傳失敗")); return json.toJSONString(); } }
上傳檔案前端我也不大會寫,所以用Postman來測試,記得Key一定要與介面中寫的引數保持一致
然後看返回
再去本地的路徑下看一下,即ToutiaoUtil裡面的D:/upload,可以看到上傳成功
第二種是七牛雲端儲存,這是我第一次接觸這個
首先去七牛雲註冊一個賬號,然後必須通過個人實名認證才能使用服務,這些完成後
在工程裡引入七牛雲的依賴,看官方文件https://developer.qiniu.com/kodo/sdk/1239/java,我就不把這一大段依賴貼出來了
在這之後,去控制檯新建一個儲存空間,記下金鑰和空間名字,後面要用到
之後就是寫程式碼了,為了方便,這裡與上面不同的就是把儲存的方式從存本地變成了上傳七牛雲,所以除了上傳那部分,以及最後返回的部分,其餘什麼命名和判斷格式都和第一種一樣
我們把七牛雲文件中的程式碼單獨作為一個service
package com.nowcoder.toutiao.service.Impl; import com.google.gson.Gson; import com.nowcoder.toutiao.Utils.ToutiaoUtil; import com.qiniu.common.QiniuException; import com.qiniu.common.Zone; import com.qiniu.http.Response; import com.qiniu.storage.Configuration; import com.qiniu.storage.UploadManager; import com.qiniu.storage.model.DefaultPutRet; import com.qiniu.util.Auth; import org.springframework.stereotype.Service; import org.springframework.web.multipart.MultipartFile; import java.io.IOException; import java.util.UUID; @Service public class QiniuService { //上傳七牛雲 public String upload(MultipartFile file) throws IOException { int pos = file.getOriginalFilename().lastIndexOf("."); if (pos<0) return null; String fileExt = file.getOriginalFilename().substring(pos+1).toLowerCase(); if (!ToutiaoUtil.isFileAllowed(fileExt)){ return null; } String fileName = UUID.randomUUID().toString().replaceAll("-","")+"."+fileExt; //構造一個帶指定Zone物件的配置類 Configuration cfg = new Configuration(Zone.zone0()); //...其他引數參考類註釋 UploadManager uploadManager = new UploadManager(cfg); //...生成上傳憑證,然後準備上傳 String accessKey = "zk7UXbWxZKH2xdqN-lic119Pu3DMFMiFeZN5HRS2"; String secretKey = "mnLG5YtRvGevec4j_0QMf8l47qmgqrj9dIL10yiL"; String bucket = "yintianhaoupload"; //如果是Windows情況下,格式是 D:\\qiniu\\test.png Auth auth = Auth.create(accessKey, secretKey); String upToken = auth.uploadToken(bucket); try { Response response = uploadManager.put(file.getBytes(), fileName, upToken); //解析上傳成功的結果 DefaultPutRet putRet = new Gson().fromJson(response.bodyString(), DefaultPutRet.class); System.out.println(putRet.key); System.out.println(putRet.hash); return ToutiaoUtil.PREFIX+putRet.key; } catch (QiniuException ex) { Response r = ex.response; System.err.println(r.toString()); try { System.err.println(r.bodyString()); } catch (QiniuException ex2) { //ignore } return null; } } }
之後就是寫介面,這裡我想在上傳之後直接顯示出圖片,所以我把service的返回值直接設成了圖片的訪問地址,之後在接口裡確認上傳無誤就只要redirect一下就行了
@RequestMapping(path = "/uploadImageByQiniu",method = {RequestMethod.POST}) public String uploadFileByQiniu(@RequestParam("file")MultipartFile file) throws IOException { String res = qiniuService.upload(file); if (res!=null){ System.out.println(res); return "redirect:"+res; }else { //不成功,返回庫中已有的圖片顯示 return "redirect:http://pji43w60m.bkt.clouddn.com/cc89ae4e48ba406eb4257c955e65c6b2.png"; } }
ok,又到了測試的時候:跟前面一樣,看看效果
之後你若還不信,控制檯有列印資訊,即檔名,然後去對比一下七牛云云空間的圖片,就能驗證了
這裡我控制檯打印出來
再看七牛雲,可以看到是一樣的