文章目錄
- 1. ServletContext 對象的概念
- 2. ServletContext 對象的擷取
- 3. ServletContext 對象的功能
- 4. 檔案下載下傳案例
1. ServletContext 對象的概念
ServletContext 對象代表整個 Web 應用,它可以和 Web 容器通信。
2. ServletContext 對象的擷取
- 通過 Request 對象擷取
request.getServletContext();
- 通過 HttpServlet 擷取
this.getServletContext();
3. ServletContext 對象的功能
- 擷取 MIME 類型
-
MIME 類型的概念
MIME 類型是在網際網路通信過程中定義的一種檔案資料類型,它是檔案類型的标準
- MIME 類型的格式
例如:大類型/小類型
text/html image/jpeg
- 擷取 MIME 類型的方法
- String getMimeType(String file)
- 擷取 MIME 類型練習
運作結果:@WebServlet("/ServletContextDemo2") public class ServletContextDemo2 extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 擷取 ServletContext 對象 ServletContext servletContext = this.getServletContext(); // 定義檔案名稱 String filename = "a.jpg"; // 擷取 MIME 類型 String mimeType = servletContext.getMimeType(filename); System.out.println(mimeType); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request,response); } }
image/jpeg
-
- 域對象
-
域對象的功能
用來共享資料
-
共享資料的範圍
所有使用者所有請求的資料
- 方法
- 存儲資料
- void setAttribute(String name,Object obj)
- 通過鍵擷取值
- Object getAttribute(String name)
- 通過鍵移除鍵值對
- void removeAttribute(String name)
- 存儲資料
-
共享資料的練習
實作 ServletContextDemo3 和 ServletContextDemo4 共享資料
@WebServlet("/ServletContextDemo3") public class ServletContextDemo3 extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 擷取 ServletContext 對象 ServletContext servletContext = this.getServletContext(); // 存儲資料 servletContext.setAttribute("value1","hello"); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request,response); } }
@WebServlet("/ServletContextDemo4") public class ServletContextDemo4 extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 擷取 ServletContext 對象 ServletContext servletContext = this.getServletContext(); // 擷取資料 Object value1 = servletContext.getAttribute("value1"); System.out.println(value1); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request,response); } }
-
- 擷取檔案的真實(伺服器)路徑
- 方法
- String getRealPath(String path)
- 擷取檔案的真實路徑練習
@WebServlet("/ServletContextDemo5") public class ServletContextDemo5 extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 擷取 ServletContext 對象 ServletContext servletContext = this.getServletContext(); // 擷取 web 目錄下的 c.txt 的真實路徑 String realPath1 = servletContext.getRealPath("a.txt"); System.out.println(realPath1); // 擷取 WEB-INF 目錄下的 b.txt 的真實路徑 String realPath2 = servletContext.getRealPath("/WEB-INF/b.txt"); System.out.println(realPath2); // 擷取 src 目錄下的 c.txt 的真實路徑 String realPath3 = servletContext.getRealPath("/WEB-INF/classes/b.txt"); System.out.println(realPath3); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request,response); } }
- 方法
4. 檔案下載下傳案例
- 需求分析
- 頁面顯示超連結
- 點選超連結後彈出下載下傳提示框
- 完成圖檔檔案下載下傳
- 詳細設計
- 定義頁面,編輯超連結 href 屬性,指向 Servlet,設定請求參數,傳遞檔案名稱
- 定義 Servlet
- 擷取請求參數,檔案名稱
- 使用位元組輸入流加載檔案進記憶體
- 設定 response 的響應頭
- 将輸入流資料寫出到 response 輸出流
- 編碼實作
- 定義頁面
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <a href="/DownloadServlet?filename=1.jpg">圖檔1</a> <a href="/DownloadServlet?filename=2.jpg">圖檔2</a> </body> </html>
- 定義 Servlet
@WebServlet("/DownloadServlet") public class DownloadServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 1.擷取請求參數,檔案名稱 String filename = request.getParameter("filename"); // 2.使用位元組輸入流加載檔案進記憶體 // 2.1 找到檔案的真實路徑 ServletContext servletContext = this.getServletContext(); String realPath = servletContext.getRealPath("/img/"+filename); // 2.2 用位元組流關聯 FileInputStream fileInputStream = new FileInputStream(realPath); // 3. 設定 Response 的響應頭 // 3.1 擷取檔案類型 String mimeType = servletContext.getMimeType(filename); // 3.2 設定響應頭類型 response.setHeader("Content-type",mimeType); // 3.3 設定響應頭打開方式 response.setHeader("Content-disposition","attachment;filename="+filename); //4.将輸入流的資料寫出到 response 輸出流中 ServletOutputStream outputStream = response.getOutputStream(); byte[] buff = new byte[1024 * 8]; int len = 0; while((len = fileInputStream.read(buff)) != -1){ outputStream.write(buff,0,len); } fileInputStream.close(); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request,response); } }
- 定義頁面
- 中文檔案問題
-
問題
如果檔案名是中文,下載下傳後的檔案名稱無法顯示
- 解決思路
- 擷取用戶端使用的浏覽器版本資訊
- 根據不同的版本資訊,設定 filename 的編碼方式不同
- 解決步驟
- 建立一個 utils 包,在其中建立一個工具類 DownLoadUtils,它可以根據浏覽器設定 filename 的編碼
package com.zt.web.utils; import sun.misc.BASE64Encoder; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; public class DownLoadUtils { public static String getFileName(String agent, String filename) throws UnsupportedEncodingException { if (agent.contains("MSIE")) { // IE浏覽器 filename = URLEncoder.encode(filename, "utf-8"); filename = filename.replace("+", " "); } else if (agent.contains("Firefox")) { // 火狐浏覽器 BASE64Encoder base64Encoder = new BASE64Encoder(); filename = "=?utf-8?B?" + base64Encoder.encode(filename.getBytes("utf-8")) + "?="; } else { // 其它浏覽器 filename = URLEncoder.encode(filename, "utf-8"); } return filename; } }
- 在 Servlet 中使用工具類方法編碼檔案名
@WebServlet("/DownloadServlet") public class DownloadServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 1.擷取請求參數,檔案名稱 String filename = request.getParameter("filename"); // 2.使用位元組輸入流加載檔案進記憶體 // 2.1 找到檔案的真實路徑 ServletContext servletContext = this.getServletContext(); String realPath = servletContext.getRealPath("/img/"+filename); // 2.2 用位元組流關聯 FileInputStream fileInputStream = new FileInputStream(realPath); // 3. 設定 Response 的響應頭 // 3.1 擷取檔案類型 String mimeType = servletContext.getMimeType(filename); // 3.2 設定響應頭類型 response.setHeader("Content-type",mimeType); // 3.3 解決中文檔案名問題 // 3.3.1.擷取 user-agent 請求頭 String agent = request.getHeader("user-agent"); // 3.3.2.使用工具類方法編碼檔案名即可 filename = DownLoadUtils.getFileName(agent, filename); // 3.4 設定響應頭打開方式 response.setHeader("Content-disposition","attachment;filename="+filename); //4.将輸入流的資料寫出到 response 輸出流中 ServletOutputStream outputStream = response.getOutputStream(); byte[] buff = new byte[1024 * 8]; int len = 0; while((len = fileInputStream.read(buff)) != -1){ outputStream.write(buff,0,len); } fileInputStream.close(); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request,response); } }
- 建立一個 utils 包,在其中建立一個工具類 DownLoadUtils,它可以根據浏覽器設定 filename 的編碼
-