Web文件下載有兩種,一種是文件在網(wǎng)站目錄下,在瀏覽器中直接輸入文件路徑即可下載,如http://www.xxx.com/file.zip。另外一種是文件不在網(wǎng)站目錄下或者文件是動(dòng)態(tài)生成的(導(dǎo)出報(bào)表或者導(dǎo)出excel等),這種情況需要通過(guò)response的OutputStream實(shí)現(xiàn)文件的下載。DownloadUtils是一個(gè)Java Web文件下載工具類,提供多種靜態(tài)方法實(shí)現(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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
|
package com.rhui.util; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; 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.http.HttpServletResponse; import org.apache.commons.lang3.StringUtils; /** * 文件下載類 */ public class DownloadUtils { /** * 文件下載編碼 * 該編碼告訴瀏覽器文件名的編碼方式,以防下載中文文件名時(shí)有亂碼 */ private static String encoding = "utf-8" ; /** * 文件下載 * @param response * @param filePath 文件在服務(wù)器上的路徑,包含文件名 */ public static void download(HttpServletResponse response, String filePath){ File file = new File(filePath.toString()); download(response, file, null , encoding); } /** * 文件下載 * @param response * @param filePath 文件在服務(wù)器上的路徑,包括文件名稱 * @param fileName 文件下載到瀏覽器的名稱,如果不想讓瀏覽器下載的文件名稱和服務(wù)器上的文件名稱一樣,請(qǐng)?jiān)O(shè)置該參數(shù) */ public static void download(HttpServletResponse response, String filePath, String fileName){ File file = new File(filePath.toString()); download(response, file, fileName, encoding); } /** * 文件下載 * @param response * @param filePath 文件在服務(wù)器上的路徑,包括文件名稱 * @param fileName 文件下載到瀏覽器的名稱,如果不想讓瀏覽器下載的文件名稱和服務(wù)器上的文件名稱一樣,請(qǐng)?jiān)O(shè)置該參數(shù) * @param encoding 文件名稱編碼 */ public static void download(HttpServletResponse response, String filePath, String fileName, String encoding){ File file = new File(filePath.toString()); download(response, file, fileName, encoding); } /** * 文件下載 * @param response * @param file 文件 * @param fileName 文件下載到瀏覽器的名稱,如果不想讓瀏覽器下載的文件名稱和服務(wù)器上的文件名稱一樣,請(qǐng)?jiān)O(shè)置該參數(shù) */ public static void download(HttpServletResponse response, File file) { download(response, file, null , encoding); } /** * 文件下載 * @param response * @param file 文件 * @param fileName 文件下載到瀏覽器的名稱,如果不想讓瀏覽器下載的文件名稱和服務(wù)器上的文件名稱一樣,請(qǐng)?jiān)O(shè)置該參數(shù) */ public static void download(HttpServletResponse response, File file, String fileName) { download(response, file, fileName, encoding); } /** * 文件下載 * @param response * @param file 文件 * @param fileName 文件下載到瀏覽器的名稱,如果不想讓瀏覽器下載的文件名稱和服務(wù)器上的文件名稱一樣,請(qǐng)?jiān)O(shè)置該參數(shù) * @param encoding 文件名稱編碼 */ public static void download(HttpServletResponse response, File file, String fileName, String encoding) { if (file == null || !file.exists() || file.isDirectory()){ return ; } // 如果不指定文件下載到瀏覽器的名稱,則使用文件的默認(rèn)名稱 if (StringUtils.isBlank(fileName)) { fileName = file.getName(); } try { InputStream is = new FileInputStream(file); download(response, is, fileName, encoding); } catch (IOException e) { e.printStackTrace(); } } /** * 文件下載 * @param response * @param is 文件輸入流 * @param fileName 下載的文件名稱 * @throws IOException */ public static void download(HttpServletResponse response, InputStream is, String fileName){ download(response, is, fileName, encoding); } /** * 文件下載 * @param response * @param is 文件輸入流 * @param fileName 下載的文件名稱 * @param encoding 編碼格式 */ public static void download(HttpServletResponse response, InputStream is, String fileName, String encoding){ if (is == null || StringUtils.isBlank(fileName)){ return ; } BufferedInputStream bis = null ; OutputStream os = null ; BufferedOutputStream bos = null ; try { bis = new BufferedInputStream(is); os = response.getOutputStream(); bos = new BufferedOutputStream(os); response.setContentType( "application/octet-stream;charset=" + encoding); response.setCharacterEncoding(encoding); response.setHeader( "Content-disposition" , "attachment;filename=" + URLEncoder.encode(fileName, encoding)); byte [] buffer = new byte [ 1024 ]; int len = bis.read(buffer); while (len != - 1 ){ bos.write(buffer, 0 , len); len = bis.read(buffer); } bos.flush(); } catch (IOException e){ e.printStackTrace(); } finally { if (bis != null ){ try { bis.close(); } catch (IOException e){} } if (is != null ){ try { is.close(); } catch (IOException e){} } } } public static String getEncoding() { return encoding; } public static void setEncoding(String encoding) { DownloadUtils.encoding = encoding; } } |
如果文件保存在服務(wù)器的非網(wǎng)站目錄下
1
2
|
String filePath = "c:\\file.zip" ; DownloadUtils.download(response, filePath); |
如果文件是輸入流
1
2
3
4
5
6
|
// is為文件輸入流 // fileName為瀏覽器下載的文件名稱 // encoding為文件名稱編碼,預(yù)防文件中有中文的時(shí)候產(chǎn)生亂碼 String fileName = "file.zip" ; String encoding = "utf-8" ; DownloadUtils.download(response, is, fileName, encoding); |
Servlet中文件下載
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
package com.rhui.web.servlet; import java.io.IOException; 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 com.rhui.util.DownloadUtils; @WebServlet ( "/download/servlet" ) public class DownloadServlet extends HttpServlet { private static final long serialVersionUID = 1L; protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String filePath = "c:\\file.zip" ; DownloadUtils.download(response, filePath); } } |
PS:圖片下載(含防盜鏈功能)
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
|
package cn.itcast.day06.web.servlet; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.URLEncoder; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class DownloadServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 實(shí)現(xiàn)防盜鏈功能 // 獲得 referer 頭 用于說(shuō)明來(lái)訪者來(lái)自哪里 String referer = request.getHeader( "referer" ); if (referer== null || !referer.startsWith( "http://localhost" )) { // 是盜鏈者 response.sendRedirect( "/day06/index.jsp" ); return ; } // 解決response中文亂碼問(wèn)題 response.setContentType( "text/html;charset=utf-8" ); // 設(shè)置消息體的編碼 // 通過(guò) http 協(xié)議 發(fā)送的http響應(yīng)消息頭 不能出現(xiàn)中文 中文必須要經(jīng)過(guò)url編碼 String filename = URLEncoder.encode( "美女.jpg" , "utf-8" ); // 通知瀏覽器以下載的方式讀取資源 response.setHeader( "content-disposition" , "attachment;filename=" +filename); // 讀取圖片數(shù)據(jù) 發(fā)給ie瀏覽器 String webPath = "/download/美女.jpg" ; // 相當(dāng)于當(dāng)前web應(yīng)用的path ServletContext servletContext = super .getServletContext(); InputStream in = servletContext.getResourceAsStream(webPath); OutputStream out = response.getOutputStream(); int len; byte [] buffer = new byte [ 1024 ]; while ((len=in.read(buffer))!=- 1 ) out.write(buffer, 0 , len); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } } |