JavaWeb 文件下載功能html
文件下載的實質就是文件拷貝,將文件從服務器端拷貝到瀏覽器端,因此文件下載須要IO技術將服務器端的文件讀取到,而後寫到response緩衝區中,而後再下載到我的客戶端。前端
1. 文件名 - 接受前端發來的文件名java
獲取到前端頁面發送過來的要下載的文件的名字web
String filenameValue = req.getParameter("filename");數據庫
2. ServletContext域 - 獲取到ServletContext域對象瀏覽器
後面將調用此對象的一系列方法,用於獲取文件路徑、文件MimeType,並設置文件輸出類型服務器
ServletContext servletContext = req.getServletContext(); //獲取到ServletContext域對象app
3. 文件路徑 - 獲取指定文件在web項目中的路徑jsp
經過獲取到ServletContext域對象的getRealPath()方法,讀取download目錄下文件的絕對路徑ide
注意:download目錄必須放在webContent目錄下面,不然可能會找不到,致使報異常,在讀取資源的時候,項目demo會直接去查找webContent下面的文件和文件夾
String realPath = servletContext.getRealPath("download/"+filenameValue); //獲取到要下載文件在web項目中的絕對路徑
4. 文件MimeType - 獲取文件的MimeType類型
經過獲取到的 ServletContext 域對象的 getMimeType() 方法,獲取到文件MimeType
MIME (Multipurpose Internet Mail Extensions) 是描述消息內容類型的因特網標準。
MIME 協議指示 MIME 用戶代理如何顯示附加的文件。
MIME 參考手冊:http://www.w3school.com.cn/media/media_mimeref.asp
告知瀏覽器文件的類型:response.setContentType(文件的MIME類型);
String mimeType = servletContext.getMimeType(filenameValue); //獲取到要下載文件的mimeType類型
5. 輸出類型 - 設置文件的輸出類型
根據以前獲取到的文件MimeType,而後經過 Response 域對象的 setContentType() 方法,設置文件的輸出類型
resp.setContentType(mimeType); //設置文件的輸出類型
6. 設置響應頭 - 肯定文件是內嵌或彈出下載框
經過 Response 域對象的 setHeader("Content-Disposition","attachment;filename="+filename) 方法設置響應頭
Content-Disposition(內容處置/處理)
是 MIME 協議的擴展,Content-Disposition 能夠控制用戶請求所得的內容存爲一個文件時提供一個默認的文件名
inline 和 attachment:文件直接在瀏覽器上顯示或者在訪問時彈出文件下載對話框。
inline 表示:內嵌顯示,文本和圖片均可以解析,但對於文件或者視頻會自動去調用成attachment,所以能夠直接使用inline
attachment:彈出下載框,由於attachment是讓文件以附件的形式打開,所以會調用下載,但此下載的功能並無提示
//設置輸出(下載)的文件的默認文件名爲filenameValue的值,inline表示內嵌文本和圖片,文件和視頻會自動調用成attachment
resp.setHeader("Content-Disposition", "inline;filename="+filenameValue);
7. 執行輸出(下載) - IO流
7.1 經過 new,建立字節輸入流 FileInputStream,讀取文件
7.2 經過Response域,建立Servlet的輸出流,輸出文件
FileInputStream fileInputStream = new FileInputStream(realPath);
ServletOutputStream outputStream = resp.getOutputStream();
int b=0;
byte[] by = new byte[1024*8];
while ((b=fileInputStream.read(by))!=-1) {
outputStream.write(by, 0, b);
}
outputStream.flush();
fileInputStream.close();
outputStream.close(); //關流,response得到流會自動關閉,所以也能夠不用手動關
功能實現代碼
Java 代碼 - /demo/src/com/Download.java
package com;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.URLEncoder;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class Download extends HttpServlet{
@Override
public void init(ServletConfig config) throws ServletException {
/**重寫了Servlet的init(ServletConfig config)方法後必定要記得調用父類的init方法,
* 不然在service/doGet/doPost方法中使用getServletContext()方法獲取ServletContext對象時
* 就會出現java.lang.NullPointerException異常
* */
super.init(config);
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
/**1. 接受前端頁面發送過來的文件名字
* 獲取到前端頁面發送過來的要下載的文件的名字
* */
String filenameValue = req.getParameter("filename");
//---------------------
// filenameValue = URLEncoder.encode(filenameValue, "gbk");
/**2. 獲取到ServletContext域對象
* 後面將調用此對象的一系列方法,用於獲取文件路徑、文件MimeType、文件輸出類型
* */
ServletContext servletContext = req.getServletContext(); //獲取到ServletContext域對象
/**3. 獲取指定文件在web項目中的路徑
* 經過獲取到ServletContext域對象的getRealPath()方法,讀取download目錄下文件的絕對路徑
* download目錄必須放在webContent目錄下面,不然可能會找不到,致使報異常,
* 在讀取資源的時候,項目demo會直接去查找webContent下面的文件和文件夾
* */
String realPath = servletContext.getRealPath("download/"+filenameValue); //獲取到要下載文件在web項目中的絕對路徑
/**4. 獲取到文件MimeType
* 經過獲取到的ServletContext域對象的getMimeType()方法,獲取到文件MimeType
* MIME (Multipurpose Internet Mail Extensions) 是描述消息內容類型的因特網標準。
* MIME 協議指示 MIME 用戶代理如何顯示附加的文件。
* MIME 參考手冊:http://www.w3school.com.cn/media/media_mimeref.asp
* */
String mimeType = servletContext.getMimeType(filenameValue); //獲取到要下載文件的mimeType類型
/**5. 設置文件的輸出類型
* Response域對象的setContentType()方法,設置文件的輸出類型
* */
resp.setContentType(mimeType); //設置文件的輸出類型
/**6. 設置響應頭,肯定文件是內嵌或彈出下載框
* 經過 Response 域對象的 setHeader("Content-Disposition","attachment;filename="+filename) 方法設置響應頭,
* Content-Disposition(內容處置/處理) :
* 是 MIME 協議的擴展,Content-Disposition 能夠控制用戶請求所得的內容存爲一個文件的時候提供一個默認的文件名,
* inline 和 attachment :
* 文件直接在瀏覽器上顯示或者在訪問時彈出文件下載對話框。
* inline 表示:內嵌顯示,文本和圖片均可以解析,但對於文件或者視頻會自動去調用成attachment,所以能夠直接使用inline
* attachment:彈出下載框
* URLEncoder 對象,將在響應回去的頭,裏面所代碼filename的編碼格式,轉換爲與客戶端的一致的編碼格式
* URLEncoder.encode(filenameValue,"utf-8"); 將Response響應到瀏覽器客戶端爲filenameValue的文件名,轉變爲utf-8的編碼格式
*/
resp.setHeader("Content-Disposition", "attachment;filename="+URLEncoder.encode(filenameValue,"utf-8")); //設置輸出(下載)的文件的默認文件名爲filenameValue的值,inline表示內嵌文本和圖片
/**7. 輸出文件(下載文件)
* 7.1 經過 new,建立字節輸入流 FileInputStream,讀取文件
* 7.2 經過Response域,建立Servlet的輸出流,輸出文件
* */
FileInputStream fileInputStream = new FileInputStream(realPath);
ServletOutputStream outputStream = resp.getOutputStream();
int b=0;
byte[] by = new byte[1024*8];
while ((b=fileInputStream.read(by))!=-1) {
outputStream.write(by, 0, b);
}
outputStream.flush();
fileInputStream.close();
outputStream.close(); //關流,response得到流會自動關閉,所以也能夠不用手動關
}
}
前端頁面 jsp 代碼 - /demo/WebContent/download.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
String path=request.getContextPath();
String basePath=request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE html>
<html>
<head>
<!-- <base> 標籤爲頁面上的全部連接規定默認地址或默認目標。 -->
<base href="<%=basePath%>">
<meta charset="UTF-8">
<title>文件下載</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
</head>
<body>
<a href="download?filename=JDBC鏈接主流數據庫.txt">點擊下載 文件</a> <br/>
<a href="download?filename=0413102708.avi">點擊下載 視頻</a>
</body>
</html>
web.xml - /demo/WebContent/WEB-INF/web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
<display-name>demo</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<context-param>
<param-name>ServletContextName</param-name>
<param-value>ServletContextValue</param-value>
</context-param>
<servlet>
<servlet-name>Download</servlet-name>
<servlet-class>com.Download</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Download</servlet-name>
<url-pattern>/download</url-pattern>
</servlet-mapping>
</web-app>
下載文件出現中文亂碼和不顯示文件名的狀況
在有些狀況下,若是下載中文文件,頁面在下載時會出現中文亂碼或不能顯示文件名的狀況,緣由是不一樣的瀏覽器默認對下載文件的編碼方式不一樣,好比ie是UTF-8編碼方式,而火狐瀏覽器是Base64編碼方式。
/**URLEncoder 對象,將在響應回去的頭,裏面所代碼filename的編碼格式,轉換爲與客戶端的一致的編碼格式
* URLEncoder.encode(filenameValue,"utf-8");
* 將Response響應到瀏覽器客戶端爲filenameValue的文件名,轉變爲utf-8的編碼格式
* */
resp.setHeader("Content-Disposition", "attachment;filename="+URLEncoder.encode(filenameValue,"utf-8"));
詳細配置信息能夠參考這篇文章:http://blog.ncmem.com/wordpress/2019/08/28/java%e6%89%b9%e9%87%8f%e4%b8%8b%e8%bd%bd/
posted on 2019-08-05 14:05 Xproer-松鼠 閱讀(1187) 評論(0) 編輯 收藏 舉報