1. 程式人生 > >SpringBoot初探(上傳檔案)

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,又到了測試的時候:跟前面一樣,看看效果

 

 之後你若還不信,控制檯有列印資訊,即檔名,然後去對比一下七牛云云空間的圖片,就能驗證了

 這裡我控制檯打印出來

再看七牛雲,可以看到是一樣的