在Javaweb中,上傳下載是經(jīng)常用到的功能,對于文件上傳,瀏覽器在上傳的過程中是以流的過程將文件傳給服務(wù)器,一般都是使用commons-fileupload這個包實現(xiàn)上傳功能,因為commons-fileupload依賴于commons-io這個包,所以需要下載這兩個包commons-fileupload-1.2.1.jar和commons-io-1.3.2.jar。
1、搭建環(huán)境
創(chuàng)建Web項目,將包導(dǎo)入到項目lib下
2、實現(xiàn)文件上傳
(第一種上傳的方法)
新建upload.jsp頁面
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
<%@ page language= "java" contentType= "text/html; charset=UTF-8" pageEncoding= "UTF-8" %> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd" > <html> <head> <meta http-equiv= "Content-Type" content= "text/html; charset=UTF-8" > <title>upload file</title> </head> <body> <!--這里的<%=request.getContextPath()%>是表示項目的絕對路徑,也就是說不管你以后將項目拷貝到哪個位置,它都會找到準確的路徑 --> <form action= "<%=request.getContextPath()%>/uploadServlet" enctype= "multipart/form-data" method= "post" > <span>選擇文件:</span><input type= "file" name= "file1" > <input type= "submit" value= "上傳" > </form> </body> </html> |
新建處理文件上傳的Servlet
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
|
package com.load; import java.io.File; import java.io.IOException; import java.util.List; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; 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; @WebServlet ( "/uploadServlet" ) public class uploadServlet extends HttpServlet { private static final long serialVersionUID = 1L; public uploadServlet() { super (); } /* fileupload 包中, HTTP 請求中的復(fù)雜表單元素都被看做一個 FileItem 對象; * FileItem 對象必須由 ServletFileUpload 類中的 parseRequest() 方法解析 HTTP 請求 * (即被包裝之后的 HttpServletRequest 對象)出來,即分離出具體的文本表單和上傳文件 * */ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //通過isMultipartContent()方法:分析請求里面是不是有文件上的請求, boolean isMultipart = ServletFileUpload.isMultipartContent(request); if (isMultipart){ //創(chuàng)建可設(shè)置的磁盤節(jié)點工廠 DiskFileItemFactory factory = new DiskFileItemFactory(); //獲取請求的上下文信息 ServletContext servletContext = request.getServletContext(); //緩存目錄,每個服務(wù)器特定的目錄 File repository = (File) servletContext.getAttribute( "javax.servlet.context.tempdir" ); //設(shè)置服務(wù)器的緩存目錄 factory.setRepository(repository); //ServletFileUpload 對象的創(chuàng)建需要依賴于 FileItemFactory //工廠將獲得的上傳文件 FileItem 對象保存至服務(wù)器硬盤,即 DiskFileItem 對象。 ServletFileUpload upload = new ServletFileUpload(factory); try { //解析即被包裝之后的 HttpServletRequest對象,既是分離文本表單和上傳文件(http請求會被包裝為HttpServletRequest) List<FileItem> items = upload.parseRequest(request); for (FileItem item:items){ String fieldName = item.getFieldName(); String fileName = item.getName(); String contentType = item.getContentType(); boolean isInMemory = item.isInMemory(); long sizeInBytes = item.getSize(); //實例化一個文件 //request.getRealPath(獲取真實路徑) File file = new File(request.getRealPath( "/" )+ "/loads" +fileName.substring(fileName.lastIndexOf( "\\" )+ 1 ,fileName.length())); item.write(file); } } catch (FileUploadException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } } } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } } |
(第二種上傳的方法)
新建Jsp頁面(同上,只是路徑改變下)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
<%@ page language= "java" contentType= "text/html; charset=UTF-8" pageEncoding= "UTF-8" %> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd" > <html> <head> <meta http-equiv= "Content-Type" content= "text/html; charset=UTF-8" > <title>upload file</title> </head> <body> <!--這里的<%=request.getContextPath()%>是表示項目的絕對路徑,也就是說不管你以后將項目拷貝到哪個位置,它都會找到準確的路徑 --> <form action= "<%=request.getContextPath()%>/uploadservlet1" enctype= "multipart/form-data" method= "post" > <span>選擇文件:</span><input type= "file" name= "file1" > <input type= "submit" value= "上傳" > </form> </body> </html> |
建立Servlet處理上傳
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
|
package com.load; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import javax.servlet.ServletException; import javax.servlet.annotation.MultipartConfig; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.Part; @WebServlet ( "/uploadservlet1" ) @MultipartConfig (location= "" ) public class uploadservlet1 extends HttpServlet { private static final long serialVersionUID = 1L; public uploadservlet1() { super (); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType( "text/html;charset=UTF-8" ); request.setCharacterEncoding( "utf-8" ); //取得上傳文件,讀取文件 Part part = request.getPart( "file1" ); //定義一個變量去接收文件名 String filename = null ; //Content-Disposition: 就是當用戶想把請求所得的內(nèi)容存為一個文件的時候提供一個默認的文件名 //Content-Disposition:告訴瀏覽器以下載的方式打開文件 for (String content : part.getHeader( "content-disposition" ).split( ";" )) { System.out.println(content); //取得文件名 if (content.trim().startsWith( "filename" )) { //截取文件名 filename = content.substring( content.indexOf( '=' ) + 1 ).trim().replace( "\"" , "" ); } } //輸出流 OutputStream out = null ; //輸入流 InputStream filecontent = null ; //File.separator 取得系統(tǒng)的分割線等數(shù)據(jù) out = new FileOutputStream( new File( "e:/loads" + File.separator + filename)); int read; //獲得一個輸入流 filecontent = part.getInputStream(); final byte [] bytes = new byte [ 1024 ]; while ((read = filecontent.read(bytes)) != - 1 ) { out.write(bytes, 0 , read); } System.out.println( "New file " + filename + " created at " + "/loads" ); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub doGet(request, response); } } |
(第三種上傳的方法)
這里使用的是jspSmartUpload包上傳下載,筆者認為這種上傳下載較為簡單,但是好像不是很多人用,不懂。
創(chuàng)建HTML頁面
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
<!DOCTYPE html> < html > < head > < meta http-equiv = "Content-Type" content = "text/html; charset=UTF-8" > < title >上傳文件</ title > </ head > < body > < p > </ p > < p align = "center" >上傳文件選擇</ p > < form method = "post" Action = "../DouploadServlet" enctype = "multipart/form-data" > < table width = "75%" border = "1" align = "center" > < tr >< td >< div align = "center" > 1.< input type = "file" name = "file1" > </ div ></ td ></ tr > < tr >< td >< div align = "center" > 2.< input type = "file" name = "file2" > </ div ></ td ></ tr > < tr >< td >< div align = "center" > 3.< input type = "file" name = "file3" > </ div ></ td ></ tr > < tr >< td >< div align = "center" > < input type = "submit" name = "Submit" value = "上傳他" > </ div ></ td ></ tr > </ table > </ form > </ body > </ html > |
創(chuàng)建Servlet處理上傳文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
|
package com.load; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.jsp.JspFactory; import javax.servlet.jsp.PageContext; import com.jspsmart.upload.File; import com.jspsmart.upload.SmartUpload; import com.jspsmart.upload.SmartUploadException; @WebServlet ( "/DouploadServlet" ) public class DouploadServlet extends HttpServlet { private static final long serialVersionUID = 1L; public DouploadServlet() { super (); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType( "text/html;charset=UTF-8" ); PrintWriter out = response.getWriter(); //新建一個智能上傳對象 SmartUpload su = new SmartUpload(); /* * PageContext pageContext; HttpSession session; ServletContext application; ServletConfig config; JspWriter out; Object page = this; HttpServletRequest request, HttpServletResponse response 其中page對象,request和response已經(jīng)完成了實例化,而其它5個沒有實例化的對象通過下面的方式實例化 pageContext = jspxFactory.getPageContext(this, request, response,null, true, 8192, true); */ //通過Jsp工廠類獲取上下文環(huán)境 PageContext pagecontext = JspFactory.getDefaultFactory().getPageContext(this, request, response, null, true, 8192, true); //上傳初始化 su.initialize(pagecontext); //上傳文件 try { su.upload(); //將上傳文件保存到指定目錄 int count = su.save("/share"); out.println(count+"個文件上傳成功!<br>"+su.toString()); } catch (SmartUploadException e) { e.printStackTrace(); } //逐個提取上傳文件信息 for(int i=0;i<su.getFiles().getCount();i++){ File file = su.getFiles().getFile(i); //如果文件不存在 if(file.isMissing()) continue; //顯示當前文件信息 out.println("<table border=1>"); out.println("<tr><td>表單項名(FieldName)</td></td>"+file.getFieldName()+"</td></tr>"); out.println("<tr><td>文件長度</td><td>"+file.getSize()+"</td></tr>"); out.println("<tr><td>文件名</td><td>"+file.getFileName()+"</td></tr>"); out.println("<tr><td>文件擴展名</td><td>"+file.getFileExt()+"</td></tr>"); out.println("<tr><td>文件全名</td><td>"+file.getFilePathName()+"</td></tr>"); out.println("</table><br>"); } } /** * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) */ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub doGet(request, response); } } |
注意:代碼 int count = su.save("/share");表示你需要先建個文件夾,所以你可以先在Webcontent建立一個,然后將項目取消部署,再重新部署進去之后就會在運行那邊建立起一個文件夾了!
或者你可以直接找到運行的路徑,然后建立share文件夾。
3、實現(xiàn)文件下載
(第一種文件下載)
注意:該代碼是直接訪問Servlet類的
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
|
package com.load; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; //直接使用Http://localhost:8080/Test1/download進行下載,但是這個有缺陷,如果下載文件名中有中文,就會變成亂碼現(xiàn)象! @WebServlet ( "/download" ) public class download extends HttpServlet { private static final long serialVersionUID = 1L; public download() { super (); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType( "text/plain;charset=utf-8" ); response.setCharacterEncoding( "utf-8" ); response.setHeader( "Location" , "中文.txt" ); response.setHeader( "Content-Disposition" , "attachment; filename=" + "賬號.txt" ); OutputStream outputStream = response.getOutputStream(); InputStream inputStream = new FileInputStream( "E:/loads" + "/賬號.txt" ); byte [] buffer = new byte [ 1024 ]; int i = - 1 ; while ((i = inputStream.read(buffer)) != - 1 ) { outputStream.write(buffer, 0 , i); } outputStream.flush(); outputStream.close(); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } } |
(第二種下載方法)
新建jsp頁面選擇下載
1
2
3
4
5
6
7
8
9
10
11
12
|
<%@ page language= "java" contentType= "text/html; charset=UTF-8" pageEncoding= "UTF-8" %> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd" > <html> <head> <meta http-equiv= "Content-Type" content= "text/html; charset=UTF-8" > <title>下載</title> </head> <body> <a href= "../DoDownloadServlet?filename=呵呵.txt" >點擊下載</a> </body> </html> |
創(chuàng)建Servlet類進行下載(注意:該下載如果文件名是中文的話,一樣會出現(xiàn)亂碼現(xiàn)象)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
|
package com.load; import java.io.BufferedInputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.URLEncoder; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.jsp.JspFactory; import javax.servlet.jsp.PageContext; import org.hsqldb.lib.StringUtil; import com.jspsmart.upload.SmartUpload; import com.jspsmart.upload.SmartUploadException; @WebServlet ( "/DoDownloadServlet" ) public class DoDownloadServlet extends HttpServlet { private static final long serialVersionUID = 1L; public DoDownloadServlet() { super (); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //得到下載文件的名稱 //String filename = request.getParameter("filename"); //String filename = new String(FileName.getBytes("iso8859-1"),"UTF-8"); //新建SmartUpload對象 SmartUpload su = new SmartUpload(); PageContext pagecontext = JspFactory.getDefaultFactory().getPageContext( this , request, response, null , true , 8192 , true ); //上傳初始化 su.initialize(pagecontext); //設(shè)置禁止打開該文件 su.setContentDisposition( null ); //下載文件 try { su.downloadFile( "/listener/" +filename); } catch (SmartUploadException e) { // TODO Auto-generated catch block e.printStackTrace(); } } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } } |
(第三種下載的方法)
同上的jsp頁面代碼,這里就不再重復(fù)了。
新建Serlvet類,實現(xiàn)下載功能(注意:這里文件名就算是中文名,也不會出現(xiàn)亂碼問題了!)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
|
package com.load; import java.io.BufferedInputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.URLEncoder; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.jsp.JspFactory; import javax.servlet.jsp.PageContext; import org.hsqldb.lib.StringUtil; import com.jspsmart.upload.SmartUpload; import com.jspsmart.upload.SmartUploadException; @WebServlet ( "/DoDownloadServlet" ) public class DoDownloadServlet extends HttpServlet { private static final long serialVersionUID = 1L; public DoDownloadServlet() { super (); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //獲得文件名稱 String path1 = request.getParameter( "filename" ); //獲得路徑名稱 String path = request.getSession().getServletContext().getRealPath( "/listener/" +path1); // path是根據(jù)日志路徑和文件名拼接出來的 File file = new File(path); String filename = file.getName(); try { //判斷是否是IE11 Boolean flag= request.getHeader( "User-Agent" ).indexOf( "like Gecko" )> 0 ; //IE11 User-Agent字符串:Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko //IE6~IE10版本的User-Agent字符串:Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.0; Trident/6.0) if (request.getHeader( "User-Agent" ).toLowerCase().indexOf( "msie" ) > 0 ||flag){ filename = URLEncoder.encode(filename, "UTF-8" ); //IE瀏覽器 } else { //先去掉文件名稱中的空格,然后轉(zhuǎn)換編碼格式為utf-8,保證不出現(xiàn)亂碼, //這個文件名稱用于瀏覽器的下載框中自動顯示的文件名 filename = new String(filename.replaceAll( " " , "" ).getBytes( "UTF-8" ), "ISO8859-1" ); //firefox瀏覽器 //firefox瀏覽器User-Agent字符串: //Mozilla/5.0 (Windows NT 6.1; WOW64; rv:36.0) Gecko/20100101 Firefox/36.0 } InputStream fis = new BufferedInputStream( new FileInputStream(path)); byte [] buffer; buffer = new byte [fis.available()]; fis.read(buffer); fis.close(); response.reset(); response.addHeader( "Content-Disposition" , "attachment;filename=" +filename); response.addHeader( "Content-Length" , "" + file.length()); OutputStream os = response.getOutputStream(); response.setContentType( "application/octet-stream" ); os.write(buffer); // 輸出文件 os.flush(); os.close(); } catch (IOException e) { e.printStackTrace(); } System.out.println(filename); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } } |
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持服務(wù)器之家。