请求头 & 文件下载 & JSP 内置对象实战

1. 文件上传:实现项目中文件提交的核心步骤

文件上传是开发中必备的功能(如头像、附件上传),JavaWeb 中实现文件上传有严格的配置要求和固定步骤,缺一不可:

(1)前端表单配置要求
  • 请求方式必须为POST

  • 表单属性enctype必须设置为multipart/form-data(表示以二进制流形式提交数据)。

    <form action="RoomInfoServlet?flag=save" method="post" enctype="multipart/form-data"> <button type="submit">上传</button> </form>
(2)后端 Servlet 配置与核心代码
  • Servlet 上必须添加注解@MultipartConfig,开启文件上传支持(可配置文件最大大小、存储目录等);

  • 通过request.getPart("表单name值")获取上传文件;

  • 为避免文件名重复,通过时间戳 / UUID 生成新文件名,再通过part.write()完成文件写入。

    @WebServlet("/RoomInfoServlet")
    @MultipartConfig // 开启文件上传支持
    public class RoomInfoServlet extends HttpServlet {
    protected void save(HttpServletRequest request, HttpServletResponse response) throws IOException {
    // 1. 获取项目真实上传目录,不存在则创建
    String realPath = this.getServletContext().getRealPath("/upload/");
    File dir = new File(realPath);
    if (!dir.exists()) dir.mkdirs();

    复制代码
          // 2. 获取上传的文件对象
          Part part = request.getPart("pic");
          // 3. 获取原始文件名,截取扩展名
          String oldName = part.getSubmittedFileName();
          String ext = oldName.substring(oldName.lastIndexOf("."));
          // 4. 生成新文件名(时间戳+扩展名),避免重复
          String newName = System.currentTimeMillis() + ext;
          // 5. 完成文件上传
          part.write(realPath + newName);
          
          // 6. 可选:将文件路径存入数据库,供前端访问
          // info.setPic("/upload/" + newName);
      }

    }

2. ServletConfig & ServletContext:配置与全局上下文对象

这两个对象是 Servlet 的核心配置对象,前者是单个 Servlet 的专属配置 ,后者是整个 Web 应用的全局对象,掌握它们的用法能让配置更灵活。

(1)ServletConfig:单个 Servlet 的配置参数对象
  • 作用:读取当前 Servlet 的初始化参数,每个 Servlet 对应一个独立的 ServletConfig;

  • 配置方式:xml 配置 / 注解@WebInitParam

  • 获取方式:this.getServletConfig(),核心方法:getInitParameter(参数名)getServletName()

    // 注解方式配置Servlet初始化参数
    @WebServlet(value = "/RoomInfoServlet", initParams = {
    @WebInitParam(name = "status", value = "1:空,2:有客,3:空脏")
    })
    public class RoomInfoServlet extends HttpServlet {
    @Override
    public void init() throws ServletException {
    // 获取ServletConfig对象
    ServletConfig config = this.getServletConfig();
    // 读取初始化参数
    String status = config.getInitParameter("status");
    System.out.println("房间状态配置:" + status);
    }
    }

(2)ServletContext:Web 应用的全局上下文对象
  • 核心特性:整个 Web 应用只有一个 ServletContext 对象,项目启动时创建,停止时销毁,所有 Servlet 共享;

  • 4 种获取方式:

    复制代码
    ServletContext context = request.getServletContext();
    ServletContext context = session.getServletContext();
    ServletContext context = this.getServletConfig().getServletContext();
    ServletContext context = this.getServletContext();
  • 核心用法:

    1. 读取全局初始化参数 (web.xml 中<context-param>配置);
    2. 全局域存值 / 取值(setAttribute()/getAttribute()),如监听器统计在线人数;
    3. 获取项目真实路径、虚拟路径、服务器信息等。
    <context-param> <param-name>email</param-name> <param-value>admin@126.com</param-value> </context-param>

    // 读取全局参数
    String email = this.getServletContext().getInitParameter("email");
    // 获取项目真实根路径
    String realPath = this.getServletContext().getRealPath("/");
    // 全局域存值
    this.getServletContext().setAttribute("onlineCount", 10);

3. 监听器 Listener:监听 Web 对象状态变化,实现个性化业务

监听器是监听 Web 组件对象状态变化 的组件,能在对象创建 / 销毁、属性增删改时触发自定义逻辑,核心监听ServletRequestHttpSessionServletContext三大对象,Day7 重点讲解实战高频用法

(1)监听器的核心配置
  • 实现对应监听接口,重写事件方法;
  • 注册方式:注解@WebListener /web.xml 中<listener>配置(二选一)。
(2)经典实战:监听器统计在线人数

利用HttpSessionListener监听 Session 的创建(用户上线)和销毁(用户下线),结合ServletContext全局域存储在线人数,是面试和开发的经典案例:

java

运行

复制代码
@WebListener // 注解注册监听器
public class OnlineCountListener implements HttpSessionListener {
    private int onlineCount = 0; // 在线人数
    
    // 监听Session创建:用户首次访问,创建Session时触发(上线+1)
    @Override
    public void sessionCreated(HttpSessionEvent se) {
        onlineCount++;
        // 存入全局域,供所有Servlet/JSP获取
        se.getSession().getServletContext().setAttribute("onlineCount", onlineCount);
    }

    // 监听Session销毁:Session超时/手动销毁时触发(下线-1)
    @Override
    public void sessionDestroyed(HttpSessionEvent se) {
        if (onlineCount > 0) onlineCount--;
        se.getSession().getServletContext().setAttribute("onlineCount", onlineCount);
    }
}
(3)监听器其他高频用法

3. JSP 内置对象:无需声明,直接使用的页面神器

JSP 内置对象(隐藏对象)是 JSP 容器自动创建的对象,无需手动 new,可直接在 JSP 页面使用 ,共 9 个,核心围绕请求、响应、会话、域对象展开,简化 JSP 页面的 Java 代码开发,是 JSP 的核心知识点。

9 大内置对象全表(含类型 + 核心作用)

表格

内置对象 对应类型 核心作用 作用域
request HttpServletRequest 获取请求参数、请求头、请求转发 请求(一次请求)
response HttpServletResponse 重定向、设置响应头、文件下载 一次响应
out JspWriter 向页面输出内容(替代 System.out) 页面
session HttpSession 会话跟踪,存储用户登录信息、购物车 会话(一次浏览器会话)
application ServletContext 全局域,存储整个应用的共享数据 应用(项目启动到停止)
pageContext PageContext 页面顶级域,获取其他 8 个内置对象 页面(仅当前 JSP)
page Object 代表当前 JSP 页面本身,相当于 this 页面
config ServletConfig 读取当前 JSP 对应的 Servlet 配置参数 页面
exception Throwable 处理 JSP 页面异常,仅在isErrorPage=true的页面使用 页面
高频用法示例

jsp

复制代码
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<body>
    <%-- 1. request获取前端参数 --%>
    用户名:<%= request.getParameter("username") %><br>
    <%-- 2. session存储/获取登录信息 --%>
    <% session.setAttribute("user", "张三"); %>
    当前登录用户:<%= session.getAttribute("user") %><br>
    <%-- 3. application获取全局在线人数 --%>
    当前在线人数:<%= application.getAttribute("onlineCount") %><br>
    <%-- 4. out输出内容 --%>
    <% out.print("这是out对象输出的内容"); %>
</body>
</html>

4. Web 全局配置与项目部署:web.xml 终极总结 + 项目发布

(1)web.xml 核心全局配置(一站式梳理)

web.xml 是 JavaWeb 的部署描述符文件,Day8 对其做了最终系统总结,核心配置如下,覆盖开发所有场景:

复制代码
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" version="4.0">
    <!-- 1. 全局初始化参数 -->
    <context-param>
        <param-name>email</param-name>
        <param-value>admin@126.com</param-value>
    </context-param>
    <!-- 2. 欢迎页(默认首页,按顺序匹配) -->
    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
        <welcome-file>login.jsp</welcome-file>
    </welcome-file-list>
    <!-- 3. 错误页面(404/500,统一异常展示) -->
    <error-page>
        <error-code>404</error-code>
        <location>/404.jsp</location>
    </error-page>
    <error-page>
        <error-code>500</error-code>
        <location>/500.jsp</location>
    </error-page>
    <!-- 4. Session全局超时时间(单位:分钟) -->
    <session-config>
        <session-timeout>20</session-timeout>
    </session-config>
    <!-- 5. 过滤器/监听器/Servlet配置(前文已讲,此处省略) -->
</web-app>
(2)JavaWeb 项目两种部署方式

开发完成后,需要将项目部署到 Tomcat 服务器才能访问,主流两种部署方式,简单高效:

复制代码
<!-- hotel_system.xml -->
<Context path="/hotel_system" docBase="D:\workspace\JavaWeb\out\artifacts\HotelSystem_war_exploded"/>

5. MVC 模式:JavaWeb 的核心架构思想

Day8 最后梳理了 JavaWeb 的MVC 设计模式 ,这是后续学习 SSM、SpringBoot 的基础,核心是分层开发,解耦代码,将项目分为 Model、View、Controller 三层,各司其职。

(1)MVC 三层划分
(2)MVC 工作流程(核心)
(3)MVC 模式的核心优势
  • ServletContextListener:监听项目启动 / 停止,如项目启动时加载配置文件、启动定时任务;
  • ServletRequestListener:监听请求的创建 / 销毁,如统计每个请求的处理时间。

1. HTTP 请求头解析:获取客户端隐藏信息

请求头是客户端发送请求时,附带的客户端环境信息、请求偏好 等数据(浏览器默认携带,前端不可见),服务器可通过request.getHeader()解析,实现个性化业务(如判断浏览器类型、限制访问设备、获取客户端 IP)。

(1)核心获取方法
复制代码
  @WebServlet("/HeadServlet")
  public class HeadServlet extends HttpServlet {
      @Override
      protected void service(HttpServletRequest req, HttpServletResponse resp) throws IOException {
          resp.setContentType("text/html;charset=utf-8");
          PrintWriter out = resp.getWriter();
          // 获取所有请求头名称,返回枚举类型
          Enumeration<String> headerNames = req.getHeaderNames();
          // 遍历所有请求头,输出名和值
          while (headerNames.hasMoreElements()) {
              String name = headerNames.nextElement();
              String value = req.getHeader(name);
              out.println(name + ":" + value + "<br>");
          }
      }
  }
(2)开发中高频的请求头字段

表格

请求头字段 核心作用 实战场景
User-Agent 客户端软件环境(操作系统、浏览器版本) 判断访问设备(PC / 手机)、限制浏览器访问
Cookie 客户端携带的 Cookie 键值对 会话跟踪,获取用户登录状态
Host 请求的主机和端口 域名解析、多域名部署
Accept 客户端可接收的响应数据类型 动态返回不同格式数据(HTML/JSON)
Referer 请求的来源地址 防盗链、统计访问来源

2. 文件下载:实现服务器文件向客户端的传输

文件下载是文件上传的配套功能,核心是通过 IO 流读取服务器文件,写入响应输出流,并通过响应头告诉浏览器 "以下载方式处理数据",而非直接打开。

核心实战代码
复制代码
  @WebServlet("/DownloadServlet")
  public class DownloadServlet extends HttpServlet {
      @Override
      protected void service(HttpServletRequest req, HttpServletResponse resp) throws IOException {
          // 1. 获取要下载的文件路径(前端传递的文件相对路径)
          String filePath = req.getParameter("path");
          // 2. 获取文件名,解决中文文件名乱码
          String fileName = filePath.substring(filePath.lastIndexOf("/") + 1);
          fileName = new String(fileName.getBytes("utf-8"), "ISO-8859-1");
          
          // 3. 设置响应头:告诉浏览器以下载方式处理
          resp.setContentType("application/octet-stream"); // 二进制流数据
          resp.setHeader("Content-Disposition", "attachment;filename=\"" + fileName + "\"");
          
          // 4. 获取服务器文件真实路径
          String realPath = this.getServletContext().getRealPath("/") + filePath;
          // 5. IO流实现文件下载:读服务器文件 → 写入响应输出流
          FileInputStream fis = new FileInputStream(realPath);
          OutputStream os = resp.getOutputStream();
          byte[] buffer = new byte[1024]; // 缓冲区,提高效率
          int len;
          while ((len = fis.read(buffer)) != -1) {
              os.write(buffer, 0, len);
          }
          // 关闭流
          fis.close();
          os.close();
      }
  }
关键注意点
  • 响应头Content-Dispositionattachment表示 "附件下载",是实现下载的核心;
  • 中文文件名必须做编码转换ISO-8859-1),否则会出现乱码;
  • 使用缓冲区(byte [])读取文件,避免一次性读取大文件导致内存溢出。
  • 直接复制法 :将项目的 war 包 / 解压后的目录,复制到 Tomcat 的webapps目录下,启动 Tomcat 自动部署;
  • XML 配置法 :在 Tomcat 的conf/Catalina/localhost目录下,创建自定义名.xml,配置项目路径和真实目录,无需复制文件,适合开发调试:
  • path:项目访问路径(如http://localhost:8080/hotel_system);
  • docBase:项目在本地的真实目录路径。
  • View(视图层) :负责页面展示,接收用户输入,对应JSP、HTML、CSS、JS
  • Controller(控制层) :负责接收请求,分发业务,对应Servlet
  • Model(模型层) :负责业务逻辑处理和数据操作,对应实体类、Service、Dao(操作数据库)。
  • 用户通过 View 层发送请求(如点击按钮);
  • Controller 层(Servlet)接收请求,解析请求参数;
  • Controller 层调用 Model 层的 Service/Dao,处理业务逻辑(如查询数据库、操作文件);
  • Model 层将处理结果返回给 Controller 层;
  • Controller 层根据结果,跳转到对应的 View 层;
  • View 层渲染结果,响应给用户。
  • 解耦:各层职责明确,修改一层不影响其他层(如改页面不用动业务代码);
  • 易维护:代码结构清晰,便于定位问题和后续迭代;
  • 易分工:前端开发负责 View 层,后端开发负责 Controller 和 Model 层,提高开发效率。
相关推荐
skywalk81632 小时前
Kotti Next的tinyfrontend前端生成和测试(使用WorkBuddy)
前端
m0_647057962 小时前
【无标题】
前端·人工智能
北城笑笑2 小时前
Frontend 与 FPGA 深度融合实战解析:从技术协同到多场景落地( 前端和现场可编程门阵列 )
前端·websocket·3d·vue·fpga
Cosmoshhhyyy2 小时前
《Effective Java》解读第46条:优先选择Stream中无副作用的函数
java·windows·python
前端 贾公子2 小时前
把 Antigravity 用成一个更像 VS Code 的 AI IDE
前端
木斯佳2 小时前
前端八股文面经大全:腾讯PCG暑期前端一面(2026-04-01)·面经深度解析
前端·算法·面经·计算机原理
无籽西瓜a2 小时前
【西瓜带你学设计模式 | 第十一期 - 模板方法模式】模板方法模式 —— 流程骨架与钩子实现、优缺点与适用场景
java·后端·设计模式·软件工程·模板方法模式
九皇叔叔2 小时前
005-SpringSecurity-Demo 配置外部文件映射
java·springboot·文件·springsecurity
freewlt2 小时前
前端性能优化实战指南:从 3s 到 0.5s 的加载提速之路
前端·性能优化