JavaEE實(shí)現(xiàn)前后臺(tái)交互的文件上傳與下載
首先為大家介紹相關(guān)的技術(shù):
service方法中的兩個(gè)重要參數(shù)。
ServletRequest – 用接收用戶的請(qǐng)求,它的作用是:
- 可獲取請(qǐng)求頭信息。
- 可設(shè)置請(qǐng)請(qǐng)求的字符編碼。
- 可獲得用戶傳遞的參數(shù)。Post或get。
- 可獲取遠(yuǎn)程(即訪問(wèn)者)的IP地址。
- 可獲取輸入流,如用戶上傳文件、相片等。
它的一個(gè)子接口:javax.servlet.http.HttpServletRequest
ServletResponse – 用于向用戶返回?cái)?shù)據(jù)。
- 設(shè)置響應(yīng)類(lèi)型- contentType
- 設(shè)置編碼-setCharacterEncoding
- 獲取輸出流。
它的一個(gè)子接口:javax.servlet.http.HttpServletResponse
文件下載技術(shù):
文件下載技術(shù)相當(dāng)于文件上傳技術(shù)相對(duì)而言比較簡(jiǎn)單。我們以下載圖片為例:
圖片都是先瀏覽再下載
1.前端代碼:
<span style="font-size:14px;"><a href="img">查找文件夾下面的所有圖片</a><br/></span>
前臺(tái)只需要一句話就可以搞定了。直接通過(guò)web.xml查找后臺(tái)的程序
2.后臺(tái)顯示代碼:
<span style="font-size:14px;">public class ShowImg extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
<span style="white-space:pre"> </span>doPost(request, response);//為了防止異常,將doGet和doPost連接在一起
}</span>
<span style="font-size:14px;">public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter();</span>
<pre name="code" class="html"><span style="font-size:14px;">//<span style="white-space:pre"> </span>調(diào)出Servletcontext,當(dāng)然也可以直接調(diào)用---當(dāng)一一列出圖片的時(shí)候需要文件的絕對(duì)路徑</span>
ServletContext context =getServletContext();String path=context.getRealPath("/imgs");//找到該文件夾的絕對(duì)路徑File file =new File(path);
<span style="font-size:14px;">//<span style="white-space:pre"> </span>找到文件夾之后,列出所有圖片供用戶瀏覽
String files[] =file.list();
for(String fn:files){</span>
<pre name="code" class="html"><span style="font-size:14px;">//一個(gè)個(gè)的全部顯示出來(lái)</span>
String img="<img src='imgs/"+fn+"'/>";
// out.print("<a href=imgs/'"+fn+"'>下載圖片</a>");String str="<a href='down?name=imgs/"+fn+"'>下載圖片</a>";//提供下載的超鏈接,傳參---傳文件名給用戶鏈接內(nèi)容下面寫(xiě)out.print(str);out.print(img+"<br/>");}}
3.文件的具體下載
首先必須設(shè)置相應(yīng)的協(xié)議。下載協(xié)議就需要設(shè)置相應(yīng)的下載頭
<span style="white-space:pre"> </span><span style="font-size:18px;"><strong>response.setContentType("application/force-download"</strong>);//設(shè)置相應(yīng)頭</span>
下載的時(shí)候需要顯示當(dāng)前圖片的文件名,需要從前臺(tái)獲取,并且從下載獲得之后寫(xiě)到前臺(tái)去
<span style="font-size:18px;"> <span style="white-space:pre"> </span>OutputStream out=response.getOutputStream();//獲得輸出流
String name=request.getParameter("name");//從客服端傳過(guò)來(lái)的參數(shù)名
int num=name.lastIndexOf("/");
String aa=name.substring(num+1);
aa=URLEncoder.encode(aa, "UTF-8");//若是中文需要重新編碼
//System.out.println(aa);
response.setHeader("Content-Disposition",<span style="color:#ff0000;">"<strong>attachment;filename</strong></span>='"+aa+"'");//獲取從那邊傳過(guò)來(lái)的文件名,以便于存儲(chǔ)的時(shí)候?yàn)橄螺d用戶名</span>
進(jìn)行具體的下載
<span style="font-size:18px;"> String filename=this.getServletContext().getRealPath(name);//獲得絕對(duì)路徑,傳文件名過(guò)來(lái),同時(shí)傳了可以獲得的絕對(duì)路徑就可以進(jìn)行讀可寫(xiě)了
InputStream in=new FileInputStream(filename);
byte[] b=new byte[1024];
int len=0;
while((len=in.read(b))!=-1){
out.write(b, 0, len);
}</span>
效果圖:

點(diǎn)擊之后的效果圖:

傳文件名不一樣

文件上傳技術(shù)
文件上傳要是自己去寫(xiě)會(huì)很麻煩,所以我們可以用別人的包,下載鏈接點(diǎn)擊打開(kāi)鏈接
表單:
客戶端發(fā)送HTTP必須使用multipart/form-data數(shù)據(jù)類(lèi)型,表示復(fù)合數(shù)據(jù)類(lèi)型。
即:<form enctype=“multipart/form-data”>
在表單中使用<input type=“file” name=“somename”/>html標(biāo)簽。
需要的包:
Commons-fileupload.jar,核心上傳文件工具都在這個(gè)包中。
commons-io.jar – 上傳文件所需要的包

詳解:
DiskFileItemFactory-創(chuàng)建監(jiān)時(shí)文件目錄,指是緩存區(qū)大小
ServletFileUpload用于解析HttpServletRequest。返回一組文件對(duì)象。
FileItem – 表示用戶上傳的每一個(gè)文件對(duì)像。
主要流程:
File f = new File("F:/ex/temp");//指定臨時(shí)文件存放位置
DiskFileItemFactory ff =new DiskFileItemFactory(1024*1024*5, f);//臨時(shí)文件的大小和存放位置
ServletFileUpload sf =new ServletFileUpload(ff);
List<FileItem> list=sf.parseRequest(request);//開(kāi)始解析
for(FileItem it:list){//獲得文件名。以及用到uuid解決重名的問(wèn)題
FileUtils.copyInputStreamToFile(it.getInputStream(), new File(path+"/"+filename));//寫(xiě)的指定的文件夾中
}
1、前臺(tái)代碼:
<span style="font-size:18px;"><h2>上傳文件</h2> <form action="UpFile" method="post" <span style="color:#ff0000;">enctype="multipart/form-data"</span> >//必須要寫(xiě),不然后臺(tái)沒(méi)辦法去接收數(shù)據(jù) <!-- 必須添加這個(gè)enctype="multipart/form-data"--> File1<input type="file"<span style="color:#ff6666;"> name</span>="file"/><br/> 請(qǐng)輸入名稱(chēng):<input type="text" <span style="color:#ff6666;">name</span>="desc"/><br/> File2<input type="file"<span style="color:#ff6666;"> name</span>="file"/><br/> 請(qǐng)輸入名稱(chēng):<input type="text"<span style="color:#ff0000;"> name</span>="desc"/><br/> <input type="submit" value="提交"/> </form></span>
2、后臺(tái)代碼:
2-1首先創(chuàng)建一個(gè)基于硬盤(pán)的工廠,用來(lái)存放臨時(shí)文件
//指定臨時(shí)存放位置
File f = new File("F:/ex/temp");//指定臨時(shí)文件存放位置
DiskFileItemFactory ff =new DiskFileItemFactory(1024*1024*5, f);//臨時(shí)文件的大小和存放位置
2-2 創(chuàng)建一個(gè)用ServletFileUpload對(duì)象,并且設(shè)置文件大小,最大允許傳多大的文件
//創(chuàng)建用于解析的對(duì)象
ServletFileUpload sf =new ServletFileUpload(ff);
sf.setFileSizeMax(1024*1024*10);//僅僅允許單個(gè)存放位置最大值是 10M
sf.setSizeMax(1024*1024*20);//所有文件的最大值是20M
String path =this.getServletContext().getRealPath("/imgs");
System.out.println("存儲(chǔ)路徑:"+path);
2-3 開(kāi)始解析對(duì)象
<span style="white-space:pre"> </span>List<FileItem> list=sf.parseRequest(request);//獲得從前臺(tái)傳過(guò)來(lái)的所有信息,前臺(tái)必須填寫(xiě)enctype="multipart/form-data"
for(FileItem it:list){
it0=it;
//<span style="white-space:pre"> </span>若是普通表單對(duì)象--可以直接判斷出
if(it.isFormField()){//是普通表單項(xiàng),如 type=text里面name的值
String name=it.getString("utf-8");
System.out.println("基本表單項(xiàng) name:"+name);//下面寫(xiě)的解釋的名字
}else{
<span style="white-space:pre"> </span>// 這就是前臺(tái)選擇的文件名
String name=it.getName();//具體的文件路徑---絕對(duì)路徑
// String str=it.getString();//文件里面的內(nèi)容
// System.out.println("str"+str);
String contenttype=it.getContentType();
Long size=it.getSize();
<span style="white-space:pre"> </span>System.out.println(name+","+contenttype+","+size);
<pre name="code" class="html" style="font-size: 18px;">//<span style="white-space:pre"> </span>在服務(wù)器端的資源文件名不能用中文,瀏覽器會(huì)自動(dòng)編碼-------必須要把用戶上傳的文件名轉(zhuǎn)成沒(méi)有中文的名字存儲(chǔ),
//為了讓用戶在下載時(shí)能還原出原來(lái)的名字,就要把原文件名和映射名的對(duì)應(yīng)關(guān)系存儲(chǔ)起來(lái),在用戶下載時(shí)再轉(zhuǎn)換回來(lái)
//映射名String id=UUID.randomUUID().toString().replace("-", "");//全球唯一UUId來(lái)進(jìn)行//文件名String lastname=name.substring(name.lastIndexOf("."));//文件格式//名字文件格式都找到了---組合String filename =id+lastname;//新的文件名//拷貝流。讓它寫(xiě)到相應(yīng)位置FileUtils.copyInputStreamToFile(it.getInputStream(), new File(path+"/"+filename));//path為存儲(chǔ)的絕對(duì)路徑--之前定義的}
這樣能實(shí)現(xiàn)簡(jiǎn)單的上傳,但是,這種上傳是沒(méi)有一點(diǎn)安全行了。完整的代碼中附上了防一般的小問(wèn)題還是沒(méi)問(wèn)題的

選擇文件之后

查看web服務(wù)器img里面的文件,文件已經(jīng)上傳到該頁(yè)面《文件名為uuid生成的文件名》

文件上傳源代碼:
<span style="font-size:14px;">package cn.hncu.UPfile;import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.Writer;
import java.util.List;
import java.util.UUID;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.io.FileUtils;
public class MyupFile extends HttpServlet {
<span style="white-space: pre;"> </span>//doGET防止有人在用戶欄輸入地址。沒(méi)有響應(yīng)
<span style="white-space: pre;"> </span>@Override
<span style="white-space: pre;"> </span>protected void doGet(HttpServletRequest req, HttpServletResponse resp)
<span style="white-space: pre;"> </span>throws ServletException, IOException {
<span style="white-space: pre;"> </span>resp.setContentType("utf-8");
<span style="white-space: pre;"> </span>Writer wr=resp.getWriter();
<span style="white-space: pre;"> </span>wr.write("暫不支持該上傳方式");
<span style="white-space: pre;"> </span>}
<span style="white-space: pre;"> </span>
<span style="white-space: pre;"> </span>public void doPost(HttpServletRequest request, HttpServletResponse response)
<span style="white-space: pre;"> </span>throws ServletException, IOException {
<span style="white-space: pre;"> </span>request.setCharacterEncoding("utf-8");
<span style="white-space: pre;"> </span>response.setContentType("text/html;charset=utf-8");
<span style="white-space: pre;"> </span>PrintWriter out=response.getWriter();
<span style="white-space: pre;"> </span>//防護(hù) 以普通表單上傳 法一:
<span style="white-space: pre;"> </span>//返回值 GET (null) POST1(apllication/x-form-urlencoded,普通表單) POST2(file:multipart/form-data,文件上傳表單)
//<span style="white-space: pre;"> </span>String type =request.getContentType();
//<span style="white-space: pre;"> </span>if(!type.contains("mulitpart/form-data")){
//<span style="white-space: pre;"> </span>out.write("不支持普通表單的上傳2");
//<span style="white-space: pre;"> </span>return ;
//<span style="white-space: pre;"> </span>}
<span style="white-space: pre;"> </span>// 法二
<span style="white-space: pre;"> </span>boolean boo=ServletFileUpload.isMultipartContent(request);
<span style="white-space: pre;"> </span>if(boo==false){
<span style="white-space: pre;"> </span>out.print("不支持普通表單的上傳1");
<span style="white-space: pre;"> </span>
<span style="white-space: pre;"> </span>}
<span style="white-space: pre;"> </span>
<span style="white-space: pre;"> </span>//指定臨時(shí)存放位置
<span style="white-space: pre;"> </span>File f = new File("F:/ex/temp");//指定臨時(shí)文件存放位置
<span style="white-space: pre;"> </span>DiskFileItemFactory ff =new DiskFileItemFactory(1024*1024*5, f);//臨時(shí)文件的大小和存放位置
<span style="white-space: pre;"> </span>
<span style="white-space: pre;"> </span>//創(chuàng)建用于解析的對(duì)象
<span style="white-space: pre;"> </span>ServletFileUpload sf =new ServletFileUpload(ff);
<span style="white-space: pre;"> </span>sf.setFileSizeMax(1024*1024*10);//僅僅允許單個(gè)存放位置最大值是 10M
<span style="white-space: pre;"> </span>sf.setSizeMax(1024*1024*20);//所有文件的最大值是20M
<span style="white-space: pre;"> </span>String path =this.getServletContext().getRealPath("/imgs");
<span style="white-space: pre;"> </span>System.out.println("存儲(chǔ)路徑:"+path);
<span style="white-space: pre;"> </span>//開(kāi)始進(jìn)行解析
<span style="white-space: pre;"> </span>FileItem it0=null;//用于在finally中進(jìn)行刪除臨時(shí)文件
<span style="white-space: pre;"> </span>try {
<span style="white-space: pre;"> </span>List<FileItem> list=sf.parseRequest(request);//獲得從前臺(tái)傳過(guò)來(lái)的所有信息,前臺(tái)必須填寫(xiě)enctype="multipart/form-data"
<span style="white-space: pre;"> </span>for(FileItem it:list){
<span style="white-space: pre;"> </span>it0=it;
<span style="white-space: pre;"> </span>if(it.isFormField()){//是普通表單項(xiàng),如 type=text里面name的值
<span style="white-space: pre;"> </span>String name=it.getString("utf-8");
<span style="white-space: pre;"> </span>System.out.println("基本表單項(xiàng) name:"+name);//下面寫(xiě)的解釋的名字
<span style="white-space: pre;"> </span>}else{
<span style="white-space: pre;"> </span>String name=it.getName();//具體的文件路徑
//<span style="white-space: pre;"> </span>String n1=it.getFieldName();
//<span style="white-space: pre;"> </span>String str=it.getString();//文件里面的內(nèi)容
//<span style="white-space: pre;"> </span>System.out.println("str"+str);
//<span style="white-space: pre;"> </span>System.out.println("n1:"+n1);
<span style="white-space: pre;"> </span>String contenttype=it.getContentType();
<span style="white-space: pre;"> </span>Long size=it.getSize();
<span style="white-space: pre;"> </span>//防止文件為空
<span style="white-space: pre;"> </span>if(size==0){
<span style="white-space: pre;"> </span>continue;//文件為空,直接返回;
<span style="white-space: pre;"> </span>}
<span style="white-space: pre;"> </span>//用戶名。必須要填寫(xiě)
<span style="white-space: pre;"> </span>if(name==null||name.trim()==""){
<span style="white-space: pre;"> </span>continue;
<span style="white-space: pre;"> </span>}
<span style="white-space: pre;"> </span>//<span style="white-space: pre;"> </span>System.out.println(name+","+contenttype+","+size);
<span style="white-space: pre;"> </span>//在服務(wù)器端的資源文件名不能用中文,瀏覽器會(huì)自動(dòng)編碼-------必須要把用戶上傳的文件名轉(zhuǎn)成沒(méi)有中文的名字存儲(chǔ),
<span style="white-space: pre;"> </span>//為了讓用戶在下載時(shí)能還原出原來(lái)的名字,就要把原文件名和映射名的對(duì)應(yīng)關(guān)系存儲(chǔ)起來(lái),在用戶下載時(shí)再轉(zhuǎn)換回來(lái)
<span style="white-space: pre;"> </span>//映射名
<span style="white-space: pre;"> </span>String id=UUID.randomUUID().toString().replace("-", "");
<span style="white-space: pre;"> </span>//文件名
<span style="white-space: pre;"> </span>String lastname=name.substring(name.lastIndexOf("."));
<span style="white-space: pre;"> </span>//名字文件格式都找到了---組合
<span style="white-space: pre;"> </span>String filename =id+lastname;
<span style="white-space: pre;"> </span>//拷貝流。讓它寫(xiě)到相應(yīng)位置
<span style="white-space: pre;"> </span>FileUtils.copyInputStreamToFile(it.getInputStream(), new File(path+"/"+filename));}<span style="white-space: pre;"> </span>}} catch (FileUploadException e) {
<span style="white-space: pre;"> </span>throw new RuntimeException("文件上傳解析錯(cuò)誤。"+e);
<span style="white-space: pre;"> </span>}finally{
<span style="white-space: pre;"> </span>if(it0==null){
<span style="white-space: pre;"> </span>it0.delete();//刪除臨時(shí)文件
<span style="white-space: pre;"> </span>}}out.close();}}</span><span style="font-size: 18px;">
</span>
文件下載源代碼:
[html] view plaincopyprint?
<span style="font-size:14px;">package cn.hncu.downImg;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.URLEncoder;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class DownImgDemo extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doPost(request, response);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//設(shè)置相應(yīng)頭
response.setContentType("application/force-download");
//給前臺(tái)傳用戶名
/*傳固定的用戶名
String aa="1.jpg";//若是中文,需要編碼
aa=URLEncoder.encode(aa, "UTF-8");
response.setHeader("Content-Disposition", "attachment;filename='"+aa+"'");////必須要加“attachment;”,否則會(huì)變成瀏覽
*/
OutputStream out=response.getOutputStream();//獲得輸出流
String name=request.getParameter("name");//從客服端傳過(guò)來(lái)的參數(shù)名
int num=name.lastIndexOf("/");
String aa=name.substring(num+1);
aa=URLEncoder.encode(aa, "UTF-8");//若是中文需要重新編碼
//System.out.println(aa);
response.setHeader("Content-Disposition","attachment;filename='"+aa+"'");//獲取從那邊傳過(guò)來(lái)的文件名,以便于存儲(chǔ)的時(shí)候?yàn)橄螺d用戶名
String filename=this.getServletContext().getRealPath(name);//獲得絕對(duì)路徑
InputStream in=new FileInputStream(filename);
byte[] b=new byte[1024];
int len=0;
while((len=in.read(b))!=-1){
out.write(b, 0, len);}}}</span><span style="font-size: 18px;">
</span>
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助。
- JavaWeb實(shí)現(xiàn)文件上傳下載功能實(shí)例解析
- JAVA中使用FTPClient實(shí)現(xiàn)文件上傳下載實(shí)例代碼
- java實(shí)現(xiàn)FTP文件上傳與文件下載
- JAVA技術(shù)實(shí)現(xiàn)上傳下載文件到FTP服務(wù)器(完整)
- JavaWeb實(shí)現(xiàn)文件上傳下載功能實(shí)例詳解
- Java通過(guò)FTP服務(wù)器上傳下載文件的方法
- JAVA SFTP文件上傳、下載及批量下載實(shí)例
- java中struts2實(shí)現(xiàn)文件上傳下載功能實(shí)例解析
- java文件上傳下載功能實(shí)現(xiàn)代碼
- java實(shí)現(xiàn)文件上傳和下載
相關(guān)文章
Java常見(jiàn)面試題之final在java中的作用是什么
這篇文章主要介紹了Java常見(jiàn)面試題之final在java中的作用是什么,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-01-01
Java 并發(fā)編程ArrayBlockingQueue的實(shí)現(xiàn)
這篇文章主要介紹了Java 并發(fā)編程ArrayBlockingQueue的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-02-02
Java 在PDF中添加頁(yè)面跳轉(zhuǎn)按鈕功能(代碼演示)
這篇文章主要介紹了Java 在PDF中添加頁(yè)面跳轉(zhuǎn)按鈕功能,本文給大家提供了多種功能的按鈕,需要的朋友可以參考下2019-11-11
最詳細(xì)的Java循環(huán)結(jié)構(gòu)解析之for循環(huán)教程(適合小白)
:循環(huán)結(jié)構(gòu)是指在程序中需要反復(fù)執(zhí)行某個(gè)功能而設(shè)置的一種程序結(jié)構(gòu),下面這篇文章主要給大家介紹了關(guān)于Java循環(huán)結(jié)構(gòu)解析之for循環(huán)的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考下2021-09-09
SpringBoot?基于?MongoTemplate?的工具類(lèi)過(guò)程詳解
MongoDB是一個(gè)高性能,開(kāi)源,無(wú)模式的文檔型數(shù)據(jù)庫(kù),是當(dāng)前NoSql數(shù)據(jù)庫(kù)中比較熱門(mén)的一種,這篇文章主要介紹了SpringBoot基于MongoTemplate的工具類(lèi),需要的朋友可以參考下2023-09-09
KotlinScript構(gòu)建SpringBootStarter保姆級(jí)教程
這篇文章主要為大家介紹了KotlinScript構(gòu)建SpringBootStarter的保姆級(jí)教程,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-09-09
Android仿微信實(shí)現(xiàn)左滑顯示刪除按鈕功能
這篇文章主要為大家詳細(xì)介紹了java仿微信實(shí)現(xiàn)左滑顯示刪除按鈕功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-10-10
SpringBoot中的Bean的初始化與銷(xiāo)毀順序解析
這篇文章主要介紹了SpringBoot中的Bean的初始化與銷(xiāo)毀順序,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-08-08
SpringBoot整合SpringTask實(shí)現(xiàn)定時(shí)任務(wù)的流程
這篇文章主要介紹了SpringBoot整合SpringTask實(shí)現(xiàn)定時(shí)任務(wù)的流程,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-06-06

