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对象功能

  1. 获取MIME类型

    • MIME类型:在互联网通信过程中定义的一种文件数据类型

      如:大类型/小类型 text/html image/jpeg

    • 获取方法:

      复制
      String getMimeType(String file)
  2. 域对象:共享数据

    复制
    setAttribute(String name,Object value)
    getAttribute(String name)
    removeAttribute(String name)
  3. 获取文件的真实(服务器)路径

    复制
    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

案例

  • 文件下载需求:

    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输出流
    • 问题:
      • 中文文件问题
        • 解决思路:
          1. 获取客户端使用的浏览器版本信息
          2. 根据不同的版本信息,设置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

      20200528221013

      点击下载图片,会下载: image06.png

      点击下载视频,会下载:view.avi


参考文献

  1. ServletContext对象详解
posted @   LeeHua  阅读(151)  评论(0编辑  收藏  举报
编辑推荐:
· 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)
点击右上角即可分享
微信分享提示

目录导航