ServletContext對象
- 概念:代表整個web應用,可以和程序的容器(服務器)來通信
- 獲取:
(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)、獲取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);