【轉載】springboot上傳+下載文件實例

 

前言

一次“上傳文件”的點擊蘊含着一輪請求,我們要做的就是針對每一次的請求進行i/o處理,並返回給前端用戶

 

一.文件上傳

文件上傳,也稱爲upload,是指將本地圖片、視頻、音頻等文件上傳到服務器上,文件上傳與下載可謂是在生活中應用十分廣泛,一次上傳對應一次請求,後端要做的是如何把這次請求中的文件信息轉存到指定的地址


以上傳圖片爲例

在表單裏,當點擊或者拖拽文件上傳,前端頁面就會發出一次如下的請求:


在後端的Controller層中怎樣才能接受到前端發來的文件呢?這就要用到Apache爲我們提供的兩個組件,commons-fileuploadcommons-io,本質是對文件的i/o操作

基於上面兩個組件,Spring框架在spring-web包中對文件上傳進行了封裝,大大簡化了服務端代碼,所以只需要在Controller的方法中聲明一個MultipartFile類型的參數即可接收上傳的文件,就像這樣:

public class CommonController {

    @Value("${reggie.path}") //@Value註解讀取配置文件中reggie的值
    private String Basepath;

    @PostMapping("/upload")
    public R<String> upload(MultipartFile file) {
        //file是一個指定文件,必須轉存到指定位置,這裏的形參必須命名爲file!
        log.info(file.toString());

        String usedName = file.getOriginalFilename();//原始名

        String jpg = usedName.substring(usedName.lastIndexOf("."));
        String uuidName = UUID.randomUUID().toString() + jpg;//使用UUID生成32位隨機名
        //創建一個目錄對象
        File file1 = new File(Basepath);
        //如果目錄不存在
        if (!(file1.exists())) {
            file1.mkdirs();//就按照Basepath創建一個目錄
        }
        //將臨時文件轉存到電腦硬盤
        try {
            //通過配置文件的形式將轉存路徑變得更靈活
            file.transferTo(new File(Basepath + uuidName));
        } catch (IOException e) {
            e.printStackTrace();
        }
        return R.success(uuidName);//把文件名字給前端,回顯數據
    }
}

要注意這裏的形參必須定義爲file,與前端中的表單信息一致,否則文件信息不會傳到方法裏。


當在前端頁面上傳文件過後,文件信息就被存到了一個tomcat臨時目錄中,在本地電腦中可以找到


爲了實現完整的上傳功能,需要將臨時的文件轉存到指定的位置中,如果不轉存,下一次刷新文件信息就會丟失
file.transferTo(new File(Basepath+usedName));

二.改進

大家可能會發現,usedName就是用戶上傳文件的文件名,但難免會出現重名的情況,爲了避免我們可以使用UUID生成隨機文件名,但是生成的id沒有“.jpg”的的後綴,所以還需要動態地去截取一下usedName,就像這樣:

      String usedName= file.getOriginalFilename();//原始名
      String jpg = usedName.substring(usedName.lastIndexOf("."));//截取.jpg後綴
      String uuidName= UUID.randomUUID().toString()+jpg;//使用UUID生成32位隨機名

在SpringBoot的配置類中,轉存目錄path是我自定義的,這就需要考慮目錄存不存在的問題,對此應在轉存前加上判斷條件,就像這樣:

//創建一個目錄對象
File file1 = new File(Basepath);
//如果目錄不存在
if (!(file1.exists())){
    file1.mkdirs();//就按照Basepath創建一個目錄
}

三.文件下載

爲了上傳文件(圖片)後能夠回顯至瀏覽器(上傳後能看到自己上傳的圖片)我們需要對上傳的文件進行讀取、下載,本質是將文件從服務器傳輸到本地計算機的過程,也是文件i/o讀寫的一種體現形式,只不過是從服務器到瀏覽器再到電腦


同樣地,當客戶端點擊下載文件,一次請求就夾帶了文件的id,也就是(uuidName),針對前端傳來的name,在Controller層中要做出相應的i/o處理,做出響應,就像這樣:

@GetMapping("/download")
//請求匹配到方法
public void download(String name, HttpServletResponse response) {
    //通過輸入流讀取文件內容
    try {
        FileInputStream fileInputStream = new FileInputStream(Basepath + name);
        //通過輸出流,將文件寫回到瀏覽器,在瀏覽器展示圖片
        ServletOutputStream outputStream = response.getOutputStream();

        response.setContentType("image/jpg");//設置響應回去的是什麼類型的文件

        int length = 0;       //   i/o讀取 重點複習
        byte[] bytes = new byte[1024];
        while (((length = fileInputStream.read(bytes)) != -1)) {
            outputStream.write(bytes, 0, length);
            outputStream.flush();
        }

        //關閉資源
        outputStream.close();
        fileInputStream.close();

    } catch (Exception e) {
        e.printStackTrace();
    }

四.上傳圖片/回顯圖片

當爲菜品添加其圖示並回顯至瀏覽器,這就涉及到文件上傳下載,文件不下載到瀏覽器就不會回顯!

回顯的過程,不難看出就是通過發送一個name參數傳給後端的download方法並得到響應:

從上傳到回顯其實就是upload/download方法的調用,就像這樣:

@PostMapping("/upload")
public R<String> upload(MultipartFile file) {
    //file是一個指定文件,必須轉存到指定位置,這裏的形參必須命名爲file!
    log.info(file.toString());

    String usedName = file.getOriginalFilename();//原始名

    String jpg = usedName.substring(usedName.lastIndexOf("."));
    String uuidName = UUID.randomUUID().toString() + jpg;//使用UUID生成32位隨機名
    //創建一個目錄對象
    File file1 = new File(Basepath);
    //如果目錄不存在
    if (!(file1.exists())) {
        file1.mkdirs();//就按照Basepath創建一個目錄
    }
    //將臨時文件轉存到電腦硬盤
    try {
        //通過配置文件的形式將轉存路徑變得更靈活
        file.transferTo(new File(Basepath + uuidName));
    } catch (IOException e) {
        e.printStackTrace();
    }
    return R.success(uuidName);//把文件名字給前端,回顯數據
}

@GetMapping("/download")
//請求匹配到方法
public void download(String name, HttpServletResponse response) {
    //通過輸入流讀取文件內容
    try {
        FileInputStream fileInputStream = new FileInputStream(new File(Basepath + name));
        //通過輸出流,將文件寫回到瀏覽器,在瀏覽器展示圖片
        ServletOutputStream outputStream = response.getOutputStream();

        response.setContentType("image/jpg");//設置響應回去的是什麼類型的文件

        int length = 0;       //   i/o讀取 重點複習
        byte[] bytes = new byte[1024];
        while (((length = fileInputStream.read(bytes)) != -1)) {
            outputStream.write(bytes, 0, length);
            outputStream.flush();
        }

        //關閉資源
        outputStream.close();
        fileInputStream.close();

    } catch (Exception e) {
        e.printStackTrace();
    }

這樣文件的上傳與下載就get了

轉載:https://www.lmlphp.com/user/414079/article/item/10594072

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章