1. 程式人生 > 其它 >【SpringMVC 從 0 開始】檔案上傳和下載

【SpringMVC 從 0 開始】檔案上傳和下載

使用 ResponseEntity 實現檔案上傳和下載

在 static 下新建一個 img ,並且我放了一張圖片在裡面,然後重新 maven 打包一下。

下載

新建一個頁面file.html,並且配置檢視控制器,以便跳轉:

<mvc:view-controller path="/file" view-name="file"></mvc:view-controller>

編寫頁面內容,用來下載我上面存放到 img 中的圖片:

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>測試檔案上傳和下載</title>
</head>
<body>
<a th:href="@{/testDown}">下載靜態圖片</a>
</body>
</html>

後端編寫對應處理請求的控制,新建一個類 FileUpAndDownController,在下面編寫控制器方法:

@Controller
public class FileUpAndDownController {

    @RequestMapping("/testDown")
    public ResponseEntity<byte[]> testResponseEntity(HttpSession session) throws IOException {
        //獲取ServletContext物件
        ServletContext servletContext = session.getServletContext();
        //獲取伺服器中檔案的真實路徑
        String realPath = servletContext.getRealPath("/static/img/ACC3.jpg");
        //建立輸入流
        InputStream is = new FileInputStream(realPath);
        //建立位元組陣列,is.available()是當前流的所有位元組數
        byte[] bytes = new byte[is.available()];
        //將流讀到位元組陣列中
        is.read(bytes);
        //建立HttpHeaders物件設定響應頭資訊
        MultiValueMap<String, String> headers = new HttpHeaders();
        //設定要下載方式以及下載檔案的名字
        headers.add("Content-Disposition", "attachment;filename=ACC3.jpg");
        //設定響應狀態碼
        HttpStatus statusCode = HttpStatus.OK;
        //建立ResponseEntity物件
        ResponseEntity<byte[]> responseEntity = new ResponseEntity<byte[]>(bytes, headers, statusCode);
        //關閉輸入流
        is.close();
        return responseEntity;
    }
}

檔案不管是上傳還是下載,本質還是一個複製的過程。

既然要複製,那還是要先讀後寫,所以上面建立了輸入流,將流讀到位元組陣列中,然後把這個位元組陣列響應到瀏覽器,這就是要下載的檔案了。

所以,用到了 ResponseEntity,要把響應到瀏覽器的資料轉化成 ResponseEntity,最後返回。

重新部署測試一下,訪問 file 頁面,點選下載超連結。

下載成功。

上傳

在前端頁面 file.html 中繼續新增內容:

<form th:action="@{/testUp}" method="post" enctype="multipart/form-data">
    頭像:<input type="file" name="photo"><br>
    <input type="submit" value="上傳">
</form>

檔案上傳要求 form 表單的請求方式必須為 post,並且新增屬性 enctype="multipart/form-data"

新增依賴:

    <!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload -->
    <dependency>
        <groupId>commons-fileupload</groupId>
        <artifactId>commons-fileupload</artifactId>
        <version>1.3.1</version>
    </dependency>

SpringMVC 中將上傳的檔案封裝到MultipartFile物件中,通過此物件可以獲取檔案相關資訊。

在 springMVC 的配置檔案中新增配置:

<!--必須通過檔案解析器的解析才能將檔案轉換為MultipartFile物件-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"></bean>

增加控制器方法,實現上傳:

    @RequestMapping("/testUp")
    public String testUp(MultipartFile photo, HttpSession session) throws IOException {
        //獲取上傳的檔案的檔名
        String fileName = photo.getOriginalFilename();
        //處理檔案重名問題
        String hzName = fileName.substring(fileName.lastIndexOf("."));
        fileName = UUID.randomUUID().toString() + hzName;
        //獲取伺服器中 photo目錄的路徑
        ServletContext servletContext = session.getServletContext();
        String photoPath = servletContext.getRealPath("photo");
        File file = new File(photoPath);
        if(!file.exists()){
            file.mkdir(); // 不存在則建立目錄
        }
        String finalPath = photoPath + File.separator + fileName;
        //實現上傳功能
        photo.transferTo(new File(finalPath));
        return "success";
    }

注意,我們最終上傳的位置是在這裡,會自動建立一個 photo 目錄,裡面存放著上傳的圖片。

部署測試一下。

上傳請求處理成功,跳轉到了 success 頁。

再來看下目標位置,已經有了上傳過來的圖片了。

--不要用肉體的勤奮,去掩蓋思考的懶惰--