Java Web開發中文件的(de)上(shàng)傳與下載
發表時(shí)間:2019-8-7
發布人(rén):融晨科技
浏覽次數:46
如何實現文件的(de)上(shàng)傳
實現Web開發中文件上(shàng)傳功能的(de)兩個(gè)步驟:
- 在(zài)Web頁面添加上(shàng)傳輸入項
- 在(zài)Servlet中讀取上(shàng)傳文件的(de)數據并保存到(dào)本地(dì / de)硬盤中
由于(yú)大(dà)多數文件的(de)上(shàng)傳都是(shì)通過表單 的(de)形式提交給服務器的(de),故需要(yào / yāo)先創建一個(gè)用于(yú)提交上(shàng)傳文件的(de)表單頁面。
實現文件上(shàng)傳的(de)表單頁面需如下配置:
- 首先要(yào / yāo)創建一個(gè)用于(yú)提交上(shàng)傳文件的(de)表單頁面
- 在(zài)頁面中,需要(yào / yāo)使用 < input type=“file”> 标簽在(zài)Web頁面中添加文件上(shàng)傳輸入項
- 必須要(yào / yāo)設置input輸入項的(de)name屬性,否則浏覽器将不(bù)會發送上(shàng)傳文件的(de)數據
- 必須把将表單頁面的(de)method屬性設置爲(wéi / wèi)post方式,enctype屬性設置爲(wéi / wèi) “multipart/form-data” 類型。
示例代碼:
<%--指定表單的(de)enctype屬性以(yǐ)及提交方式--%>
<form enctype="multipart/form-data" method="post">
<%--指定标記的(de)類型和(hé / huò)文件域的(de)名稱--%>
選擇上(shàng)傳文件:< inpurt type="file" name="myfile"/><br />
</form>
Apache組織提供一個(gè)開源組件Commons-FileUpload,可以(yǐ)方便的(de)将 “multipart/form-data” 類型請求中的(de)各種表單域解析出(chū)來(lái),并實現一個(gè)或多個(gè)文件的(de)上(shàng)傳,同時(shí)也(yě)可以(yǐ)限制上(shàng)傳文件的(de)大(dà)小等内容。使用時(shí)需要(yào / yāo)導入commons-fileupload.jar和(hé / huò)commons-io.jar兩個(gè)JAR包,可去官網:"http://commons.apache.org/"下載(在(zài)網址頁面Apache Commons Proper下方表格的(de)Components列中的(de)FileUpload和(hé / huò)IO)。
如何實現文件的(de)下載
實現文件下載不(bù)需要(yào / yāo)使用第三方組件,直接使用Servlet類和(hé / huò)輸入/輸出(chū)流即可。
與訪問服務器文件不(bù)同的(de)是(shì),要(yào / yāo)實現文件的(de)下載,不(bù)僅需要(yào / yāo)指定文件的(de)路徑,還需要(yào / yāo)在(zài)HTTP協議中設置兩個(gè)響應消息頭:
//設置接受程序處理方式
Content-Disposition:attachment;filename=
//設定實體内容的(de)MIME類型(多用途互聯網郵件擴展類型)
Content-Type:appliccation/x-msdownload
簡述文件下載的(de)實現原理:
首先獲取下載文件的(de)地(dì / de)址,并根據該地(dì / de)址創建文件字節輸入流,然後通過該流讀取下載文件内容,最後将讀取的(de)内容通過輸出(chū)流寫到(dào)目标文件中。
實例問題一:
請按照以(yǐ)下要(yào / yāo)求設計一個(gè)實現文件上(shàng)傳的(de)類UploadServlet?
要(yào / yāo)求如下:
1) 已知form.html文件中form表單内定義了(le/liǎo)一個(gè)名爲(wéi / wèi)name的(de)文本框及名爲(wéi / wèi)myfile的(de)文件域,具備文件上(shàng)傳的(de)前提條件。
2)在(zài)doPost()方法中,寫出(chū)文件上(shàng)傳的(de)相關代碼。
3)上(shàng)傳的(de)文件保存在(zài)當前應用程序的(de)upload文件夾下。
解:UploadServlet代碼如下:
public class UploadServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
try { // 創建工廠
DiskFileItemFactory factory = new DiskFileItemFactory();
factory.setRepository(new File("e:\\Target"));
ServletFileUpload fileupload = new ServletFileUpload(factory); // 創建 fileupload 組件
fileupload.setHeaderEncoding("utf-8");
List<FileItem> fileitems = fileupload.parseRequest(request); // 解析 request
PrintWriter writer = response.getWriter();
for (FileItem fileitem : fileitems) { // 遍曆集合
if (fileitem.isFormField()) { // 判斷是(shì)否爲(wéi / wèi)普通字段
String name = fileitem.getFieldName(); // 獲得字段名和(hé / huò)字段值
String value = fileitem.getString("utf-8");
} else { // 上(shàng)傳的(de)文件路徑
String filename = fileitem.getName();
writer.print("文件來(lái)源:" + filename + "<br>");
filename = filename // 截取出(chū)文件名
.substring(filename.lastIndexOf("\\") + 1);
writer.print("成功上(shàng)傳的(de)文件:" + filename + "<br>");
filename = UUID.randomUUID().toString() + "_" + filename; // 文件名需要(yào / yāo)唯一
String webPath = "/upload/" + filename; // 在(zài)服務器創建同名文件
String path = getServletContext().getRealPath(webPath);
File file = new File(path); // 創建文件
file.getParentFile().mkdirs();
file.createNewFile();
InputStream in = fileitem.getInputStream(); // 獲得上(shàng)傳文件流
OutputStream out = new FileOutputStream(file); // 獲得寫入文件流
byte[] buffer = new byte[1024]; // 流的(de)對拷
int len;
while ((len = in.read(buffer)) > 0)
out.write(buffer, 0, len);
in.close(); // 關流
out.close();
fileitem.delete(); // 删除臨時(shí)文件
}
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
實例問題二:
請編寫一個(gè)用于(yú)實現文件下載的(de)程序,并且保證下載文件的(de)文件名不(bù)能出(chū)現中文亂碼問題?
解:
該功能的(de)實現步驟如下:
(1)創建下載頁面download.jsp
<%@ page language="java" import="java.util.*" 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="${pagContext.request.contextPath}/chapter06/DownloadServlet"}>
文件下載
</a>
<br />
</body>
</html>
(2)編寫DownloadServlet類,該類主要(yào / yāo)用于(yú)設置所要(yào / yāo)下載的(de)文件以(yǐ)及文件在(zài)浏覽器中的(de)打開方式,并使用 encode(String s, String enc) 方法,将URL中的(de)字符串以(yǐ)指定的(de)編碼形式輸出(chū),防止文件名出(chū)現中文亂碼問題
import java.io.*;
import java.net.URLEncoder;
import javax.servlet.*;
import javax.servlet.http.*;
public class DownloadServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
// 獲得絕對路徑創建文件對象
String path=getServletContext().getRealPath("/download/人(rén)物.jpg");
File file=new File(path);
// 通知浏覽器以(yǐ)下載的(de)方式打開文件
response.addHeader("Content-Type", "application/octet-stream");
response.addHeader("Content-Disposition","attachment;filename="
+URLEncoder.encode(file.getName(),"utf-8"));
InputStream in=new FileInputStream(file); // 通過文件對象獲取文件相關的(de)輸入流
OutputStream out = response.getOutputStream(); // 獲取response對象的(de)輸出(chū)流
byte [] buffer=new byte[1024];
int len;
while((len=in.read(buffer))!=-1){
out.write(buffer,0,len);
}
}
public void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
doGet(req, resp);
}
}
(3)使用IE浏覽器訪問該download.jsp,單擊頁面中的(de)文件下載鏈接後,即可保存下載該文件