天天看點

ServletContext1. ServletContext 對象的概念2. ServletContext 對象的擷取3. ServletContext 對象的功能4. 檔案下載下傳案例

文章目錄

  • 1. ServletContext 對象的概念
  • 2. ServletContext 對象的擷取
  • 3. ServletContext 對象的功能
  • 4. 檔案下載下傳案例

1. ServletContext 對象的概念

ServletContext 對象代表整個 Web 應用,它可以和 Web 容器通信。

2. ServletContext 對象的擷取

  1. 通過 Request 對象擷取
    request.getServletContext();
               
  2. 通過 HttpServlet 擷取
    this.getServletContext();
               

3. ServletContext 對象的功能

  1. 擷取 MIME 類型
    1. MIME 類型的概念

      MIME 類型是在網際網路通信過程中定義的一種檔案資料類型,它是檔案類型的标準

    2. MIME 類型的格式
      大類型/小類型
                 
      例如:
      text/html	image/jpeg
                 
    3. 擷取 MIME 類型的方法
      • String getMimeType(String file)
    4. 擷取 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
                 
  2. 域對象
    1. 域對象的功能

      用來共享資料

    2. 共享資料的範圍

      所有使用者所有請求的資料

    3. 方法
      1. 存儲資料
        • void setAttribute(String name,Object obj)
      2. 通過鍵擷取值
        • Object getAttribute(String name)
      3. 通過鍵移除鍵值對
        • void removeAttribute(String name)
    4. 共享資料的練習

      實作 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);
          }
      }
                 
  3. 擷取檔案的真實(伺服器)路徑
    1. 方法
      • String getRealPath(String path)
    2. 擷取檔案的真實路徑練習
      @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. 檔案下載下傳案例

  1. 需求分析
    1. 頁面顯示超連結
    2. 點選超連結後彈出下載下傳提示框
    3. 完成圖檔檔案下載下傳
  2. 詳細設計
    1. 定義頁面,編輯超連結 href 屬性,指向 Servlet,設定請求參數,傳遞檔案名稱
    2. 定義 Servlet
    3. 擷取請求參數,檔案名稱
    4. 使用位元組輸入流加載檔案進記憶體
    5. 設定 response 的響應頭
    6. 将輸入流資料寫出到 response 輸出流
  3. 編碼實作
    1. 定義頁面
      <!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>
                 
    2. 定義 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);
          }
      }
                 
  4. 中文檔案問題
    1. 問題

      如果檔案名是中文,下載下傳後的檔案名稱無法顯示

    2. 解決思路
      1. 擷取用戶端使用的浏覽器版本資訊
      2. 根據不同的版本資訊,設定 filename 的編碼方式不同
    3. 解決步驟
      1. 建立一個 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;
            }
        }
        
                   
      2. 在 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);
            }
        }
                   

繼續閱讀