天天看點

使用SpringBoot實作檔案上傳

本篇部落格使用執行個體說明如何使用springboot實作單檔案上傳、多檔案上傳和多檔案下載下傳,在執行個體中會給出前端代碼後後端代碼。前端代碼如下:

<!DOCTYPE html>  
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org"  
      xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity3">  
    <head>  
        <title>DownloadAndUpload</title>  
    </head>  
    <body>  
       <form method="POST" enctype="multipart/form-data" action="http://localhost:9000/singleFileUpload">   
           <p>檔案1:<input type="file" name="file" /></p>  
           <p><input type="submit" value="單檔案上傳" /></p>  
       </form> 
       <form method="POST" enctype="multipart/form-data" action="http://localhost:9000/multiFileUpload">   
           <p>檔案1:<input type="file" name="file" /></p>  
           <p>檔案2:<input type="file" name="file" /></p>  
           <p>檔案3:<input type="file" name="file" /></p>  
           <p><input type="submit" value="多檔案上傳" /></p>  
       </form>
        <form method="GET" enctype="multipart/form-data" action="http://localhost:9000/downloadFile">   
           <p><input type="submit" value="下載下傳檔案" /></p>  
       </form>     
    </body>  
</html> 
           

先來看看上傳一個檔案,本次執行個體中前端使用的是form表單的形式送出帶上傳的檔案,在後端使用MultiFile接收前端送出的檔案。後端代碼如下:

@RequestMapping(value = "singleFileUpload",method = RequestMethod.POST)
    public ResponseDto singleFileUpload(@RequestParam("file")MultipartFile file) throws IOException {
        String fileName = file.getOriginalFilename();
        String fileType = fileName.substring(fileName.lastIndexOf(".")+);
        File fileDir = new File("tmp");
        if(!fileDir.exists()){
            fileDir.mkdir();
        }
        String path = fileDir.getAbsolutePath();
        file.transferTo(new File(fileDir.getAbsolutePath(),fileName));
        Map<String ,String> result = new HashMap<String, String>();
        result.put("name",file.getOriginalFilename());
        result.put("size",String.valueOf(file.getSize()));
        ResponseDto dto = new ResponseDto();
        dto.setData(result);
        dto.setStatus("200");
        dto.setTimestamp(String.valueOf(System.currentTimeMillis()));
        return dto;
    }
           

在背景代碼中指定了,form表單中檔案的控件名為file,如果前端的name沒有設定為file,後端将無法正确接收到檔案。後端重要是通過MultiFile拿到前端傳入的檔案,并在代碼中實作轉存。

多檔案上傳的後端代碼如下:

@RequestMapping(value = "multiFileUpload",method = RequestMethod.POST)
    public ResponseDto multiFileUpload(@RequestParam("file") MultipartFile[] files){
        StringBuilder builder = new StringBuilder();
        for (MultipartFile file : files){
            String fileName = file.getOriginalFilename();
            String fileType = fileName.substring(fileName.lastIndexOf(".")+);
            File fileDir = new File("tmp");
            if(!fileDir.exists()){
                fileDir.mkdir();
            }
            String path = fileDir.getAbsolutePath();
            try {
                file.transferTo(new File(fileDir.getAbsolutePath(),fileName));
            } catch (IOException e) {
                continue;
            }
            builder.append(file.getOriginalFilename()).append(",");
        }

        if(builder.length()>){
            builder = builder.deleteCharAt(builder.length()-);
        }
        ResponseDto dto = new ResponseDto();
        dto.setData(builder.toString());
        dto.setStatus("200");
        dto.setTimestamp(String.valueOf(System.currentTimeMillis()));
        return dto;
    }
           

跟單檔案上傳的後端代碼類似,隻不過這裡傳入的參數是一個File檔案數組,需要使用循環對數組裡的每個檔案做轉存處理。多檔案上傳時,前端多個檔案控件的名字都要與後端中RequestParam中指定的名稱的對應,否則後端隻會得到一個空的檔案數組。

關于檔案下載下傳,就是通過Response将伺服器或者其他地方存儲的檔案,以資料流的格式傳回給前端,代碼如下:

@RequestMapping(value = "/downloadFile", method=RequestMethod.GET)
    public void downFileFromServer(HttpServletResponse response){
        String fileName = "ScrollViewGroup.avi";
        //response.setHeader("content-type", "application/octet-stream");
        response.setContentType("application/octet-stream");
        response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
        byte[] buff = new byte[];
        BufferedInputStream bis = null;
        OutputStream os = null;
        try {
            os = response.getOutputStream();
            bis = new BufferedInputStream(new FileInputStream(new File("tmp",fileName)));
            int i = bis.read(buff);
            while (i != -) {
                os.write(buff, , buff.length);
                os.flush();
                i = bis.read(buff);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (bis != null) {
                try {
                    bis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
           

這裡需要注意,在使用response傳回檔案時,需要指定response的内容類型,在傳輸檔案時,設定為:application/octet-stream,在response的header中需要設定Content-Disposition,這個設定表明檔案時下載下傳還是線上打開,不可以不設定的。

上述代碼實測有效,需要的朋友可以直接使用。

繼續閱讀