文件上傳下載步驟
JavaWeb項目
1. 導包
導入commons-io
和commons-fileupload
jar包
2. 前端頁面
action:頁面請求,需和web.xml
中匹配
method:設置為post
,沒有文件大小限制
enctype:值為multipart/form-data
用於識別是否為文件表單還是普通文本表單
<form action="${pageContext.request.contextPath}/upload.do" enctype="multipart/form-data" method="post">
<input type="file" name="file1">
<br>
<input type="file" name="file2">
<br>
<input type="submit">
<br>
</form>
3. 注冊web.xml
<servlet>
<servlet-name>FileUploadServlet</servlet-name>
<servlet-class>com.juyss.servlet.FileUploadServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>FileUploadServlet</servlet-name>
<url-pattern>/upload.do</url-pattern>
</servlet-mapping>
4. 編寫Servlet
實現步驟
-
判斷表單為普通文本表單還是文件表單
-
創建上傳文件的保存根路徑
-
創建臨時文件的保存根路徑
-
獲取
FileItem
對象 需要
ServletFileUpload
對象 需要用到
DiskFileItemFactory
對象,用於處理上傳路徑和限制文件大小 -
通過
FileItem
對象獲取文件名,文件后綴 -
使用UUID創建唯一保存路徑
-
使用
fileItem.getInputStream()
獲取文件輸入流 -
創建文件輸出流
FileOutputStream fos = new FileOutputStream(savePath + "/" + fileName)
-
關閉流資源,同時刪除臨時文件
fileItem.delete()
public class FileUploadServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("進入了FileUploadServlet.class");
//判斷表單是否為帶有文件的表單
if (!ServletFileUpload.isMultipartContent(request)) {
return; //終止方法運行
}
//定義文件上傳后保存的根路徑
String rootPath = this.getServletContext().getRealPath("/WEB-INF/upload");
File rootFile = new File(rootPath);
if (!rootFile.exists()) {
rootFile.mkdir();
}
//定義文件緩存路徑
String tempPath = this.getServletContext().getRealPath("/WEB-INF/temp");
File tempFile = new File(tempPath);
if (!tempFile.exists()) {
tempFile.mkdir();
}
//創建DiskFileItemFactory對象,處理上傳路徑和限制文件大小
DiskFileItemFactory fileItemFactory = new DiskFileItemFactory(1024 * 1024, tempFile);
//創建ServletFileUpload對象
ServletFileUpload servletFileUpload = new ServletFileUpload(fileItemFactory);
//獲取FileItem對象
List<FileItem> fileItems = null;
try {
fileItems = servletFileUpload.parseRequest(request);
} catch (FileUploadException e) {
e.printStackTrace();
}
if (fileItems==null){
System.out.println("fileItem空指針");
return;
}
Iterator<FileItem> iterator = fileItems.iterator();
//遍歷fileItems集合
while (iterator.hasNext()) {
FileItem fileItem = iterator.next();
if (fileItem.isFormField()) {//是普通文本表單
continue; //跳出循環
} else {//是文件表單
//獲取文件字段名,標簽中name屬性的值
String fieldName = fileItem.getFieldName();
//獲取文件上傳字段中的文件名,一般來說為為文件名(不包含路徑信息),在opera瀏覽器中可能會包含文件路徑信息
String name = fileItem.getName();
System.out.println("文件字段名:"+fieldName);
System.out.println("文件名:"+name);
//判斷文件名是否合法
if (name.trim().equals("") || name == null) {
continue;
}
//獲取文件名和文件后綴
String fileName; //文件名
if (name.contains("/")){ //判斷name是否包含路徑信息
fileName = name.substring(name.lastIndexOf("/"));
}else{
fileName = name;
}
String fileExtension = fileName.substring(fileName.indexOf(".") + 1);//獲取文件后綴
System.out.println("文件名:" + fileName);
System.out.println("文件類型:" + fileExtension);
//獲取隨機UUID
String uuid = UUID.randomUUID().toString();
//使用uuid創建唯一的文件夾作為文件存放路徑
String savePath = rootPath + "/" + uuid; //文件存放路徑
File savePathFile = new File(savePath);
if (!savePathFile.exists()) { //路徑不存在就創建
savePathFile.mkdir();
}
//獲取輸入流讀取上傳的文件
InputStream is = fileItem.getInputStream();
//用輸出流保存到本地
FileOutputStream fos = new FileOutputStream(savePath + "/" + fileName);
int len;
byte[] bytes = new byte[1024 * 1024];
while((len = is.read(bytes))!=-1){
fos.write(bytes,0,len);
}
fos.close();
is.close();
//刪除臨時文件
fileItem.delete();
}
}
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
SpringBoot項目
文件上傳
1. 引入web支持和模板引擎
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
2. 編寫控制器
@RestController
@RequestMapping("/file")
public class FileController {
/**
* 文件上傳控制器
* @param file 上傳的文件
* @return 上傳信息
*/
@RequestMapping("/upload")
public String upload(MultipartFile file){ //變量名需要與前端頁面的file類型的name值一致
//判斷傳入文件是否為空
if (file == null || file.isEmpty()) {
return "未選擇需上傳的文件";
}
//定義文件保存位置(絕對路徑)
String filePath = new File("D:\\WorkSpace\\Demo-Project\\atguigu-Advanced\\fileupload\\src\\main\\resources\\upload").getPath();
//判斷文件路徑是否存在,不存在就創建路徑
File fileUpload = new File(filePath);
if (!fileUpload.exists()) {
fileUpload.mkdirs();
}
//創建文件對象,指定文件保存路徑和文件名
fileUpload = new File(filePath, Objects.requireNonNull(file.getOriginalFilename()));
//判斷是否存在同名文件
if (fileUpload.exists()) {
return "上傳的文件已存在";
}
//保存文件
try {
file.transferTo(fileUpload);
} catch (IOException e) {
e.printStackTrace();
return "上傳到服務器失敗";
}
//返回信息
return file.getOriginalFilename()+"文件上傳成功";
}
}
3. 前端頁面
<!DOCTYPE html>
<html lang="ch" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>FileUpload Test</title>
</head>
<body>
<h3>文件上傳</h3>
<form action="" th:action="@{/file/upload}" enctype="multipart/form-data" method="post">
<input type="file" name="file"><br>
<input type="submit" value="上傳">
</form>
</body>
</html>
文件下載
1. 前端頁面
<h3>文件下載</h3>
<a href="" th:href="@{/file/download/01.jpg}">01.jpg</a>
<a href="" th:href="@{/file/download/02.png}">02.png</a>
2. 編寫控制器
package com.juyss.controller;
import org.apache.tomcat.util.http.fileupload.IOUtils;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.Objects;
/**
* @author ShmeBluk
* @version 1.0
* @ClassName: FileController
* @Desc: 文件上傳和下載
* @package com.juyss.controller
* @project atguigu-Advanced
* @date 2020/12/8 19:37
*/
@RestController
@RequestMapping("/file")
public class FileController {
/**
* 文件下載控制器
* @param fileName 要下載的文件名
* @param request 請求
* @param response 響應
* @return 返回響應信息
*/
@RequestMapping("/download/{fileName}")
public String download(@PathVariable("fileName") String fileName, HttpServletRequest request, HttpServletResponse response){
//獲取下載文件路徑
//String realPath = request.getServletContext().getRealPath("/download"); //相對路徑
String realPath = "D:\\WorkSpace\\Demo-Project\\atguigu-Advanced\\fileupload\\src\\main\\resources\\download"; //絕對路徑
//創建文件抽象類
File file = new File(realPath,fileName);
//判斷文件是否存在
if(!file.exists()){
return "文件不存在";
}
//從服務器通過文件輸入流讀入文件,然后通過文件輸出流由Response寫出給瀏覽器
FileInputStream is = null;
ServletOutputStream os = null;
try {
is = new FileInputStream(file);
//設置響應頭信息
response.setHeader("content-disposition", "attachment:fileName="+ URLEncoder.encode(fileName, "UTF-8"));
os = response.getOutputStream();
//IO工具類復制操作
IOUtils.copy(is, os);
} catch (IOException e) {
e.printStackTrace();
return "文件下載錯誤";
} finally {
//關閉資源
IOUtils.closeQuietly(is);
IOUtils.closeQuietly(os);
}
return "下載成功!!!";
}
}