首先為大家介紹相關的技術:
service方法中的兩個重要參數。
ServletRequest 用接收用戶的請求,它的作用是:
它的一個子接口:javax.servlet.http.HttpServletRequest
ServletResponse 用於向用戶返回數據。
它的一個子接口:javax.servlet.http.HttpServletResponse
文件下載技術:
文件下載技術相當於文件上傳技術相對而言比較簡單。我們以下載圖片為例:
圖片都是先瀏覽再下載
1.前端代碼:
<span style="font-size:14px;"><a href="img">查找文件夾下面的所有圖片</a><br/></span>
前台只需要一句話就可以搞定了。直接通過web.xml查找後台的程序
2.後台顯示代碼:
<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 "><span style="font-size:14px;">//<span style="white-space:pre"> </span>調出Servletcontext,當然也可以直接調用---當一一列出圖片的時候需要文件的絕對路徑</span> ServletContext context =getServletContext();String path=context.getRealPath("/imgs");//找到該文件夾的絕對路徑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"><span style="font-size:14px;">//一個個的全部顯示出來</span> String img="<img src='imgs/"+fn+"'/>";
// out.print("<a href=imgs/'"+fn+"'>下載圖片</a>");String str="<a href='down?name=imgs/"+fn+"'>下載圖片</a>";//提供下載的超鏈接,傳參---傳文件名給用戶鏈接內容下面寫out.print(str);out.print(img+"<br/>"); }}
3.文件的具體下載
首先必須設置相應的協議。下載協議就需要設置相應的下載頭
<span style="white-space:pre"> </span><span style="font-size:18px;"><strong>response.setContentType("application/force-download"</strong>);/ /設置相應頭</span>下載的時候需要顯示當前圖片的文件名,需要從前台獲取,並且從下載獲得之後寫到前台去
<span style="font-size:18px;"> <span style="white-space:pre"> </span>OutputStream out=response.getOutputStream();//獲得輸出流String name=request.getParameter( "name");//從客服端傳過來的參數名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+"'");//獲取從那邊傳過來的文件名,以便於存儲的時候為下載用戶名</span>進行具體的下載
<span style="font-size:18px;"> String filename=this.getServletContext().getRealPath(name);//獲得絕對路徑,傳文件名過來,同時傳了可以獲得的絕對路徑就可以進行讀可寫了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>效果圖:
點擊之後的效果圖:
傳文件名不一樣
文件上傳技術
文件上傳要是自己去寫會很麻煩,所以我們可以用別人的包,下載鏈接點擊打開鏈接表單:
客戶端發送HTTP必須使用multipart/form-data數據類型,表示複合數據類型。
即:<form enctype=“multipart/form-data”>
在表單中使用<input type=“file” name=“somename”/>html標籤。
需要的包:
Commons-fileupload.jar,核心上傳文件工具都在這個包中。
commons-io.jar 上傳文件所需要的包
詳解:
DiskFileItemFactory-創建監時文件目錄,指是緩存區大小
ServletFileUpload用於解析HttpServletRequest。返回一組文件對象。
FileItem 表示用戶上傳的每一個文件對像。
主要流程:
File f = new File("F:/ex/temp");//指定臨時文件存放位置
DiskFileItemFactory ff =new DiskFileItemFactory(1024*1024*5, f);//臨時文件的大小和存放位置
ServletFileUpload sf =new ServletFileUpload(ff);
List<FileItem> list=sf.parseRequest(request);//開始解析
for(FileItem it:list){//獲得文件名。以及用到uuid解決重名的問題
FileUtils.copyInputStreamToFile(it.getInputStream(), new File(path+"/"+filename));//寫的指定的文件夾中
}
1、前台代碼:
<span style="font-size:18px;"><h2>上傳文件</h2> <form action="UpFile" method="post" <span style="color:#ff0000;">enctype="multipart /form-data"</span> >//必須要寫,不然後台沒辦法去接收數據<!-- 必須添加這個enctype="multipart/form-data"--> File1<input type="file" <span style="color:#ff6666;"> name</span>="file"/><br/> 請輸入名稱:<input type="text" <span style="color:#ff6666;"> name</span>="desc"/><br/> File2<input type="file"<span style="color:#ff6666;"> name</span>="file"/><br/>請輸入名稱:<input type="text"<span style="color:#ff0000;"> name</span>="desc"/><br/> <input type="submit" value="提交" /> </form></span>
2、後台代碼:
2-1首先創建一個基於硬盤的工廠,用來存放臨時文件
//指定臨時存放位置File f = new File("F:/ex/temp");//指定臨時文件存放位置DiskFileItemFactory ff =new DiskFileItemFactory(1024*1024*5, f);//臨時文件的大小和存放位置2-2 創建一個用ServletFileUpload對象,並且設置文件大小,最大允許傳多大的文件
//創建用於解析的對象ServletFileUpload sf =new ServletFileUpload(ff); sf.setFileSizeMax(1024*1024*10);//僅僅允許單個存放位置最大值是10M sf.setSizeMax(1024*1024*20); //所有文件的最大值是20M String path =this.getServletContext().getRealPath("/imgs"); System.out.println("存儲路徑:"+path); 2-3 開始解析對象
<span style="white-space:pre"> </span>List<FileItem> list=sf.parseRequest(request);//獲得從前台傳過來的所有信息,前台必須填寫enctype="multipart/form- data" for(FileItem it:list){ it0=it; //<span style="white-space:pre"> </span>若是普通表單對象--可以直接判斷出if(it.isFormField()) {//是普通表單項,如type=text裡面name的值String name=it.getString("utf-8"); System.out.println("基本表單項name:"+name);//下面寫的解釋的名字}else{ <span style="white-space:pre"> </span>// 這就是前台選擇的文件名String name=it.getName();//具體的文件路徑-- -絕對路徑// String str=it.getString();//文件裡面的內容// 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" style="font- size: 18px;">//<span style="white-space:pre"> </span>在服務器端的資源文件名不能用中文,瀏覽器會自動編碼-------必須要把用戶上傳的文件名轉成沒有中文的名字存儲, //為了讓用戶在下載時能還原出原來的名字,就要把原文件名和映射名的對應關係存儲起來,在用戶下載時再轉換回來//映射名String id=UUID.randomUUID().toString().replace("-", "");//全球唯一UUId來進行//文件名String lastname=name.substring(name.lastIndexOf(" ."));//文件格式//名字文件格式都找到了---組合String filename =id+lastname;//新的文件名//拷貝流。讓它寫到相應位置FileUtils.copyInputStreamToFile(it.getInputStream(), new File(path+"/"+filename));//path為存儲的絕對路徑--之前定義的}
這樣能實現簡單的上傳,但是,這種上傳是沒有一點安全行了。完整的代碼中附上了防一般的小問題還是沒問題的
選擇文件之後
查看web服務器img裡面的文件,文件已經上傳到該頁面《文件名為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防止有人在用戶欄輸入地址。沒有響應<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>//防護以普通表單上傳法一: <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>//指定臨時存放位置<span style="white-space: pre;"> </span>File f = new File("F :/ex/temp");//指定臨時文件存放位置<span style="white-space: pre;"> </span>DiskFileItemFactory ff =new DiskFileItemFactory(1024*1024*5, f);//臨時文件的大小和存放位置<span style="white-space: pre;"> </span> <span style="white-space: pre;"> </span>//創建用於解析的對象<span style="white-space: pre;"> </span>ServletFileUpload sf =new ServletFileUpload(ff); <span style="white-space: pre;"> </span>sf.setFileSizeMax(1024*1024*10 );//僅僅允許單個存放位置最大值是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("存儲路徑:"+path); <span style="white-space: pre;"> </span>//開始進行解析<span style="white-space: pre;" > </span>FileItem it0=null;//用於在finally中進行刪除臨時文件<span style="white-space: pre;"> </span>try { <span style="white-space: pre ;"> </span>List<FileItem> list=sf.parseRequest(request);//獲得從前台傳過來的所有信息,前台必須填寫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()){//是普通表單項,如type=text裡面name的值<span style="white-space: pre;"> </span>String name= it.getString("utf-8"); <span style="white-space: pre;"> </span>System.out.println("基本表單項name:"+name);//下面寫的解釋的名字<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();//文件裡面的內容//<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>//用戶名。必須要填寫<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>//在服務器端的資源文件名不能用中文,瀏覽器會自動編碼-------必須要把用戶上傳的文件名轉成沒有中文的名字存儲, <span style="white-space: pre;" > </span>//為了讓用戶在下載時能還原出原來的名字,就要把原文件名和映射名的對應關係存儲起來,在用戶下載時再轉換回來<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>//拷貝流。讓它寫到相應位置<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("文件上傳解析錯誤。"+ 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();//刪除臨時文件<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 { //設置相應頭response.setContentType("application/force-download"); //給前台傳用戶名/*傳固定的用戶名String aa="1.jpg";//若是中文,需要編碼aa=URLEncoder.encode(aa, "UTF-8"); response.setHeader("Content-Disposition", "attachment ;filename='"+aa+"'");////必須要加“attachment;”,否則會變成瀏覽*/ OutputStream out=response.getOutputStream();//獲得輸出流String name=request. getParameter("name");//從客服端傳過來的參數名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+"'");//獲取從那邊傳過來的文件名,以便於存儲的時候為下載用戶名String filename=this.getServletContext().getRealPath(name);//獲得絕對路徑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>以上就是本文的全部內容,希望對大家的學習有所幫助。