HttpServletResponse 对象用来做什么?

HttpServletResponse 对象是由 Servlet 容器创建并传递给 Servlet 的 service() 方法(以及间接传递给 doGet(), doPost() 等方法)的。它的核心作用是让 Servlet 能够向客户端(通常是浏览器)发送 HTTP 响应

通过 HttpServletResponse 对象,我们可以:

  1. 设置响应状态码 (Status Code)
  2. 设置响应头 (Headers)
  3. 设置 Cookie
  4. 写入响应体 (Response Body),即发送内容回浏览器

下面我们详细看看如何进行这些操作:


1. 设置响应状态码 (Status Code)

状态码告诉浏览器请求的处理结果(例如,成功、未找到、服务器错误等)。

  • 方法:

    • response.setStatus(int sc): 设置指定的 HTTP 状态码。
    • response.sendError(int sc): 发送一个指定的状态码给客户端(通常会附带一个简单的错误页面)。
    • response.sendError(int sc, String msg): 发送一个指定的状态码和一条错误消息给客户端。
    • response.sendRedirect(String location): 发送一个重定向响应 (状态码 302) 到指定的 URL。
  • 常量: javax.servlet.http.HttpServletResponse 接口定义了很多常用的状态码常量,例如:

    • HttpServletResponse.SC_OK (200)
    • HttpServletResponse.SC_CREATED (201)
    • HttpServletResponse.SC_NO_CONTENT (204)
    • HttpServletResponse.SC_MOVED_PERMANENTLY (301)
    • HttpServletResponse.SC_FOUND (302) - sendRedirect 默认使用这个
    • HttpServletResponse.SC_BAD_REQUEST (400)
    • HttpServletResponse.SC_UNAUTHORIZED (401)
    • HttpServletResponse.SC_FORBIDDEN (403)
    • HttpServletResponse.SC_NOT_FOUND (404)
    • HttpServletResponse.SC_INTERNAL_SERVER_ERROR (500)
  • 示例:

    // 设置成功状态码
    response.setStatus(HttpServletResponse.SC_OK);// 如果资源未找到
    // response.sendError(HttpServletResponse.SC_NOT_FOUND, "The requested resource was not found.");// 重定向到另一个页面
    // response.sendRedirect("http://www.example.com/newPage");
    

    注意: 设置状态码或调用 sendError/sendRedirect 应该在向响应体写入任何内容 之前 进行。


2. 设置响应头 (Headers)

响应头包含关于响应的元数据,例如内容类型、缓存控制、自定义信息等。

  • 方法:

    • response.setHeader(String name, String value): 设置一个具有给定名称和值的头。如果该头已存在,则新值将覆盖旧值。
    • response.addHeader(String name, String value): 添加一个具有给定名称和值的头。允许同一个头名称有多个值。
    • response.setContentType(String type): 设置响应内容的 MIME 类型(例如 “text/html”, “application/json”, “image/jpeg”)。这实际上是设置 Content-Type 头的一个便捷方法。
    • response.setCharacterEncoding(String charset): 设置发送到客户端的响应的字符编码(例如 “UTF-8”)。通常与 setContentType 一起使用,或者直接在 setContentType 中指定,如 response.setContentType("text/html; charset=UTF-8");
    • response.setContentLength(int len) / response.setContentLengthLong(long len): 设置响应体的长度(以字节为单位)。
  • 示例:

    // 设置内容类型为 HTML,并使用 UTF-8 编码
    response.setContentType("text/html; charset=UTF-8");
    // 或者分两步:
    // response.setContentType("text/html");
    // response.setCharacterEncoding("UTF-8");// 设置自定义头
    response.setHeader("X-Custom-Info", "This is my custom header value");// 设置缓存控制,禁止缓存
    response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate"); // HTTP 1.1
    response.setHeader("Pragma", "no-cache"); // HTTP 1.0
    response.setDateHeader("Expires", 0); // Proxies// 如果你知道响应体的确切字节数
    // byte[] responseBodyBytes = ...;
    // response.setContentLength(responseBodyBytes.length);
    

    注意: 设置响应头也应该在向响应体写入任何内容 之前 进行。


3. 设置 Cookie

Cookie 是服务器发送到用户浏览器并保存在本地的一小块数据,它们会在浏览器下次向同一服务器发起请求时被携带并发送到服务器上。

  • 步骤:

    1. 创建一个 javax.servlet.http.Cookie 对象。
    2. 可选地,设置 Cookie 的属性 (如过期时间 setMaxAge(), 路径 setPath(), 域 setDomain(), 安全性 setSecure(), setHttpOnly(), setSameSite())。
    3. 使用 response.addCookie(Cookie cookie) 将 Cookie 添加到响应中。这会生成一个 Set-Cookie 响应头。
  • 示例:

    // 创建一个新的 Cookie
    Cookie userCookie = new Cookie("username", "john_doe");// 设置 Cookie 的有效期为 1 小时 (3600 秒)
    userCookie.setMaxAge(3600);// 设置 Cookie 的路径,使其对整个应用可见
    userCookie.setPath(request.getContextPath() + "/"); // 或者简单地 "/"// (可选) 设置为 HttpOnly,防止 JavaScript 访问,增强安全性
    userCookie.setHttpOnly(true);// (可选) 设置为 Secure,仅通过 HTTPS 传输
    // userCookie.setSecure(true);// (可选,现代浏览器推荐) 设置 SameSite 属性
    // userCookie.setSameSite("Lax"); // 或 "Strict" 或 "None" (None 需要 Secure=true)// 将 Cookie 添加到响应中
    response.addCookie(userCookie);// 删除一个 Cookie (通过设置 maxAge 为 0)
    // Cookie deleteCookie = new Cookie("old_cookie_name", "");
    // deleteCookie.setMaxAge(0);
    // deleteCookie.setPath("/");
    // response.addCookie(deleteCookie);
    

    注意: 添加 Cookie 也是通过设置响应头 (Set-Cookie) 实现的,所以也应该在向响应体写入任何内容 之前 进行。


4. 将内容发送回浏览器 (写入响应体)

一旦状态码和头信息设置完毕,你就可以开始向响应体写入实际内容了。你有两种方式获取输出流:

  • response.getWriter(): 返回一个 java.io.PrintWriter 对象,用于发送字符文本数据 (如 HTML, XML, JSON, plain text)。
    • 在使用 getWriter() 之前,应该先通过 response.setContentType() 和/或 response.setCharacterEncoding() 设置正确的字符编码。
  • response.getOutputStream(): 返回一个 javax.servlet.ServletOutputStream 对象,用于发送二进制数据 (如图片, PDF, ZIP 文件)。

重要: 你在一个响应中只能调用 getWriter()getOutputStream() 一次。调用其中一个后,就不能再调用另一个了,否则会抛出 IllegalStateException

  • 示例 (使用 PrintWriter 发送 HTML):

    response.setContentType("text/html; charset=UTF-8");
    // response.setStatus(HttpServletResponse.SC_OK); // 默认是 200 OK,可以不显式设置PrintWriter out = response.getWriter();
    out.println("<!DOCTYPE html>");
    out.println("<html>");
    out.println("<head>");
    out.println("<meta charset=\"UTF-8\">");
    out.println("<title>My Servlet Response</title>");
    out.println("</head>");
    out.println("<body>");
    out.println("<h1>Hello from Servlet!</h1>");
    out.println("<p>This is a dynamic response.</p>");
    out.println("</body>");
    out.println("</html>");
    // out.flush(); // 可选,容器通常会自动 flush
    // out.close(); // 可选,容器通常会自动关闭
    
  • 示例 (使用 ServletOutputStream 发送图片 - 假设 imageData 是一个 byte[]):

    // byte[] imageData = ... ; // 从文件或数据库加载图片数据// response.setContentType("image/jpeg");
    // response.setContentLength(imageData.length);
    // // response.setStatus(HttpServletResponse.SC_OK);// ServletOutputStream sos = response.getOutputStream();
    // sos.write(imageData);
    // sos.flush();
    // sos.close();
    

完整示例 (一个简单的 Servlet):

package com.example;import java.io.IOException;
import java.io.PrintWriter;
import java.util.Date;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;@WebServlet("/hello")
public class HelloServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {// 1. 设置状态码 (默认是 200 OK,如果一切正常,可以不显式设置)response.setStatus(HttpServletResponse.SC_OK);// 2. 设置响应头response.setContentType("text/html; charset=UTF-8");response.setHeader("X-Server-Time", new Date().toString());// 3. 设置 CookieCookie visitCookie = new Cookie("lastVisit", String.valueOf(System.currentTimeMillis()));visitCookie.setMaxAge(60 * 60 * 24 * 7); // 7 daysvisitCookie.setPath(request.getContextPath() + "/");visitCookie.setHttpOnly(true);response.addCookie(visitCookie);// 4. 获取 PrintWriter 并写入响应体// (注意:一旦调用 getWriter() 或 getOutputStream(),响应头就被认为是“已提交”,不能再修改状态码或头信息)PrintWriter out = response.getWriter();out.println("<!DOCTYPE html>");out.println("<html>");out.println("<head>");out.println("<meta charset=\"UTF-8\">");out.println("<title>Servlet Response</title>");out.println("</head>");out.println("<body>");out.println("<h1>Hello, World from Servlet!</h1>");out.println("<p>Welcome! Your request was processed successfully.</p>");out.println("<p>Check your browser's developer tools for the 'X-Server-Time' header and the 'lastVisit' cookie.</p>");out.println("</body>");out.println("</html>");// 通常不需要显式调用 out.close(),因为 Servlet 容器会在请求处理完成后自动关闭它。// 但如果是在 Filter 中或有特殊资源管理需求,可能需要。}
}

关键点总结:

  • 顺序很重要: 设置状态码、响应头和 Cookie 必须在第一次调用 response.getWriter()response.getOutputStream() 之前完成,或者在响应被提交(flushed)之前完成。一旦响应体开始写入,头信息就不能再更改了。
  • getWriter() vs getOutputStream(): 只能选择一个,不能同时使用。
  • 字符编码: 对于文本内容,务必设置正确的字符编码(通常是 UTF-8)以避免乱码问题。
  • 容器管理: Servlet 容器负责在请求处理结束后刷新和关闭输出流。

通过这些方法,HttpServletResponse 提供了全面的控制,使 Servlet 能够构建并发送各种类型的 HTTP 响应给客户端。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.pswp.cn/news/908144.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

FTPS、HTTPS、SMTPS以及WebSockets over TLS的概念及其应用场景

一、什么是FTPS&#xff1f; FTPS&#xff0c;英文全称File Transfer Protocol with support for Transport Layer Security (SSL/TLS)&#xff0c;安全文件传输协议&#xff0c;是一种对常用的文件传输协议(FTP)添加传输层安全(TLS)和安全套接层(SSL)加密协议支持的扩展协议。…

前端​​HTML contenteditable 属性使用指南

​​什么是 contenteditable&#xff1f; HTML5 提供的全局属性&#xff0c;使元素内容可编辑类似于简易富文本编辑器兼容性​​ 支持所有现代浏览器&#xff08;Chrome、Firefox、Safari、Edge&#xff09; 移动端&#xff08;iOS/Android&#xff09;部分键盘行为需测试 &l…

持续领跑中国异地组网路由器市场,贝锐蒲公英再次登顶销量榜首

作为国产远程连接SaaS服务的创领者&#xff0c;贝锐持续引领行业发展&#xff0c;旗下贝锐蒲公英异地组网路由器&#xff0c;凭借出色的技术实力和市场表现&#xff0c;斩获2024年线上电商平台市场销量份额中国第一的佳绩&#xff0c;充分彰显了其在网络解决方案与异地组网领域…

五大主流大模型推理引擎深度解析:llama.cpp、vLLM、SGLang、DeepSpeed和Unsloth的终极选择指南

在人工智能的竞技场上,大模型推理框架就像是为超级跑车精心调校的引擎系统——选对了能让你的AI应用一骑绝尘,选错了可能连"停车场"都开不出去。这些框架的核心价值在于将训练好的"大脑"转化为实际可用的"肌肉记忆",而选择标准则需要像职业赛…

前端面试二之运算符与表达式

目录 1.JavaScript 中的 和 运算符 2.|| (逻辑或) 运算符 与 ES6 默认参数的区别 与 ?? (空值合并运算符) 的区别 3.?.&#xff08;可选链&#xff09;运算符 (1). 安全访问深层嵌套属性 (2). 安全调用可能不存在的函数 (3). 安全访问数组元素 4.展开运算符 (..…

GB/T 24507-2020 浸渍纸层压实木复合地板检测

浸渍纸层压实木地板是指以一层或多层专用纸浸渍热固性氨基树脂&#xff0c;经干燥后铺装在胶合板基材正面&#xff0c;专用纸表面加耐磨层&#xff0c;基材背面可加平衡层&#xff0c;经热压、成型的地板。 GB/T 24507-2020 浸渍纸层压实木复合地板测试项目&#xff1a; 测试项…

AWS DocumentDB vs MongoDB:数据库的技术抉择

随着非关系型数据库在现代应用中的广泛应用&#xff0c;文档型数据库因其灵活的结构与出色的扩展性&#xff0c;逐渐成为企业开发与架构设计中的核心选择。在众多文档数据库中&#xff0c;MongoDB 凭借其成熟生态与社区支持占据主导地位&#xff1b;与此同时&#xff0c;AWS 提…

微信小程序实现运动能耗计算

微信小程序实现运动能耗计算 近我做了一个挺有意思的微信小程序&#xff0c;能够实现运动能耗的计算。只需要输入性别、年龄、体重、运动时长和运动类型这些信息&#xff0c;就能算出对应的消耗热量。 具体来说&#xff0c;在小程序里&#xff0c;性别不同&#xff0c;身体基…

三轴地磁传感器的主要应用场景

随着材料科学、微电子技术以及传感器技术的不断进步&#xff0c;三轴地磁传感器的性能将不断提升&#xff0c;包括提高精度、降低功耗、增强抗干扰能力等。 RAMSUN提供的是一款三轴地磁传感器采用第三代AMR技术&#xff0c;带有自动温度补偿的三轴磁传感器&#xff0c;该产品因…

使用 SseEmitter 实现 Spring Boot 后端的流式传输和前端的数据接收

1.普通文本消息的发送和接收 GetMapping("/stream")public SseEmitter streamResponse() {SseEmitter emitter new SseEmitter(0L); // 0L 表示永不超时Executors.newSingleThreadExecutor().execute(() -> {try {for (int i 1; i < 5; i) {emitter.send(&q…

nssm配置springboot项目环境,注册为windows服务

NSSM 的官方下载地址是&#xff1a;NSSM - the Non-Sucking Service Manager1 使用powershell输入命令,java项目需要手动配置和依赖nacos .\nssm.exe install cyMinio "D:\minio\启动命令.bat" .\nssm.exe install cyNacos "D:\IdeaProject\capacity\nacos-s…

WinCC学习系列-基础概念

从本节起&#xff0c;学习和了解西门子最新SCADA软件WinCC 8.0&#xff0c;将从基础概念开始&#xff0c;到入门操作&#xff08;创建项目、组态通信、组态过程画面、组态面板类型和变量结构、归档和显示值、组态消息&#xff09;&#xff0c;到高级应用&#xff08;WinCC选件、…

数据分析图表类型及其应用场景

说明&#xff1a;顶部HTML文件下载后可以直接查看&#xff0c;带有示图。 摘要 数据可视化作为现代数据分析的核心环节&#xff0c;旨在将复杂、抽象的数据转化为直观、易懂的图形形式。这种转化显著提升了业务决策能力&#xff0c;优化了销售与营销活动&#xff0c;开辟了新…

《江西棒垒球》败方mvp叫什么·棒球1号位

败方mvp也是MVP&#xff0c;以棒球运动为例&#xff0c;MLB&#xff08;美国职棒大联盟&#xff09;的个人奖项旨在表彰球员在不同领域的卓越表现&#xff0c;涵盖常规赛和季后赛的杰出成就。 常规赛核心奖项 最有价值球员奖&#xff08;MVP&#xff09; 定义&#xff1a;表彰…

CD43.vector模拟实现(2)

目录 1.拷贝构造函数 写法1 写法2 测试代码 调试找bug 解决方法:修改拷贝构造函数 测试代码 2.operator[ ] 测试代码 1.没有const修饰 2.有const修饰 3.insert 迭代器失效问题 承接CD42.vector模拟实现(1)文章 1.拷贝构造函数 设置start、finish和end_of_storag…

【C/C++】入门grpc的idl

文章目录 grpc idl 简单介绍1. 文件结构组织规范文件命名包结构&#xff1a;推荐&#xff1a;一个文件只定义一个 service&#xff0c;如果 service 很复杂&#xff0c;可拆分多个 proto 文件。 2. 消息定义规范命名风格字段编号&#xff1a;示例&#xff1a; 3. 服务与 RPC 设…

安全-JAVA开发-第二天

Web资源访问的流程 由此可见 客户访问JAVA开发的应用时 会先通过 监听器&#xff08;Listener&#xff09;和 过滤器&#xff08;Filter&#xff09; 今天简单的了解下这两个模块的开发过程 监听器&#xff08;Listener&#xff09; 主要是监听 我们触发了什么行为 并进行反应…

使用 Ansys Q3D 进行电容提取

精确的电容提取在高速和 RF 设计中至关重要。虽然简单的公式可以提供一个很好的起点&#xff0c;但它们往往无法捕捉 fringing fields 和 layout-dependent parasitics 的影响。在本博客中&#xff0c;我们演示了如何使用Ansys Q3D Extractor来计算电容值&#xff0c;从基本的平…

卡西欧模拟器:Windows端功能强大的计算器

引言 大家还记得初中高中时期用的计算器吗&#xff1f;今天给大家分享的就是一款windows端的卡西欧计算器。 软件介绍 大家好&#xff0c;我是逍遥小欢。 CASIO fx-9860G是一款功能强大的图形计算器&#xff0c;适用于数学、科学和工程计算。以下是其主要功能和特点的详细介…

【Bluedroid】蓝牙启动之gatt_init 流程源码解析

本文围绕Android蓝牙协议栈中 GATT(通用属性配置文件)模块的初始化函数gatt_init展开,深入解析其核心实现逻辑与关键步骤。通过分析gatt_init及其关联子函数(如L2CA_RegisterFixedChannel、gatt_profile_db_init、EattExtension::Start等),以及相关数据结构(如tGATT_CB控…