ServletContext 对象的学习笔记
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
-
参考文献
本文来自博客园,作者:LeeHua,转载请注明原文链接:https://www.cnblogs.com/liyihua/p/14477501.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· winform 绘制太阳,地球,月球 运作规律
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 上周热点回顾(3.3-3.9)