ServletContext對象的相關概念以及文件下載案例

ServletContext對象

  1. 概念:代表整個web應用,可以和程序的容器(服務器)來通信
  2. 獲取:
    (1)、 通過request對象獲取 request.getServletContext();
    (2)、 通過HttpServlet獲取 this.getServletContext();
//1.通過request對象獲取
ServletContext context1 = request.getServletContext();
//2.通過HttpServlet獲取
ServletContext context2 = this.getServletContext();
System.out.println(context1);//org.apache.catalina.core.ApplicationContextFacade@4b65ad46
System.out.println(context2);//org.apache.catalina.core.ApplicationContextFacade@4b65ad46
  1. 功能:
    (1)、獲取MIME類型:MIME類型:在互聯網通信過程中定義的一種文件數據類型
    - 格式: 大類型/小類型 text/html image/jpeg
    - 獲取:String getMimeType(String file)
//1.獲取HTTPServlet獲取
ServletContext context = this.getServletContext();
//2.定義文件名稱
String filename = "a.jpg";
//3.獲取MIME類型
String mimeType = context.getMimeType(filename);
System.out.println(mimeType);//---->image/jpeg

(2)、 域對象:共享數據

  • ①、 setAttribute(String name,Object value)

  • ②、 getAttribute(String name)

  • ③、 removeAttribute(String name)

  • ServletContext對象範圍:所有用戶所有請求的數據
    下面的例子中,當訪問ServletContextDemo3路徑時,在裏面存儲數據;然後當我們訪問ServletContextDemo4時獲取數據。

@WebServlet("/ServletContextDemo3")
public class ServletContextDemo3 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1.獲取HTTPServlet獲取
        ServletContext context = this.getServletContext();
        //設置數據
        context.setAttribute("msg","haha");
    }
    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 {
        //1.獲取HTTPServlet獲取
        ServletContext context = this.getServletContext();
        //獲取數據
        Object msg = context.getAttribute("msg");
        System.out.println(msg);
    }
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }
}

(3)、 獲取文件的真實(服務器)路徑

  • ①、 方法:String getRealPath(String path)
String b = context.getRealPath("/b.txt");//web目錄下資源訪問
System.out.println(b);
		
String c = context.getRealPath("/WEB-INF/c.txt");//WEB-INF目錄下的資源訪問
System.out.println(c);
		
String a = context.getRealPath("/WEB-INF/classes/a.txt");//src目錄下的資源訪問
System.out.println(a);

案例:

  • 文件下載需求:
    1. 頁面顯示超鏈接
    2. 點擊超鏈接後彈出下載提示框
    3. 完成圖片文件下載

  • 分析:
    1. 超鏈接指向的資源如果能夠被瀏覽器解析,則在瀏覽器中展示,如果不能解析,則彈出下載提示框。
    2. 任何資源都必須彈出下載提示框
    3. 使用響應頭設置資源的打開方式:content-disposition:attachment;filename=xxx

  • 步驟:
    1. 定義頁面,編輯超鏈接href屬性,指向Servlet,傳遞資源名稱filename
    2. 定義Servlet
    (1)、 獲取文件名稱
    (2)、 使用字節輸入流加載文件進內存
    (3)、 指定response的響應頭: content-disposition:attachment;filename=xxx
    (4)、 將數據寫出到response輸出流

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>download</title>
</head>
<body>
    <a href="/LoginCase/img/1.jpg">圖片瀏覽</a>
    <a href="/LoginCase/DownloadServlet?filename=1.jpg">圖片下載</a>
</body>
</html>
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.FileInputStream;
import java.io.IOException;

@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);//將圖片保存在web/img/文件目錄下
        //2.2用字節流關聯
        FileInputStream fis = new FileInputStream(realPath);

        //3.設置response的響應頭
        //3.1設置響應頭:content-type
        String mimeType = servletContext.getMimeType(filename);//獲取文件的mime類型
        response.setHeader("content-type",mimeType);
        //3.2設置響應頭打開方式:content-disposition
        response.setHeader("content-disposition","attachment;filename="+filename);
        //4.將輸入流的數據寫出到輸出流中
        ServletOutputStream sos = response.getOutputStream();//輸出流
        byte[] buff = new byte[1024*8];//緩衝區
        int len = 0;//讀到的個數
        while ((len = fis.read(buff)) != -1){
            sos.write(buff,0,len);
        }

        fis.close();
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }
}

  • 問題:中文文件問題:如果按照上述的代碼實現文件下載的概念,然後將文件命名爲中文,這樣會導致中文亂碼。

  • 解決思路:
    (1)、 獲取客戶端使用的瀏覽器版本信息
    (2)、 根據不同的版本信息,設置filename的編碼方式不同

導入utils包裏面的DownLoadUtils.java文件

package cn.itcast.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;
    }
}

然後再response.setHeader("content-disposition","attachment;filename="+filename);這行代碼前加入下面的幾行代碼即可

//解決中文文件名問題
//1.獲取user-agent請求頭
String agent = request.getHeader("user-agent");
//2.使用工具類方法編碼文件名即可
filename = DownLoadUtils.getFileName(agent,filename);

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章