在 Java Web 开发中,HttpServletRequestHttpServletResponse 是 Servlet 中最核心的两个对象,由 Tomcat 等 Web 容器创建,我们直接使用即可:

  • HttpServletRequest请求对象,封装客户端(浏览器)发送给服务器的所有请求信息(请求头、请求参数、请求方式、Cookie 等)。
  • HttpServletResponse响应对象,封装服务器返回给客户端的所有响应信息(响应头、响应体、状态码、Cookie 等)。

二者是请求 - 响应模型的核心,贯穿整个 Web 请求处理流程。

一、HttpServletRequest 详解

1. 核心作用

获取客户端发送的所有请求数据,常用场景:

  • 获取请求行信息(请求方式、URL、协议)
  • 获取请求头信息
  • 获取请求参数(表单、URL 传参)
  • 获取请求域属性、Cookie、Session
  • 获取请求转发、请求编码

2. 常用核心方法

(1)获取请求行信息
// 1. 获取请求方式 GET/POST/PUT/DELETE
String method = request.getMethod();

// 2. 获取请求URL(完整地址)
String url = request.getRequestURL().toString();

// 3. 获取请求URI(项目内路径)
String uri = request.getRequestURI();

// 4. 获取项目上下文路径(根路径)
String contextPath = request.getContextPath();

// 5. 获取客户端IP地址
String ip = request.getRemoteAddr();

(2)获取请求头信息

// 获取指定请求头(如浏览器信息、Referer、Content-Type)
String userAgent = request.getHeader("User-Agent");
// 获取所有请求头名称
Enumeration<String> headerNames = request.getHeaderNames();
3)获取请求参数(最常用)

支持 URL 传参表单提交 参数获取:

// 1. 获取单个参数(常用)
String username = request.getParameter("username");
String password = request.getParameter("password");

// 2. 获取多个同名参数(如复选框)
String[] hobbies = request.getParameterValues("hobby");

// 3. 获取所有参数的Map集合
Map<String, String[]> paramMap = request.getParameterMap();
(4)请求域(Request 域)操作

请求域:一次请求内有效,请求转发后仍有效,重定向失效。

// 存储数据到请求域
request.setAttribute("msg", "请求成功");

// 从请求域获取数据
Object msg = request.getAttribute("msg");

// 删除请求域数据
request.removeAttribute("msg");
(5)请求转发(服务器内部跳转)

特点:一次请求、地址栏不变、可共享请求域数据、只能转发到项目内资源

// 转发到页面或Servlet
request.getRequestDispatcher("/success.jsp").forward(request, response);

(6)获取会话(Session)

// 获取当前会话,没有则创建
HttpSession session = request.getSession();
// 获取当前会话,没有则返回null
HttpSession session = request.getSession(false);
(7)解决请求参数乱码

仅对 POST 请求 有效:

// 设置请求编码为UTF-8(必须在获取参数前调用)
request.setCharacterEncoding("UTF-8");

3. 生命周期

  • 创建:客户端发送请求时,Web 容器自动创建
  • 销毁:服务器完成响应,请求结束后立即销毁
  • 作用域:一次请求范围内

二、HttpServletResponse 详解

1. 核心作用

向客户端发送响应数据,常用场景:

  • 设置响应行(状态码)
  • 设置响应头(编码、缓存、下载、重定向)
  • 输出响应体(HTML、文本、JSON、文件)
  • 发送 Cookie、重定向

2. 常用核心方法

(1)设置响应行(状态码)
// 设置200成功状态码
response.setStatus(200);
// 设置404未找到
response.sendError(404, "资源不存在");

(2)设置响应头

// 设置响应编码(核心:解决响应乱码)
response.setHeader("Content-Type", "text/html;charset=UTF-8");
// 简化写法(推荐)
response.setContentType("text/html;charset=UTF-8");

// 重定向(设置Location头)
response.sendRedirect("/项目名/index.jsp");

// 设置缓存1小时
response.setHeader("Cache-Control", "max-age=3600");
(3)输出响应体(向浏览器写数据)

两种输出流:字节流(下载文件、图片)、字符流(输出文本 / HTML)

        注意:两个流不能同时使用,二选一

// 1. 字符输出流(输出文本、HTML、JSON)
PrintWriter writer = response.getWriter();
writer.write("<h1>Hello Servlet</h1>");
writer.write("{\"name\":\"张三\"}");

// 2. 字节输出流(下载文件、图片、音频)
ServletOutputStream out = response.getOutputStream();
out.write(文件字节数组);
(4)重定向(客户端跳转)

特点:两次请求、地址栏改变、不共享请求域数据、可跳转到外部网站

// 方式1:标准写法
response.sendRedirect(request.getContextPath() + "/index.jsp");

// 跳转到外部网站
response.sendRedirect("https://www.baidu.com");

(5)发送 Cookie

// 创建Cookie
Cookie cookie = new Cookie("username", "zhangsan");
// 设置Cookie有效期1天
cookie.setMaxAge(60*60*24);
// 发送Cookie到客户端
response.addCookie(cookie);

3. 生命周期

  • 创建:Web 容器接收到请求时,与 Request 同时创建
  • 销毁:响应完成(数据输出完毕)后立即销毁
  • 作用域:一次响应范围内

三、请求转发 vs 重定向(面试高频)

特性请求转发 getRequestDispatcher().forward()重定向 sendRedirect()
请求次数1 次2 次
地址栏不变改变
数据共享共享 Request 域数据不共享
跳转范围仅项目内部可跳转到外部网站
本质服务器内部跳转客户端重新请求

使用场景

  • 增删改操作后用重定向(避免表单重复提交)
  • 查询 / 展示数据用请求转发(共享请求域数据)

四、乱码问题终极解决方案

请求 / 响应乱码是 Web 开发常见问题,统一用 UTF-8 编码:

@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    // 1. 解决POST请求参数乱码
    request.setCharacterEncoding("UTF-8");
    
    // 2. 解决响应乱码(必须在获取流之前设置)
    response.setContentType("text/html;charset=UTF-8");
    
    // 业务逻辑
}

五、完整示例代码

@WebServlet("/demo")
public class DemoServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 1. 设置编码
        request.setCharacterEncoding("UTF-8");
        response.setContentType("text/html;charset=UTF-8");

        // 2. 使用Request获取请求参数
        String username = request.getParameter("username");
        String password = request.getParameter("password");

        // 3. 存储数据到请求域
        request.setAttribute("user", username);

        // 4. 使用Response输出数据
        PrintWriter writer = response.getWriter();
        writer.write("用户名:" + username);
        writer.write("密码:" + password);

        // 5. 请求转发/重定向
        // request.getRequestDispatcher("/success.jsp").forward(request, response);
        // response.sendRedirect(request.getContextPath() + "/index.jsp");
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }
}

总结

  1. HttpServletRequest获取请求数据,核心方法 getParameter()setAttribute()getRequestDispatcher()
  2. HttpServletResponse发送响应数据,核心方法 setContentType()getWriter()sendRedirect()
  3. 请求转发:服务器跳转,一次请求,共享数据
  4. 重定向:客户端跳转,两次请求,不共享数据
  5. 统一编码为 UTF-8 彻底解决乱码问题
Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐