版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認(rèn)領(lǐng)
文檔簡介
第詳解JavaWeb如何實現(xiàn)文件上傳和下載功能目錄1.文件傳輸原理及介紹2.JavaWeb文件上傳2.1我們用一個新的方式創(chuàng)建項目2.2導(dǎo)包2.3實用類介紹2.4pom.xml導(dǎo)入需要的依賴2.5index.jsp2.6info.jsp2.7FileServlet2.8配置Servlet2.9測試結(jié)果3.SpringMVC文件上傳和下載3.1上傳3.2下載
1.文件傳輸原理及介紹
2.JavaWeb文件上傳
2.1我們用一個新的方式創(chuàng)建項目
空項目會直接彈出框
把jdk版本設(shè)置好
點擊確定后是比較干凈的,啥都不會,不要慌,點擊file-new-module。之后就和之前做過的一樣了
創(chuàng)建model:file,配置tomcat運行保證沒有錯誤
2.2導(dǎo)包
可以選擇去maven倉庫中下,也可以在官網(wǎng)上搜出來然后復(fù)制到項目中,我們創(chuàng)建一個文件夾lib,然后如果從外面復(fù)制到項目中需要右鍵點擊addaslibrary添加到內(nèi)庫中
上述只是講一個新建項目的方式,我后面還是按照之前的用maven進行了一個項目完成
2.3實用類介紹
文件上傳的注意事項
1.為保證服務(wù)器安全,上傳文件應(yīng)該放在外界無法直接訪問的目錄下,比如放在WEB-INF目錄下。
2.為防止文件覆蓋的現(xiàn)象發(fā)生,要為上傳文件產(chǎn)生一個唯一的文件名,
加一個時間戳
UUID
自己寫位運算算法
3.要限制上傳文件的最大值
4.可以限制上傳文件的類型,在收到上傳文件名時,判斷后綴名是否合法。
需要用到的類詳解
ServletFileUpload負(fù)責(zé)處理上傳的文件數(shù)據(jù),并將表單中每個輸入項封賬成一個fileItem對象,在使用ServletFileUpload對象解析請求時需要DiskFileItemFactory對象。所以,我們需要在進行解析工作前構(gòu)造好DiskFileItemFactory對象,通過ServletFileUpload對象的構(gòu)造方法或setFileItemFactory()方法設(shè)置ServletFileUpload對象的fileItemFactory屬性。
FileItem類
在HTML頁面input必須有
inputtype="file"name="filename"
表單中如果包含一個文件上傳輸入項的話,這個表單的enctype屬性就必須設(shè)置為multipart/form-data
常用方法介紹
//isFromField方法用于判斷FileItem類對象封裝的數(shù)據(jù)是一個普通文本表單還是一個文件表單,如果是普通表單就返回true,否則返回false
booleanisFormField();
//getFieldName方法用于返回表單標(biāo)簽name屬性的值
StringgetFieldName();
//getString方法用于將FileItem對象中保存的數(shù)據(jù)流內(nèi)容以一個字符串返回
StringgetString();
//getName方法用于獲得文件上傳字段中的文件名
StringgetName();
//以流的形式返回上傳文件的數(shù)據(jù)內(nèi)容
InputStreamgetInputStream();
//delete方法用來清空FileItem類對象中存放的主體內(nèi)容。如果主題內(nèi)容被保存在臨時文件中,delete方法將刪除該臨時文件
voiddelete();
ServletFileUpload類
ServletFileUpload負(fù)責(zé)處理上傳的文件數(shù)據(jù),并將表單中每個輸入項封裝成一個FileItem對象中,使用其parseRequest(HttpServletRequest)方法可以將通過表單中每一個HTML標(biāo)簽提交的數(shù)據(jù)封裝成一個FIleItem對象,然后以list列表的形式返回。使用該方法處理上傳文件簡單易用
2.4pom.xml導(dǎo)入需要的依賴
!--Servlet依賴--
dependency
groupIdjavax.servlet/groupId
artifactIdjavax.servlet-api/artifactId
version4.0.1/version
/dependency
!--JSP依賴--
dependency
groupIdjavax.servlet.jsp/groupId
artifactIdjavax.servlet.jsp-api/artifactId
version2.3.3/version
/dependency
!--/artifact/commons-fileupload/commons-fileupload--
dependency
groupIdcommons-fileupload/groupId
artifactIdcommons-fileupload/artifactId
version1.4/version
/dependency
!--/artifact/commons-io/commons-io--
dependency
groupIdcommons-io/groupId
artifactIdcommons-io/artifactId
version2.6/version
/dependency
2.5index.jsp
%@pagecontentType="text/html;charset=UTF-8"language="java"%
html
head
title$Title$/title
/head
body
%--通過表單上傳文件;
get:上傳文件大小有限制
post:上傳文件大小沒有限制
${pageContext.request.contextPath}獲取服務(wù)器當(dāng)前路徑
formaction="${pageContext.request.contextPath}/upload.do"enctype="multipart/form-data"method="post"
上傳用戶:inputtype="text"name="username"br/
pinputtype="file"name="file1"/p
pinputtype="file"name="file1"/p
pinputtype="submit"|inputtype="reset"/p
/form
/body
/html
2.6info.jsp
該頁面主要用于接受message
%@pagecontentType="text/html;charset=UTF-8"language="java"%
html
head
titleTitle/title
/head
body
%=request.getAttribute("msg")%
/body
/html
2.7FileServlet
這里的包一定要注意不要導(dǎo)錯了。另外這里使用了封裝的方法讓結(jié)構(gòu)看起來更簡潔
importmons.fileupload.FileItem;
importmons.fileupload.FileUploadException;
importmons.fileupload.ProgressListener;
importmons.fileupload.disk.DiskFileItemFactory;
importmons.fileupload.servlet.ServletFileUpload;
importjavax.servlet.ServletException;
importjavax.servlet.http.HttpServlet;
importjavax.servlet.http.HttpServletRequest;
importjavax.servlet.http.HttpServletResponse;
importjava.io.*;
importjava.util.List;
importjava.util.UUID;
publicclassFileServletextendsHttpServlet{
@Override
protectedvoiddoGet(HttpServletRequestreq,HttpServletResponseresp)throwsServletException,IOException{
doPost(req,resp);
@Override
protectedvoiddoPost(HttpServletRequestreq,HttpServletResponseresp)throwsServletException,IOException{
//判斷上傳的文件是普通表單還是帶文件的表單
if(!ServletFileUpload.isMultipartContent(req)){
return;//終止方法運行,說明這是一個普通的表單
//創(chuàng)建上傳文件的保存路徑,建議在WEB-INF路徑下,安全,用戶無法直接訪問上傳的文件
//獲得全局的上下文,地址
StringuploadPath=this.getServletContext().getRealPath("/WEB-INF/upload");
FileuploadFile=newFile(uploadPath);
if(!uploadFile.exists()){
uploadFile.mkdir();//創(chuàng)建這個目錄
//緩存,臨時文件
//臨時文件,假如文件超過了預(yù)期的大小,我們就把他放到一個臨時文件中,過幾天激動刪除,或者提醒用戶轉(zhuǎn)存為永久
StringtmpPath=this.getServletContext().getRealPath("/WEB-INF/tmp");
FiletmpFile=newFile(tmpPath);
if(!tmpFile.exists()){
tmpFile.mkdir();//創(chuàng)建這個目錄
//處理上傳的文件,一般需要通過流來獲取,我們可以使用request.getInputStream(),原生態(tài)的文件上傳流獲取,
//上面的太麻煩,建議使用APache的文件上傳組件來實現(xiàn),common-fileupload,它需要依賴于commons-io組件
try{
//1.創(chuàng)建DiskFileItemFactory對象,處理文件上傳路徑或者大小限制的
DiskFileItemFactoryfactory=getDiskFileItemFactory(tmpFile);
//2.獲取ServletFileUpload
ServletFileUploadupload=getServletFileUpload(factory);
//3.處理上傳文件
Stringmsg=uploadParseRequest(upload,req,uploadPath);
//servlet請求轉(zhuǎn)發(fā)消息
req.setAttribute("msg",msg);
req.getRequestDispatcher("info.jsp").forward(req,resp);
}catch(FileUploadExceptione){
e.printStackTrace();
publicstaticDiskFileItemFactorygetDiskFileItemFactory(FiletmpFile){
DiskFileItemFactoryfactory=newDiskFileItemFactory();
//通過這個工廠設(shè)置一個緩沖區(qū),當(dāng)上傳的文件大于這個緩沖區(qū)的時候,將他放到臨時文件中
//可以設(shè)可以不設(shè)
factory.setSizeThreshold(1024*1024);
factory.setRepository(tmpFile);
returnfactory;
publicstaticServletFileUploadgetServletFileUpload(DiskFileItemFactoryfactory){
//2.獲取ServletFileUpload
ServletFileUploadupload=newServletFileUpload(factory);
//可以設(shè),可以不設(shè)
//監(jiān)聽文件上傳進度
upload.setProgressListener(newProgressListener(){
//pContentLength:文件大小
//pBytesRead:已經(jīng)讀取到的文件大小
@Override
publicvoidupdate(longpBytesRead,longpContentLength,intpItems){
System.out.println("總大小:"+pContentLength+"已上傳"+pBytesRead);
//處理亂碼問題
upload.setHeaderEncoding("UTF-8");
//設(shè)置單個文件的最大值
upload.setFileSizeMax(1024*1024*10);
//設(shè)置總共能夠上傳的文件的大小
//1024=1kb*1024=1M*10=10M
upload.setSizeMax(1024*1024*10);
returnupload;
publicstaticStringuploadParseRequest(ServletFileUploadupload,HttpServletRequestreq,StringuploadPath)throwsFileUploadException,IOException{
Stringmsg="";
//3.處理上傳文件
//把前端請求解析,封裝成一個FileItem對象,需要從ServletFileUpload對象中獲取
ListFileItemfileItems=upload.parseRequest(req);
//每一個表單對象
for(FileItemfileItem:fileItems){
//判斷上傳的文件是普通的表單還是帶文件的表單
if(fileItem.isFormField()){
//getFieldName()指的是前端表單控件的name
Stringname=fileItem.getFieldName();
Stringvalue=fileItem.getString("UTF-8");//處理亂碼
System.out.println(name+":"+value);
}else{//文件的情況
//=====處理文件
//拿到文件名字
StringuploadFileName=fileItem.getName();
System.out.println("上傳的文件名:"+uploadFileName);
if(uploadFileName.trim().equals("")||uploadFileName==null){
continue;
//獲得文件上傳的文件名和后綴名;/images/boys/dajie.jpg下面這塊不是必須的
StringfileName=uploadFileName.substring(uploadFileName.lastIndexOf("/")+1);
StringfileExtName=uploadFileName.substring(uploadFileName.lastIndexOf(".")+1);
//如果文件后綴名fileExtName不是我們所需要的就直接return,不處理,告訴用戶文件類型不對
System.out.println("文件信息");
//可以使用UUID(唯一識別的通用碼),保證文件名唯一
//UUID.randomUUID(),隨機生成一個唯一識別的通用碼
//網(wǎng)絡(luò)傳輸中的東西,都需要序列化,
//比如:POJO,實體類,如果想要在多個電腦上運行,需要進行傳輸===需要把對象序列化
//implementsSerializable:標(biāo)記接口,JVM--java棧本地方法棧;native》C++
StringuuidPath=UUID.randomUUID().toString();
//===處理文件結(jié)束
//=====存放地址
//存到哪?uploadPath
//文件真實存在的路徑realPath
StringrealPath=uploadPath+"/"+uuidPath;
//給每個文件創(chuàng)建一個對應(yīng)的文件夾
FilerealPathFile=newFile(realPath);
if(!realPathFile.exists()){
realPathFile.mkdir();
//=====存放地址完畢
//=====文件傳輸
//獲得文件上傳的流
InputStreaminputStream=fileItem.getInputStream();
//創(chuàng)建一個文件輸出流
//realPath=真實的文件夾
//差了一個文件,加上輸出的文件的名字+"/"+uuidFileName
FileOutputStreamfos=newFileOutputStream(realPath+"/"+fileName);
//創(chuàng)建一個緩沖區(qū)
byte[]buffer=newbyte[1024*1024];
//判斷是否讀取完畢
intlen=0;
//如果大于0說明還存在數(shù)據(jù)
while((len=inputStream.read(buffer))0){
fos.write(buffer,0,len);
//關(guān)閉流
fos.close();
inputStream.close();
msg="文件上傳成功!";
fileItem.delete();//上傳成功,清楚臨時文件
returnmsg;
2.8配置Servlet
xmlversion="1.0"encoding="UTF-8"
web-appxmlns="/xml/ns/javaee"
xmlns:xsi="/2001/XMLSchema-instance"
xsi:schemaLocation="/xml/ns/javaee/xml/ns/javaee/web-app_4_0.xsd"
version="4.0"
servlet
servlet-nameFileServlet/servlet-name
servlet-classcom.hxl.servlet.FileServlet/servlet-class
/servlet
servlet-mapping
servlet-nameFileServlet/servlet-name
url-pattern/upload.do/url-pattern
/servlet-mapping
/web-app
2.9測試結(jié)果
3.SpringMVC文件上傳和下載
3.1上傳
在controller中有兩種方式
新建一個module,一套流程整體下來。測試能運行即可
??導(dǎo)入jar包
!--文件上傳--
dependency
groupIdcommons-fileupload/groupId
artifactIdcommons-fileupload/artifactId
version1.3.3/version
/dependency
dependency
groupIdjavax.servlet/groupId
artifactIdjavax.servlet-api/artifactId
version4.0.1/version
/dependency
??index.jsp
%@pagecontentType="text/html;charset=UTF-8"language="java"%
html
head
title文件上傳和下載/title
/head
body
formaction="${pageContext.request.contextPath}/upload"enctype="multipart/form-data"method="post"
inputtype="file"name="file"/
inputtype="submit"value="upload"
/form
/body
/html
??applicationContext.xml中配置bean
!--文件上傳配置--
beanid="multipartResolver"
!--請求的編碼格式,必須和jSP的pageEncoding屬性一致,以便正確讀取表單的內(nèi)容,默認(rèn)為ISO-8859-1--
propertyname="defaultEncoding"value="utf-8"/
!--上傳文件大小上限,單位為字節(jié)(10485760=10M)--
propertyname="maxUploadSize"value="10485760"/
propertyname="maxInMemorySize"value="40960"/
/bean
??FileController
packagecom.hxl.controller;
importorg.springframework.web.bind.annotation.RequestMapping;
importorg.springframework.web.bind.annotation.RequestParam;
importorg.springframework.web.bind.annotation.RestController;
importmons.CommonsMultipartFile;
importjavax.servlet.http.HttpServletRequest;
importjava.io.*;
@RestController
publicclassFileController{
//@RequestParam("file")將name=file控件得到的文件封裝成CommonsMultipartFile對象
//批量上傳CommonsMultipartFile則為數(shù)組即可
@RequestMapping("/upload")
publicStringfileUpload(@RequestParam("file")CommonsMultipartFilefile,HttpServletRequestrequest)throwsIOException{
//獲取文件名:file.getOriginalFilename();
StringuploadFileName=file.getOriginalFilename();
//如果文件名為空,直接回到首頁!
if("".equals(uploadFileName)){
return"redirect:/index.jsp";
System.out.println("上傳文件名:"+uploadFileName);
//上傳路徑保存設(shè)置
Stringpath=request.getServletContext().getRealPath("/upload");
//如果路徑不存在,創(chuàng)建一個
FilerealPath=newFile(path);
if(!realPath.exists()){
realPath.mkdir();
System.out.println("上傳文件保存地址:"+realPath);
InputStreamis=file.getInputStream();//文件輸入流
OutputStreamos=newFileOutputStream(newFile(realPath,uploadFileName));//文件輸出流
//讀取寫出
intlen=0;
byte[]buffer=newbyte[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")
publicStringfileUpload2(@RequestParam("file")CommonsMultipartFilefile,HttpServletRequestrequest)throwsIOException{
//上傳路徑保存設(shè)置
Stringpath=request.getServletContext().getRealPath("/upload");
FilerealPath=newFile(path);
if(!realPath.exists()){
realPath.mkdir();
//上傳文件地址
System.out.println("上傳文件保存地址:"+realPath);
//通過CommonsMultipartFile的方法直接寫文件(注意這個時候)
file.transferTo(newFile(realPath+"/"+file.getOriginalFilename()));
return"redirect:/index.jsp";
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 創(chuàng)業(yè)培訓(xùn)教師授課信息反饋表
- 平臺穩(wěn)性操作員保密競賽考核試卷含答案
- 制材工安全文明測試考核試卷含答案
- 軋鋼精整工安全宣貫強化考核試卷含答案
- 橋梁支座試驗培訓(xùn)
- 銀行內(nèi)部審計報告制度
- 酒店員工獎懲與激勵機制制度
- 超市員工績效考核制度
- 濟南拼音書寫培訓(xùn)
- 流量計培訓(xùn)教學(xué)課件
- 北京市順義區(qū)2025-2026學(xué)年八年級上學(xué)期期末考試英語試題(原卷版+解析版)
- 中學(xué)生冬季防溺水主題安全教育宣傳活動
- 2026年藥廠安全生產(chǎn)知識培訓(xùn)試題(達標(biāo)題)
- 初中九年級上一元二次方程計算練習(xí)題及答案詳解B2
- 中國涉外律師人才研究報告2025
- 冷庫防護制度規(guī)范
- 2026年生產(chǎn)管理崗入職性格測試題及答案
- 2026年bjt商務(wù)能力考試試題
- 廣東省廣州市番禺區(qū)2026屆高一數(shù)學(xué)第一學(xué)期期末聯(lián)考試題含解析
- 2026年廣東省佛山市高三語文聯(lián)合診斷性考試作文題及3篇范文:可以“重讀”甚至“重構(gòu)”這些過往
- 老年住院患者非計劃性拔管分析2026
評論
0/150
提交評論