target
了解使用 JavaWeb方式的文件上傳
掌握文件上傳的表單設(shè)置
掌握使用 SpringMVC 進(jìn)行文件上傳
理解使用SpringMVC進(jìn)行文件下載
文件上傳你是任何一個項目都必不缺少的,抖音里面頭像的上傳,QQ里面視頻的上傳嚷量,拼多多里面商品詳情介紹等,文件上傳隨處可見蜓竹。下面介紹JavaWeb方式的原始上傳和SpringMVC方式的上傳。
1. 文件上傳-JavaWeb方式
對于文件上傳储藐,瀏覽器在上傳的過程中是將文件以流的形式提交到服務(wù)器端的俱济,如果直接使用Servlet獲取上傳文件的輸入流然后再解析里面的請求參數(shù)是比較麻煩,所以一般選擇采用apache的開源工具common-fileupload
這個文件上傳組件钙勃。common-fileupload
是依賴于common-io
這個包的蛛碌,所以還需要下載這個包。
新建動態(tài)Web項目:FileUpload-1
在WebContent目錄下新建上傳表單:upload.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>文件上傳</title>
</head>
<body>
<form method="post" action="${pageContext.servletContext.contextPath }/upload"
enctype="multipart/form-data">
上傳用戶:<input type="text" name="username"><br>
上傳文件:<input type="file" name="myfile" multiple="multiple"><br>
<input type="submit" value="上傳">
</form>
</body>
</html>
新建 UploadServlet類處理文件上傳:
package com.lee.servlet;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
@WebServlet("/upload")
public class UploadServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
private static final int FILE_SIZE = 10;// 單個文件最大值
private static final String EXT_NAME = "gif,pdf,dmg,jpg,jpeg,png,bmp,swf,flv,mp3,wav,wma,wmv,mid,avi,mpg,asf,rm,rmvb,doc,docx,xls,xlsx,ppt,htm,html,txt,zip,rar,gz,bz2";// 定義允許上傳的文件名
private static final String savePath = "WEB-INF/upload";
private static final String temPath = "WEB-INF/tem";
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 得到上傳文件的保存目錄辖源,將上傳文件存放在WEB-INF目錄下蔚携,不允許外界直接訪問,保證上傳文件的安全
String saveRealPath = this.getServletContext().getRealPath(savePath);
createDir(saveRealPath);// 創(chuàng)建WEB-INF/upload目錄
// 上傳時生成臨時文件保存目錄
String saveTemPath = this.getServletContext().getRealPath(temPath);
File temDir = createDir(saveTemPath);// 創(chuàng)建WEB-INF/tem文件夾
String message = "";// 消息提醒
String fileName = "";// 上傳的文件名
// 使用Apache文件上傳組件處理文件上傳步驟
try {
/**
* 1.創(chuàng)建DiskFileItemFactory對象
*/
DiskFileItemFactory factory = new DiskFileItemFactory();
// 設(shè)置工廠的緩沖區(qū)大小克饶,當(dāng)上傳的文件大小超過緩沖區(qū)大小時酝蜒,就會生成一個臨時文件存放在指定的臨時目錄之中
// 設(shè)置緩沖區(qū)大小為100kb,如果不設(shè)置矾湃,默認(rèn)緩沖區(qū)大小是10kb
factory.setSizeThreshold(1024 * 100);
// 設(shè)置上傳時生成的臨時文件的保存目錄
factory.setRepository(temDir);
/**
* 2.創(chuàng)建文件上傳解析器
*/
ServletFileUpload upload = new ServletFileUpload(factory);
// 解決上傳文件名的中文亂碼問題
upload.setHeaderEncoding("UTF-8");
// 判斷提交上來的數(shù)據(jù)是否是文件表單
if (!ServletFileUpload.isMultipartContent(req)) {
// 終止文件上傳處理
return;
}
// 獲取文件表單中的所有文件
List<FileItem> items = upload.parseRequest(req);
for (FileItem item : items) {
if (item.isFormField()) {// formfield中封裝的是普通的輸入項數(shù)據(jù)
String name = item.getFieldName();
// 解決輸入項數(shù)據(jù)中文亂碼問題
String value = item.getString("UTF-8");
// value = new String(value.getBytes("iso8859-1"),"UTF-8");
System.out.println(name + "=" + value);
} else {// formfield中封裝的是上傳文件
fileName = item.getName();// 得到文件上傳名
System.out.println("文件名:" + fileName);
if (fileName == null || fileName.trim().length() == 0) {
continue;
}
/**
* 注意:不同的瀏覽器提交的文件名是不一樣的亡脑,有些瀏覽器提交上來的文件名是帶有路徑的 如: C:\Users\H__D\Desktop\1.txt
* 而有些則是: 1.txt
*/
// 處理獲取到的上傳文件的文件名的路徑部分,只保留文件名部分
fileName = fileName.substring(fileName.lastIndexOf(File.separator) + 1);
// 得到上傳文件的擴(kuò)展名
String fileExt = fileName.substring(fileName.lastIndexOf(".") + 1).toLowerCase();
// 通過擴(kuò)展名判斷上傳文件是否合法
System.out.println("上傳文件的擴(kuò)展名是:" + fileExt);
if (!EXT_NAME.contains(fileExt)) {
System.out.println("不允許上傳" + fileExt + "格式的文件邀跃!");
message += "文件:" + fileName + ",上傳文件擴(kuò)展名不允許是" + fileExt + "<br>";
continue;
}
// 檢查文件大小
if (item.getSize() == 0 || item.getSize() > FILE_SIZE * 1024 * 1024) {
message += "文件大小為:" + item.getSize() / 1024 / 1024 + "M,規(guī)定大小不超過" + FILE_SIZE + "M<br>";
continue;
}
// 得到存儲的文件名
String saveFileName = makeFileName(fileName);
// 獲取item中上傳文件的輸入流
InputStream is = item.getInputStream();
// 創(chuàng)建文件輸出流
FileOutputStream out = new FileOutputStream(saveRealPath + File.separator + saveFileName);
// 創(chuàng)建一個緩沖區(qū)
byte[] b = new byte[1024];
int len = 0;
while ((len = is.read(b)) > 0) {
out.write(b, 0, len);
}
// 關(guān)閉流
out.close();
is.close();
// 刪除臨時文件
item.delete();
message += "文件:" + fileName + "上傳成功!<br>";
}
}
} catch (Exception e) {
System.out.println(e.getMessage());
message += fileName + "上傳失斆棺伞!";
}
req.setAttribute("message", message);
req.getRequestDispatcher("WEB-INF/views/message.jsp").forward(req, resp);
}
/**
* 為防止文件覆蓋現(xiàn)象坞嘀,為上傳文件產(chǎn)生一個唯一的文件名
*
* @param fileName
* @return
*/
private String makeFileName(String fileName) {
return UUID.randomUUID().toString().replaceAll("-", "") + "_" + fileName;
}
/**
* 創(chuàng)建目錄
*
* @param path
*/
private File createDir(String path) {
File pathDir = new File(path);
if (!pathDir.exists()) {
// 創(chuàng)建WEB-INF/upload目錄
pathDir.mkdirs();
}
return pathDir;
}
}
在WEB-INF/views目錄下新建消息頁面:message.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>提示</title>
</head>
<body>
${message }
</body>
</html>
訪問地址:http://localhost:8080/File/upload.jsp
此種方式可以上傳一個或多個文件躯护。
文件上傳到服務(wù)器的位置"upload",該位置是指:workspace/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps
幾個細(xì)節(jié):
①為保證服務(wù)器安全惊来,上傳文件應(yīng)該放在外界無法直接訪問的目錄下丽涩,比如放于WEB-INF目錄下。
②為防止文件覆蓋的現(xiàn)象發(fā)生,要為上傳文件產(chǎn)生一個唯一的文件名矢渊。
③要限制上傳文件的最大值继准。
④要限制上傳文件的類型,在收到上傳文件名時矮男,判斷后綴名是否合法移必。
⑤表單的enctype="multipart/form-data" method="post"
2. 文件上傳-SpringMVC方式
Spring MVC 框架的文件上傳是基于 commons-fileupload 組件的文件上傳,只不過 Spring MVC 框架在原有文件上傳組件上做了進(jìn)一步封裝毡鉴,簡化了文件上傳的代碼實現(xiàn)崔泵,取消了不同上傳組件上的編程差異。
commons-fileupload 組件依賴于 Apache 的另外一個項目(commons-io)猪瞬,因此需要導(dǎo)入commons-io的jar包憎瘸。
Commons 是 Apache 開放源代碼組織中的一個 Java子項目,該項目包括文件上傳陈瘦、命令行處理幌甘、數(shù)據(jù)庫連接池、XML 配置文件處理等模塊痊项。fileupload 就是其中用來處理基于表單的文件上傳的子項目锅风,commons-fileupload 組件性能優(yōu)良,并支持任意大小文件的上傳鞍泉。
2.1 表單屬性
由于多數(shù)文件上傳都是通過表單形式提交給后臺服務(wù)器的皱埠,因此,要實現(xiàn)文件上傳功能咖驮,就需要提供一個文件上傳的表單漱逸。同時該表單必須滿足以下3個條件:
- form表單的method屬性設(shè)置為post;
- form表單的enctype屬性設(shè)置為
multipart/form-data
游沿; - 提供
<input type="file" name="fileName" />
的文件上傳輸入框饰抒。
表單的 enctype 屬性指定的是表單數(shù)據(jù)的編碼方式,該屬性有以下 3 個值:
- application/x-www-form-urlencoded:這是默認(rèn)的編碼方式诀黍,它只處理表單域里的 value 屬性值袋坑。
- multipart/form-data:該編碼方式以二進(jìn)制流的方式來處理表單數(shù)據(jù),并將文件域指定文件的內(nèi)容封裝到請求參數(shù)里眯勾。
- text/plain:該編碼方式只有當(dāng)表單的 action 屬性為“mailto:”URL 的形式時才使用枣宫,主要適用于直接通過表單發(fā)送郵件的方式。
在HTML5之前吃环,如果想要上傳多個文件也颤,必須使用多個<input>
元素。但是在HTML5中郁轻,在<input>
元素配置multiple屬性即可進(jìn)行多個文件的上傳:
<input type="file" name="fileName" multiple />
2.3 MultipartFile接口
在 Spring MVC 框架中上傳文件時將文件相關(guān)信息及操作封裝到 MultipartFile 對象中翅娶,因此開發(fā)者只需要使用 MultipartFile 類型聲明模型類的一個屬性即可對被上傳文件進(jìn)行操作文留。該接口具有如下方法:
名稱 | 作用 |
---|---|
byte[] getBytes() | 以字節(jié)數(shù)組的形式返回文件的內(nèi)容 |
String getContentType() | 返回文件的內(nèi)容類型 |
InputStream getInputStream() | 返回一個InputStream,從中讀取文件的內(nèi)容 |
String getName() | 返回請求參數(shù)的名稱 |
String getOriginalFillename() | 返回客戶端提交的原始文件名稱 |
long getSize() | 返回文件的大小竭沫,單位為字節(jié) |
boolean isEmpty() | 判斷被上傳文件是否為空 |
void transferTo(File destination) | 將上傳文件保存到目標(biāo)目錄下 |
在上傳文件時需要在配置文件中使用 Spring 的 org.springframework.web.multipart.commons.CommonsMultipartResolver 類配置 MultipartResolver
用于文件上傳燥翅。
2.3 springmvc配置文件
當(dāng)客戶端form表單的enctype屬性為multipart/form-data時,瀏覽器就會采用二進(jìn)制流的方式來處理表單數(shù)據(jù)蜕提,而對于文件上傳的處理則涉及在服務(wù)器端解析原始的HTTP請求森书。Spring MVC為文件上傳提供了直接的支持,這種支持是用即插即用的MultipartResolver實現(xiàn)的谎势。
在Sring MVC中使用MultipartResolver也非常簡單凛膏,只需要在Spring MVC配置文件springmvc.xml中定義MultipartResolver接口實現(xiàn)類即可,示例如下:
<!-- 配置文件解析器 -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- 設(shè)置最大允許上傳的文件的大小脏榆,單位是B -->
<property name="maxUploadSize" value="50000000"></property>
<!-- 設(shè)置最大允許上傳的單個文件的大小译柏,單位是B -->
<property name="maxUploadSizePerFile" value="10000000"></property>
<property name="defaultEncoding" value="UTF-8"></property>
</bean>
注意:
由于MultipartResolver實現(xiàn)類CommonsMultipartResolver
內(nèi)部是引用multipartResolver字符串獲取該實現(xiàn)類對象并完成文件上傳操作的,所以在配置CommonsMultipartResolver
時必須指定該bean的id為multipartResolver姐霍。
由于MultipartResolver實現(xiàn)類CommonsMultipartResolver是Spring MVC內(nèi)部通過Apache Commons FileUpload技術(shù)實現(xiàn)的鄙麦。因此Spirng MVC的文件上傳還需要依賴Apache Commons FileUpload的組件,即需要導(dǎo)入支持文件上傳和下載的JAR包镊折,具體如下:
- commons-fileupload.jar
- commons-io.jar
2.4 代碼實現(xiàn)
新建動態(tài)Web項目:FileUpload-2
① 引入 jar
將一下jar 復(fù)制到lib文件夾下:
commons-fileupload-1.4.jar
commons-io-2.6.jar
commons-logging-1.2.jar
spring-aop-4.3.9.RELEASE.jar
spring-beans-4.3.9.RELEASE.jar
spring-context-4.3.9.RELEASE.jar
spring-core-4.3.9.RELEASE.jar
spring-expression-4.3.9.RELEASE.jar
spring-web-4.3.9.RELEASE.jar
spring-webmvc-4.3.9.RELEASE.jar
② 創(chuàng)建 web.xml 文件
在 WEB-INF 目錄下創(chuàng)建 web.xml 文件胯府。為防止中文亂碼,需要在 web.xml 文件中添加字符編碼過濾器恨胚。
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
<display-name>FileUpload-2</display-name>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- The front controller of this Spring Web application, responsible for
handling all application requests -->
<servlet>
<servlet-name>springDispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<!-- Map all requests to the DispatcherServlet for handling -->
<servlet-mapping>
<servlet-name>springDispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
③ 創(chuàng)建 springmvc配置文件
在 src 下配置 springmvc.xml 骂因,配置包掃描、視圖解析器以及文件上傳相關(guān)設(shè)置赃泡。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">
<!-- 使用掃描機(jī)制掃描控制器類 -->
<context:component-scan
base-package="com.lee.controller" />
<!-- 配置視圖解析器 -->
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/" />
<property name="suffix" value=".jsp" />
</bean>
<!-- 配置文件解析器 -->
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- 設(shè)置最大允許上傳的文件的大小寒波,單位是B -->
<property name="maxUploadSize" value="1000000000"></property>
<!-- 設(shè)置最大允許上傳的單個文件的大小,單位是B -->
<property name="maxUploadSizePerFile" value="100000000"></property>
<property name="defaultEncoding" value="UTF-8"></property>
</bean>
</beans>
開發(fā)經(jīng)驗:一定要加上id="multipartResolver"
升熊,否則會報錯400俄烁。
④ 文件上傳頁面
在 WebContent 目錄下創(chuàng)建 JSP頁面 upload.jsp,在該頁面中使用表單上傳文件(可以一個或多個文件呢)级野,具體代碼如下:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>SpringMVC方式上傳</title>
</head>
<body>
<form action="${pageContext.servletContext.contextPath }/upload" method="post" enctype="multipart/form-data">
上傳文件:<input type="file" name="files" multiple />
<input type="submit" value="上傳">
</form>
</body>
</html>
⑤ 創(chuàng)建控制器類
package com.lee.controller;
@Controller
public class UploadController {
private static final String EXT_NAME = "gif,pdf,dmg,jpg,jpeg,png,bmp,swf,flv,mp3,wav,wma,wmv,mid,avi,mpg,asf,rm,rmvb,doc,docx,xls,xlsx,ppt,htm,html,txt,zip,rar,gz,bz2";// 定義允許上傳的文件名
private static final String SAVE_PATH = "WEB-INF/upload";
@RequestMapping("/upload")
public String fileUpload(@RequestParam("files") List<MultipartFile> files, HttpServletRequest req,
Map<String, Object> map) {
String message = "";
// 對上傳的文件進(jìn)行解析
if (files != null && files.size() > 0) {
for (MultipartFile file : files) {
// 獲取文件的原始名字
String filename = file.getOriginalFilename();
// 設(shè)置文件保存目錄
String saveRealPath = req.getServletContext().getRealPath(SAVE_PATH);
File saveDir = new File(saveRealPath);
if (!saveDir.exists()) {
saveDir.mkdirs();
}
// 判斷文件格式是否符合
String extFileName = filename.substring(filename.lastIndexOf(".") + 1);
if (!EXT_NAME.contains(extFileName)) {
message += filename + "格式不符合页屠!<br>";
map.put("message", message);
continue;
}
// 設(shè)置保存文件的名字:UUID或者時間進(jìn)行重新命名
String newFileName = UUID.randomUUID().toString().replaceAll("-", "") + "_" + filename;
// 使用multipartFile接口上傳
try {
File saveFile = new File(saveRealPath + File.separator + newFileName);
file.transferTo(saveFile);
message += filename + "上傳成功!<br>";
} catch (Exception e) {
e.printStackTrace();
message += filename + "上傳失敱腿帷辰企!<br>";
}
map.put("message", message);
}
}
return "success";
}
}
⑥ 創(chuàng)建成功顯示頁面
在 WEB-INF/views 目錄下創(chuàng)建頁面 success.jsp。具體代碼如下:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>提示</title>
</head>
<body>
${message }
</body>
</html>
部署項目况鸣,進(jìn)行測試牢贸,可以選擇一個或多個文件測試。
3. 文件下載
3.1 實現(xiàn)方法
實現(xiàn)文件下載有以下兩種方法:
- 通過超鏈接實現(xiàn)下載镐捧。
- 利用程序編碼實現(xiàn)下載潜索。
通過超鏈接實現(xiàn)下載固然簡單臭增,但暴露了下載文件的真實位置,并且只能下載存放在 Web 應(yīng)用程序所在的目錄下的文件帮辟。
利用程序編碼實現(xiàn)下載可以增加安全訪問控制,還可以從任意位置提供下載的數(shù)據(jù)玩焰,可以將文件存放到 Web 應(yīng)用程序以外的目錄中由驹,也可以將文件保存到數(shù)據(jù)庫中。
利用程序?qū)崿F(xiàn)下載需要設(shè)置兩個報頭:
① Web 服務(wù)器需要告訴瀏覽器其所輸出內(nèi)容的類型不是普通文本文件或 HTML 文件昔园,而是一個要保存到本地的下載文件蔓榄,這需要設(shè)置 Content-Type 的值為 application/x-msdownload。
② Web 服務(wù)器希望瀏覽器不直接處理相應(yīng)的實體內(nèi)容默刚,而是由用戶選擇將相應(yīng)的實體內(nèi)容保存到一個文件中甥郑,這需要設(shè)置 Content-Disposition 報頭。
該報頭指定了接收程序處理數(shù)據(jù)內(nèi)容的方式荤西,在 HTTP 應(yīng)用中只有 attachment 是標(biāo)準(zhǔn)方式澜搅,attachment 表示要求用戶干預(yù)。在 attachment 后面還可以指定 filename 參數(shù)邪锌,該參數(shù)是服務(wù)器建議瀏覽器將實體內(nèi)容保存到文件中的文件名稱勉躺。
設(shè)置報頭的示例如下:
response.setHeader("Content-Type", "application/x-msdownload");
response.setHeader("Content-Disposition", "attachment;filename="+filename);
3.2 代碼實現(xiàn)
下面繼續(xù)通過 FileUpload-2 應(yīng)用講述利用程序?qū)崿F(xiàn)下載的過程,要求從(workspace.metadata.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\WEB-INF\uploadf)中下載文件觅丰,具體開發(fā)步驟如下:
① 編寫控制器類
首先編寫控制器類 FileDownController饵溅,在該類中有 3 個方法棋凳,即 show咐扭、down 和 toUTF8String。其中路呜,show 方法獲取被下載的文件名稱冠句;down 方法執(zhí)行下載功能轻掩;toUTF8String 方法是下載保存時中文文件名的字符編碼轉(zhuǎn)換方法。
package com.lee.controller;
@Controller
public class FileDownController {
/**
* 顯示要下載的文件
*/
@RequestMapping("showDownFiles")
public String show(HttpServletRequest request, Model model) {
// 從 workspace\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\下載
String realpath = request.getServletContext()
.getRealPath("WEB-INF/upload");
File dir = new File(realpath);
File files[] = dir.listFiles();
// 獲取該目錄下的所有文件名
ArrayList<String> fileName = new ArrayList<String>();
for (int i = 0; i < files.length; i++) {
fileName.add(files[i].getName());
}
model.addAttribute("files", fileName);
return "showDownFiles";
}
/**
* 執(zhí)行下載
*/
@RequestMapping("down")
public String down(@RequestParam String filename,
HttpServletRequest request, HttpServletResponse response) {
String aFilePath = null; // 要下載的文件路徑
FileInputStream in = null; // 輸入流
ServletOutputStream out = null; // 輸出流
try {
// 從workspace\.metadata\.plugins\org.eclipse.wst.server.core\
// tmp0\wtpwebapps下載
aFilePath = request.getServletContext().getRealPath("WEB-INF/upload");
// 設(shè)置下載文件使用的報頭
response.setHeader("Content-Type", "application/x-msdownload");
response.setHeader("Content-Disposition", "attachment; filename="
+ toUTF8String(filename));
// 讀入文件
in = new FileInputStream(aFilePath + File.separator+ filename);
// 得到響應(yīng)對象的輸出流懦底,用于向客戶端輸出二進(jìn)制數(shù)據(jù)
out = response.getOutputStream();
out.flush();
int aRead = 0;
byte b[] = new byte[1024];
while ((aRead = in.read(b)) != -1 & in != null) {
out.write(b, 0, aRead);
}
out.flush();
in.close();
out.close();
} catch (Throwable e) {
e.printStackTrace();
}
return null;
}
/**
* 下載保存時中文文件名的字符編碼轉(zhuǎn)換方法
*/
public String toUTF8String(String str) {
StringBuffer sb = new StringBuffer();
int len = str.length();
for (int i = 0; i < len; i++) {
// 取出字符中的每個字符
char c = str.charAt(i);
// Unicode碼值為0~255時放典,不做處理
if (c >= 0 && c <= 255) {
sb.append(c);
} else { // 轉(zhuǎn)換 UTF-8 編碼
byte b[];
try {
b = Character.toString(c).getBytes("UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
b = null;
}
// 轉(zhuǎn)換為%HH的字符串形式
for (int j = 0; j < b.length; j++) {
int k = b[j];
if (k < 0) {
k &= 255;
}
sb.append("%" + Integer.toHexString(k).toUpperCase());
}
}
}
return sb.toString();
}
}
② 創(chuàng)建文件列表頁面
下載文件示例需要一個顯示被下載文件的 JSP 頁面 showDownFiles.jsp,在WEB-INF/views目錄下編寫基茵,代碼如下:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<table>
<tr>
<td>被下載的文件名</td>
</tr>
<!--遍歷 model中的 files-->
<c:forEach items="${files}" var="filename">
<tr>
<td>
<a href="${pageContext.request.contextPath }/down?filename=${filename}">${filename}</a>
</td>
</tr>
</c:forEach>
</table>
</body>
</html>
③ 測試下載功能
將應(yīng)用部署到到 Tomcat 服務(wù)器并啟動 Tomcat 服務(wù)器奋构,然后通過地址"http://localhost:8080/FileUpload-2/showDownFiles"測試下載示例。