創建名為spring_mvc_file的新module,過程參考9.1節和9.5節 11.1、文件下載 11.1.1、創建圖片目錄並放置圖片 11.1.2、頁面請求示例 <a th:href="@{/test/down}">下載圖片</a> 11.1.3、控制器方法示例 package online ...
創建名為spring_mvc_file的新module,過程參考9.1節和9.5節
11.1、文件下載
11.1.1、創建圖片目錄並放置圖片
11.1.2、頁面請求示例
<a th:href="@{/test/down}">下載圖片</a>
11.1.3、控制器方法示例
package online.liaojy.controller;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpSession;
import java.io.*;
/**
* @author liaojy
* @date 2023/11/2 - 20:50
*/
@Controller
public class FileDownloadController {
// ResponseEntity 可以作為控制器方法的返回值,表示響應到瀏覽器的完整響應報文(包含響應體、響應體和響應狀態碼)
@RequestMapping("/test/down")
public ResponseEntity<byte[]> testResponseEntity(HttpSession session) throws IOException {
//獲取ServletContext對象
ServletContext servletContext = session.getServletContext();
//獲取伺服器中工程的真實路徑
String realPath = servletContext.getRealPath("");
//拼接工程路徑和文件路徑
//File.pathSeparator 表示文件路徑分隔符,其能自動適應不同系統的路徑分隔符(例如Windows的分隔符是\,Linux的分隔符是/)
realPath = realPath + File.separator + "img" + File.separator + "Windows.jpg";
//創建輸入流
InputStream is = new FileInputStream(realPath);
//創建位元組數組作為響應報文的響應體,is.available() 用於獲取輸入流所對應的文件的位元組數
byte[] bytes = new byte[is.available()];
//將流讀到位元組數組中
is.read(bytes);
//創建HttpHeaders對象設置響應頭信息
MultiValueMap<String, String> headers = new HttpHeaders();
//設置下載方式以及下載文件的名字
//請求頭的鍵不區分大小寫,Content Disposition頭用來強制瀏覽器下載文件,而不是在瀏覽器中顯示
//attachment表示以附件形式下載,即在下載時有提示信息
//filename表示下載的文件的名字
headers.add("Content-Disposition", "attachment;filename=Win10.jpg");
//設置響應狀態碼
HttpStatus statusCode = HttpStatus.OK;
//創建ResponseEntity對象
ResponseEntity<byte[]> responseEntity = new ResponseEntity<byte[]>(bytes, headers, statusCode);
//關閉輸入流
is.close();
return responseEntity;
}
}
11.1.4、測試效果
11.2、文件上傳
11.2.1、頁面請求示例
<!--
文件上傳要求form表單的請求方式必須為post
並且設置屬性enctype="multipart/form-data",表示表單中的數據以二進位的方式提交到伺服器中
enctype屬性值預設為application/x-www-form-urlencoded,傳輸不了文件
-->
<form th:action="@{/test/up}" method="post" enctype="multipart/form-data">
<!--
type屬性值為file
name屬性值要和控制器方法的形參一致
-->
圖片:<input type="file" name="photo">
<br>
<input type="submit" value="上傳圖片">
</form>
11.2.2、引入依賴
<!--文件上傳-->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
11.2.3、配置文件上傳解析器
註意:springmvc 根據bean的id來獲取文件解析器,因此必須設置 id 屬性,且屬性值必須為 multipartResolver
<!--配置文件解析器-->
<!--必須通過文件解析器的解析才能將文件轉換為 MultipartFile 對象-->
<!--文件解析器的id屬性值必須為 multipartResolver -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!--文件上傳最大值,預設值為 -1(表示沒有限制)-->
<!--<property name="maxUploadSize" value="-1"></property>-->
<!--解析請求的預設字元編碼,預設值為"ISO-8859-1",通常設置為"UTF-8"-->
<!--<property name="defaultEncoding" value="UTF-8"></property>-->
<!--存儲在記憶體的最大值,預設值為10240B(10KB)-->
<!--<property name="maxInMemorySize" value="10240"></property>-->
<!--每個文件上傳最大值,預設值為 -1(表示沒有限制)-->
<!--<property name="maxUploadSizePerFile" value="-1"></property>-->
<!--延遲解析,預設為false(立即解析)-->
<!--<property name="resolveLazily" value="false"></property>-->
<!--傳文件的臨時目錄,預設值為WEB應用程式的臨時目錄-->
<!--<property name="uploadTempDir" value="classpath:online"></property>-->
</bean>
11.2.4、控制器方法示例
package online.liaojy.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpSession;
import java.io.File;
import java.io.IOException;
/**
* @author liaojy
* @date 2023/11/5 - 18:06
*/
@Controller
public class FileUploadController {
@RequestMapping("/test/up")
public String testUp(MultipartFile photo, HttpSession session) throws IOException {
// 獲取上傳的文件的文件名
String originalFilename = photo.getOriginalFilename();
// 獲取ServletContext對象
ServletContext servletContext = session.getServletContext();
// 獲取伺服器中當前工程下photo目錄的真實路徑
String photoPath = servletContext.getRealPath("photo");
// 創建photoPath所對應的file對象
File file = new File(photoPath);
// 判斷file所對應目錄是否存在
if (!file.exists()){
// file所對應目錄不存在,則創建該目錄
file.mkdir();
}
// 拼接目錄路徑和文件名為最終路徑
String finalPath = photoPath + File.separator + originalFilename;
// 上傳文件
photo.transferTo(new File(finalPath));
return "success";
}
}
11.2.5、測試效果
11.3、文件上傳的重名問題
11.3.1、問題描述
如果上傳了同名的文件,那新的文件就會覆蓋舊的文件;
因此需要通過一個機制,保證上傳後的文件名的不會和新上傳的文件名重覆;
通常,可以使用uuid或時間戳,替換原來的文件名,從而保證文件名的唯一性。
11.3.2、解決方式
// 獲取上傳的文件的尾碼名
String suffixName = originalFilename.substring(originalFilename.lastIndexOf("."));
// 使用uuid生成的字元串和上傳文件的尾碼名,拼接成一個新的文件名
String fileName = UUID.randomUUID().toString() + suffixName;
// 拼接目錄路徑和新的文件名為最終路徑
String finalPath = photoPath + File.separator + fileName;
11.3.3、測試效果
本文來自博客園,作者:Javaer1995,轉載請註明原文鏈接:https://www.cnblogs.com/Javaer1995/p/17805710.html