ServletContext对象概述
ServletContext用来存放全局变量,每个Java虚拟机每个Web项目只有一个ServletContext,这个ServletContext是由Web服务器创建的,来保证它的唯一性。由于一个WEB应用中的所有Servlet共享同一个ServletContext对象,因此Servlet对象之间可以通过ServletContext对象通讯。ServletContext对象通常也被称之为Context域对象。
-
获取方式
-
通过request对象获取
request.getServletContext();
-
通过HttpServlet获取
this.getServletContext();
-
获取ServletContext对象
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/demo01")
public class ServletContextDemo01 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 通过 Request 对象获取 ServletContext 对象
ServletContext requestServletContext = request.getServletContext();
// 通过 HttpServlet 获取 ServletContext 对象
ServletContext servletContext = this.getServletContext();
System.out.println(requestServletContext);
System.out.println(servletContext);
System.out.println(requestServletContext == servletContext);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
this.doGet(request, response);
}
}
启动服务器,浏览器访问:http://localhost:8080/ServletContext_war_exploded/demo01
控制台输出:
org.apache.catalina.core.ApplicationContextFacade@86cb2b8
org.apache.catalina.core.ApplicationContextFacade@86cb2b8
true
ServletContext对象功能
-
获取MIME类型
-
MIME类型:在互联网通信过程中定义的一种文件数据类型
如:大类型/小类型 text/html image/jpeg
-
获取方法:
String getMimeType(String file)
-
-
域对象:共享数据
setAttribute(String name,Object value) getAttribute(String name) removeAttribute(String name)
-
获取文件的真实(服务器)路径
String getRealPath(String path)
获取mime 类型
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/demo02")
public class ServletContextDemo02 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 通过 HttpServlet 获取 ServletContext 对象
ServletContext servletContext = this.getServletContext();
// 定义文件名称
String fileName01 = "a.png";
String fileName02 = "b.jpeg";
// 获取 MIME 类型
String mimeType01 = servletContext.getMimeType(fileName01);
System.out.println(mimeType01);
String mimeType02 = servletContext.getMimeType(fileName02);
System.out.println(mimeType02);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
this.doGet(request, response);
}
}
启动服务器,浏览器访问:http://localhost:8080/ServletContext_war_exploded/demo02
控制台输出:
image/png
image/jpeg
域对象:共享数据
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/demo03")
public class ServletContextDemo03 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 通过 HttpServlet 获取 ServletContext 对象
ServletContext servletContext = this.getServletContext();
// 设置数据
servletContext.setAttribute("demo03's data", "我是demo03这里设置的数据!!!");
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
this.doGet(request, response);
}
}
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/demo04")
public class ServletContextDemo04 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 通过 HttpServlet 获取 ServletContext 对象
ServletContext servletContext = this.getServletContext();
// 获取demo03中设置的数据
System.out.println(servletContext.getAttribute("demo03's data"));
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
this.doGet(request, response);
}
}
启动服务器,浏览器中访问:http://localhost:8080/ServletContext_war_exploded/demo03,目的是,访问demo03,设置数据。
然后,浏览器中访问:http://localhost:8080/ServletContext_war_exploded/demo04。控制台输出:
我是demo03这里设置的数据!!!
获取文件的真实(服务器)路径
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/demo05")
public class ServletContextDemo05 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 通过 HttpServlet 获取 ServletContext 对象
ServletContext servletContext = this.getServletContext();
// 获取文件的服务器路径
System.out.println(servletContext.getRealPath("/file01.txt"));
System.out.println(servletContext.getRealPath("/WEB-INF/file02.txt"));
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
this.doGet(request, response);
}
}
启动服务器,浏览器中访问:http://localhost:8080/ServletContext_war_exploded/demo05
控制台输出:
/Users/liyihua/IdeaProjects/ServletContext/out/artifacts/ServletContext_war_exploded/file01.txt
/Users/liyihua/IdeaProjects/ServletContext/out/artifacts/ServletContext_war_exploded/WEB-INF/file02.txt
案例
-
文件下载需求:
- 页面显示超链接
- 点击超链接后弹出下载提示框
- 完成图片文件下载
-
分析:
- 超链接指向的资源如果能够被浏览器解析,则在浏览器中展示,如果不能解析,则弹出下载提示框。不满足需求
- 任何资源都必须弹出下载提示框
- 使用响应头设置资源的打开方式:
- content-disposition:attachment;filename=xxx
-
步骤:
- 定义页面,编辑超链接href属性,指向Servlet,传递资源名称filename
- 定义Servlet
- 获取文件名称
- 使用字节输入流加载文件进内存
- 指定response的响应头: content-disposition:attachment;filename=xxx
- 将数据写出到response输出流
- 问题:
- 中文文件问题
- 解决思路:
- 获取客户端使用的浏览器版本信息
- 根据不同的版本信息,设置filename的编码方式不同
- 解决思路:
- 中文文件问题
-
实现:
-
java
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 { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 获取用户请求参数(文件名称) String fileName = request.getParameter("filename"); // 获取 ServletContext 对象 ServletContext servletContext = request.getServletContext(); // 根据文件名称,找到服务器中文件的路径 String filePath = servletContext.getRealPath("/downloadFile/" + fileName); // 根据文件名称,获取文件类型 String mimeType = servletContext.getMimeType(fileName); // 设置 response 的响应头 —————— 响应头类型:content-type response.setHeader("content-type", mimeType); // 响应头的打开方式:content-disposition response.setHeader("content-disposition", "attachment;filename=" + fileName); // 使用字节输入流加载文件进内存 FileInputStream fileInputStream = new FileInputStream(filePath); // 将字节输入流的数据写出到输出流中 ServletOutputStream responseOutputStream = response.getOutputStream(); byte[] bytes = new byte[1024 * 8]; int len = 0; while ((len = fileInputStream.read(bytes)) != -1) { responseOutputStream.write(bytes, 0, len); } fileInputStream.close(); } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doGet(request, response); } }
-
html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <!-- 虚拟路径:/ResponseDownload_war_exploded --> <!-- /downloadServlet 为Servlet的访问路径 --> <!-- 资源名称:image06.png、view.avi --> <a href="/ResponseDownload_war_exploded/downloadServlet?filename=image06.png">下载图片</a> <a href="/ResponseDownload_war_exploded/downloadServlet?filename=view.avi">下载视频</a> </body> </html>
-
启动服务器,浏览器中访问:http://localhost:8080/ResponseDownload_war_exploded/download.html
点击下载图片,会下载:
image06.png
点击下载视频,会下载:
view.avi
-