🏇 小 木 來 了 \textcolor{Orange}{小木來了} 小木來了
🍣 圣 誕 樹 火 了 \textcolor{green}{圣誕樹火了} 圣誕樹火了, 但 怎 么 忘 了 文 件 上 傳 呢 \textcolor{red}{但怎么忘了檔案上傳呢} 但怎么忘了文件上傳呢🍣
🍣 我 可 以 將 許 多 的 圖 片 文 檔 等 都 可 以 進 行 上 傳 \textcolor{green}{我可以將許多的圖片檔案等都可以進行上傳} 我可以將許多的圖片文檔等都可以進行上傳 但 這 豈 不 更 爽 \textcolor{red}{但這豈不更爽} 但這豈不更爽🍣
🙏 博 主 也 在 學 習 階 段 , 如 若 發 現 問 題 , 請 告 知 , 非 常 感 謝 \textcolor{Orange}{博主也在學習階段,如若發現問題,請告知,非常感謝} 博主也在學習階段,如若發現問題,請告知,非常感謝💗
歡迎各位小伙伴😄關注👍點贊??收藏📝留言
檔案上傳和下載
- 1. 檔案傳輸原理及介紹
- 2. JavaWeb檔案上傳
- 2.1我們用一個新的方式創建專案
- 2.2 導包
- 2.3 實用類介紹
- FileItem類
- ServletFileUpload類
- 2.4 pom.xml匯入需要的依賴
- 2.5 index.jsp
- 2.6 info.jsp
- 2.7 FileServlet
- 2.8 配置Servlet
- 2.9 測驗結果
- 3. SpringMVC檔案上傳和下載
- 3.1 上傳
- 3.2 下載
1. 檔案傳輸原理及介紹

2. JavaWeb檔案上傳
2.1我們用一個新的方式創建專案


空專案會直接彈出框

把jdk版本設定好

點擊確定后是比較干凈的,啥都不會,不要慌,點擊file->new->module,之后就和之前做過的一樣了

創建model:file,配置tomcat運行保證沒有錯誤
2.2 導包
可以選擇去maven倉庫中下,也可以在官網上搜出來然后復制到專案中,我們創建一個檔案夾lib,然后如果從外面復制到專案中需要右鍵點擊add as library添加到內庫中


- 上述只是講一個新建專案的方式,我后面還是按照之前的用maven進行了一個專案完成
2.3 實用類介紹
- 檔案上傳的注意事項
- 為保證服務器安全,上傳檔案應該放在外界無法直接訪問的目錄下,比如放在WEB-INF目錄下,
- 為防止檔案覆寫的現象發生,要為上傳檔案產生一個唯一的檔案名,
- 加一個時間戳
- UUID
- md5
- 自己寫位運算演算法
- 要限制上傳檔案的最大值
- 可以限制上傳檔案的型別,在收到上傳檔案名時,判斷后綴名是否合法,
需要用到的類詳解
ServletFileUpload負責處理上傳的檔案資料,并將表單中每個輸入項封賬成一個fileItem物件,在使用ServletFileUpload物件決議請求時需要DiskFileItemFactory物件,所以,我們需要在進行決議作業前構造好DiskFileItemFactory物件,通過ServletFileUpload物件的構造方法或setFileItemFactory()方法設定ServletFileUpload物件的fileItemFactory屬性,
FileItem類
在HTML頁面input必須有
<input type="file" name = "filename">
表單中如果包含一個檔案上傳輸入項的話,這個表單的enctype屬性就必須設定為multipart/form-data
- 常用方法介紹
//isFromField方法用于判斷FileItem類物件封裝的資料是一個普通文本表單還是一個檔案表單,如果是普通表單就回傳true,否則回傳false
boolean isFormField();
//getFieldName方法用于回傳表單標簽name屬性的值
String getFieldName();
//getString方法用于將FileItem物件中保存的資料流內容以一個字串回傳
String getString();
//getName方法用于獲得檔案上傳欄位中的檔案名
String getName();
//以流的形式回傳上傳檔案的資料內容
InputStream getInputStream();
//delete方法用來清空FileItem類物件中存放的主體內容,如果主題內容被保存在臨時檔案中,delete方法將洗掉該臨時檔案
void delete();
ServletFileUpload類
ServletFileUpload負責處理上傳的檔案資料,并將表單中每個輸入項封裝成一個FileItem物件中,使用其parseRequest(HttpServletRequest)方法可以將通過表單中每一個HTML標簽提交的資料封裝成一個FIleItem物件,然后以list串列的形式回傳,使用該方法處理上傳檔案簡單易用
2.4 pom.xml匯入需要的依賴
<!--Servlet 依賴-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
</dependency>
<!--JSP依賴-->
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>javax.servlet.jsp-api</artifactId>
<version>2.3.3</version>
</dependency>
<!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.4</version>
</dependency>
<!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
</dependency>
2.5 index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>$Title$</title>
</head>
<body>
<%--通過表單上傳檔案;
get:上傳檔案大小有限制
post:上傳檔案大小沒有限制
${pageContext.request.contextPath}獲取服務器當前路徑
--%>
<form action="${pageContext.request.contextPath}/upload.do" enctype="multipart/form-data" method="post">
上傳用戶:<input type="text" name="username"><br/>
<p><input type="file" name="file1"></p>
<p><input type="file" name="file1"></p>
<p><input type="submit"> | <input type="reset"></p>
</form>
</body>
</html>
2.6 info.jsp
該頁面主要用于接受message
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%=request.getAttribute("msg")%>
</body>
</html>
2.7 FileServlet
這里的包一定要注意不要導錯了,另外這里使用了封裝的方法讓結構看起來更簡潔
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.ProgressListener;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.List;
import java.util.UUID;
public class FileServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//判斷上傳的檔案是普通表單還是帶檔案的表單
if (!ServletFileUpload.isMultipartContent(req)) {
return;//終止方法運行,說明這是一個普通的表單
}
//創建上傳檔案的保存路徑,建議在WEB-INF路徑下,安全,用戶無法直接訪問上傳的檔案
//獲得全域的背景關系,地址
String uploadPath = this.getServletContext().getRealPath("/WEB-INF/upload");
File uploadFile = new File(uploadPath);
if (!uploadFile.exists()) {
uploadFile.mkdir();//創建這個目錄
}
//快取,臨時檔案
//臨時檔案,假如檔案超過了預期的大小,我們就把他放到一個臨時檔案中,過幾天激動洗掉,或者提醒用戶轉存為永久
String tmpPath = this.getServletContext().getRealPath("/WEB-INF/tmp");
File tmpFile = new File(tmpPath);
if (!tmpFile.exists()) {
tmpFile.mkdir();//創建這個目錄
}
//處理上傳的檔案,一般需要通過流來獲取,我們可以使用request.getInputStream(),原生態的檔案上傳流獲取,
//上面的太麻煩,建議使用APache的檔案上傳組件來實作,common-fileupload,它需要依賴于commons-io組件
try {
//1.創建DiskFileItemFactory物件,處理檔案上傳路徑或者大小限制的
DiskFileItemFactory factory = getDiskFileItemFactory(tmpFile);
//2.獲取ServletFileUpload
ServletFileUpload upload = getServletFileUpload(factory);
//3.處理上傳檔案
String msg = uploadParseRequest(upload, req, uploadPath);
//servlet請求轉發訊息
req.setAttribute("msg", msg);
req.getRequestDispatcher("info.jsp").forward(req, resp);
} catch (FileUploadException e) {
e.printStackTrace();
}
}
public static DiskFileItemFactory getDiskFileItemFactory(File tmpFile) {
DiskFileItemFactory factory = new DiskFileItemFactory();
//通過這個工廠設定一個緩沖區,當上傳的檔案大于這個緩沖區的時候,將他放到臨時檔案中
//可以設可以不設
factory.setSizeThreshold(1024 * 1024);
factory.setRepository(tmpFile);
return factory;
}
public static ServletFileUpload getServletFileUpload(DiskFileItemFactory factory) {
//2.獲取ServletFileUpload
ServletFileUpload upload = new ServletFileUpload(factory);
//可以設,可以不設
//監聽檔案上傳進度
upload.setProgressListener(new ProgressListener() {
//pContentLength:檔案大小
//pBytesRead:已經讀取到的檔案大小
@Override
public void update(long pBytesRead, long pContentLength, int pItems) {
System.out.println("總大小:" + pContentLength + "已上傳" + pBytesRead);
}
});
//處理亂碼問題
upload.setHeaderEncoding("UTF-8");
//設定單個檔案的最大值
upload.setFileSizeMax(1024 * 1024 * 10);
//設定總共能夠上傳的檔案的大小
//1024 = 1kb * 1024 = 1M * 10 = 10M
upload.setSizeMax(1024 * 1024 * 10);
return upload;
}
public static String uploadParseRequest(ServletFileUpload upload, HttpServletRequest req, String uploadPath) throws FileUploadException, IOException {
String msg = "";
//3.處理上傳檔案
//把前端請求決議,封裝成一個FileItem物件,需要從ServletFileUpload物件中獲取
List<FileItem> fileItems = upload.parseRequest(req);
//每一個表單物件
for (FileItem fileItem : fileItems) {
//判斷上傳的檔案是普通的表單還是帶檔案的表單
if (fileItem.isFormField()) {
//getFieldName()指的是前端表單控制元件的name
String name = fileItem.getFieldName();
String value = fileItem.getString("UTF-8");//處理亂碼
System.out.println(name + ":" + value);
} else { //檔案的情況
//=====處理檔案
//拿到檔案名字
String uploadFileName = fileItem.getName();
System.out.println("上傳的檔案名:" + uploadFileName);
if (uploadFileName.trim().equals("") || uploadFileName == null) {
continue;
}
//獲得檔案上傳的檔案名和后綴名;/images/boys/dajie.jpg 下面這塊不是必須的
String fileName = uploadFileName.substring(uploadFileName.lastIndexOf("/") + 1);
String fileExtName = uploadFileName.substring(uploadFileName.lastIndexOf(".") + 1);
//如果檔案后綴名fileExtName不是我們所需要的就直接return,不處理,告訴用戶檔案型別不對
System.out.println("檔案資訊【件名:" + fileName + "---檔案型別" + fileExtName + "】");
//可以使用UUID(唯一識別的通用碼),保證檔案名唯一
//UUID.randomUUID(),隨機生成一個唯一識別的通用碼
//網路傳輸中的東西,都需要序列化,
//比如:POJO,物體類,如果想要在多個電腦上運行,需要進行傳輸===>需要把物件序列化
//implements Serializable :標記介面,JVM--> java堆疊 本地方法堆疊 ; native---》C++
String uuidPath = UUID.randomUUID().toString();
//===處理檔案結束
//=====存放地址
//存到哪?uploadPath
//檔案真實存在的路徑realPath
String realPath = uploadPath + "/" + uuidPath;
//給每個檔案創建一個對應的檔案夾
File realPathFile = new File(realPath);
if (!realPathFile.exists()) {
realPathFile.mkdir();
}
//=====存放地址完畢
//=====檔案傳輸
//獲得檔案上傳的流
InputStream inputStream = fileItem.getInputStream();
//創建一個檔案輸出流
//realPath = 真實的檔案夾
//差了一個檔案,加上輸出的檔案的名字+"/" +uuidFileName
FileOutputStream fos = new FileOutputStream(realPath + "/" + fileName);
//創建一個緩沖區
byte[] buffer = new byte[1024 * 1024];
//判斷是否讀取完畢
int len = 0;
//如果大于0說明還存在資料
while ((len = inputStream.read(buffer)) > 0) {
fos.write(buffer, 0, len);
}
//關閉流
fos.close();
inputStream.close();
msg = "檔案上傳成功!";
fileItem.delete();//上傳成功,清楚臨時檔案
}
}
return msg;
}
}
2.8 配置Servlet
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<servlet>
<servlet-name>FileServlet</servlet-name>
<servlet-class>com.hxl.servlet.FileServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>FileServlet</servlet-name>
<url-pattern>/upload.do</url-pattern>
</servlet-mapping>
</web-app>
2.9 測驗結果



3. SpringMVC檔案上傳和下載
3.1 上傳
在controller中有兩種方式
新建一個module,一套流程整體下來,測驗能運行即可
? ? > 導 入 j a r 包 \textcolor{OrangeRed}{--> 匯入jar包} ??>導入jar包💻
<!--檔案上傳-->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.3</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
</dependency>
? ? > i n d e x . j s p \textcolor{OrangeRed}{--> index.jsp} ??>index.jsp💻
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>檔案上傳和下載</title>
</head>
<body>
<form action="${pageContext.request.contextPath}/upload" enctype="multipart/form-data" method="post">
<input type="file" name="file"/>
<input type="submit" value="upload">
</form>
</body>
</html>
? ? > a p p l i c a t i o n C o n t e x t . x m l 中 配 置 b e a n \textcolor{OrangeRed}{--> applicationContext.xml中配置bean} ??>applicationContext.xml中配置bean💻
<!--檔案上傳配置-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- 請求的編碼格式,必須和jSP的pageEncoding屬性一致,以便正確讀取表單的內容,默認為ISO-8859-1 -->
<property name="defaultEncoding" value="utf-8"/>
<!-- 上傳檔案大小上限,單位為位元組(10485760=10M) -->
<property name="maxUploadSize" value="10485760"/>
<property name="maxInMemorySize" value="40960"/>
</bean>
? ? > F i l e C o n t r o l l e r \textcolor{OrangeRed}{--> FileController} ??>FileController💻
package com.hxl.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.commons.CommonsMultipartFile;
import javax.servlet.http.HttpServletRequest;
import java.io.*;
@RestController
public class FileController {
//@RequestParam("file") 將name=file控制元件得到的檔案封裝成CommonsMultipartFile 物件
//批量上傳CommonsMultipartFile則為陣列即可
@RequestMapping("/upload")
public String fileUpload(@RequestParam("file") CommonsMultipartFile file , HttpServletRequest request) throws IOException {
//獲取檔案名 : file.getOriginalFilename();
String uploadFileName = file.getOriginalFilename();
//如果檔案名為空,直接回到首頁!
if ("".equals(uploadFileName)){
return "redirect:/index.jsp";
}
System.out.println("上傳檔案名 : "+uploadFileName);
//上傳路徑保存設定
String path = request.getServletContext().getRealPath("/upload");
//如果路徑不存在,創建一個
File realPath = new File(path);
if (!realPath.exists()){
realPath.mkdir();
}
System.out.println("上傳檔案保存地址:"+realPath);
InputStream is = file.getInputStream(); //檔案輸入流
OutputStream os = new FileOutputStream(new File(realPath,uploadFileName)); //檔案輸出流
//讀取寫出
int len=0;
byte[] buffer = new byte[1024];
while ((len=is.read(buffer))!=-1){
os.write(buffer,0,len);
os.flush();
}
os.close();
is.close();
return "redirect:/index.jsp";
}
/*
* 采用file.Transto 來保存上傳的檔案
*/
@RequestMapping("/upload2")
public String fileUpload2(@RequestParam("file") CommonsMultipartFile file, HttpServletRequest request) throws IOException {
//上傳路徑保存設定
String path = request.getServletContext().getRealPath("/upload");
File realPath = new File(path);
if (!realPath.exists()){
realPath.mkdir();
}
//上傳檔案地址
System.out.println("上傳檔案保存地址:"+realPath);
//通過CommonsMultipartFile的方法直接寫檔案(注意這個時候)
file.transferTo(new File(realPath +"/"+ file.getOriginalFilename()));
return "redirect:/index.jsp";
}
}
? ? > 測 試 : \textcolor{OrangeRed}{--> 測驗:} ??>測試:💻


3.2 下載
1、設定 response 回應頭
2、讀取檔案 – InputStream
3、寫出檔案 – OutputStream
4、執行操作
5、關閉流 (先開后關)
? ? > i n d e x . j s p \textcolor{OrangeRed}{--> index.jsp} ??>index.jsp💻
<a href="${pageContext.request.contextPath}/download">點擊下載</a>
? ? > 增 加 一 個 u p l o a d 文 件 \textcolor{OrangeRed}{-->增加一個upload檔案} ??>增加一個upload文件💻
并且把要下載的圖片弄進去

? ? > c o n t r o l l e r \textcolor{OrangeRed}{-->controller} ??>controller💻
@RequestMapping(value="/download")
public String downloads(HttpServletResponse response , HttpServletRequest request) throws Exception{
//要下載的圖片地址
String path = request.getServletContext().getRealPath("/upload");
//String fileName = "你想要下載的檔案,要加上后綴";
String fileName = "1.jpg";
//1、設定response 回應頭
response.reset(); //設定頁面不快取,清空buffer
response.setCharacterEncoding("UTF-8"); //字符編碼
response.setContentType("multipart/form-data"); //二進制傳輸資料
//設定回應頭
response.setHeader("Content-Disposition",
"attachment;fileName="+ URLEncoder.encode(fileName, "UTF-8"));
File file = new File(path,fileName);
//2、 讀取檔案--輸入流
InputStream input=new FileInputStream(file);
//3、 寫出檔案--輸出流
OutputStream out = response.getOutputStream();
byte[] buff =new byte[1024];
int index=0;
//4、執行 寫出操作
while((index= input.read(buff))!= -1){
out.write(buff, 0, index);
out.flush();
}
out.close();
input.close();
return "ok";
}
? ? > 測 試 : \textcolor{OrangeRed}{-->測驗:} ??>測試:💻

轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/390402.html
標籤:其他
上一篇:【歷史上的今天】12 月 22 日:世界上第一封電子郵件發出;我國研制億次計算機;第一臺可編程計算機的發明者出生
