当前位置: 首页 > article >正文

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 响应给客户端。

相关文章:

HttpServletResponse 对象用来做什么?

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

第十三章 Java基础-特殊处理

文章目录 1.包和final2.权限修饰符和代码块3.抽象类1.包和final 2.权限修饰符和代码块 3.抽象类...

MTK的Download agent是什么下载程序?

MTK(MediaTek)的Download Agent(DA)是一种与MTK设备进行通信的协议代理程序,在MTK设备的固件下载与烧录过程中起着关键作用,以下为你展开介绍: 下载原理 在MTK平台的固件下载过程中,DA会被加载到MTK设备的内部RAM中运行。它负责配置Flash及RAM的时序,从而建立起PC端…...

ArcGIS Pro 3.4 二次开发 - 地图创作 2

环境:ArcGIS Pro SDK 3.4 + .NET 8 文章目录 ArcGIS Pro 3.4 二次开发 - 地图创作 224 注记24.1 创建标注构造工具24.2 通过属性更新注释文本。注意:TEXTSTRING 注释属性必须存在24.3 旋转或移动标注24.4 获取注释文本图形24.5 获取注记的轮廓几何24.6 获取标注的掩膜几何25 …...

【操作系统原理08】文件管理

文章目录 零.大纲一.文件管理0.大纲1.文件管理1.1 **文件属性**1.2 文件内部数据组织1.3 文件之间的组织1.4操作系统提供功能1.5 文件在外存存放 二.文件的逻辑结构0.大纲1.无结构文件2.有结构文件 三.文件目录0.大纲1.文件控制块2.目录结构3.索引节点(FCB改进) 四.文件共享0.大…...

图论学习笔记 5 - 最小树形图

我们不废话&#xff0c;直接进入正题&#xff1a;最小树形图&#xff0c;一个名字看起来很高级的东西。 声明&#xff1a;为了便于理解&#xff0c;可能图片数量会有亿点点多。图片尺寸可能有的较大。 概念 最小树形图的英文是 Directed Minimum Spanning Tree。 相信懂英文…...

VueUse:组合式API实用函数全集

VueUse 完全学习指南&#xff1a;组合式API实用函数集合 &#x1f3af; 什么是 VueUse&#xff1f; VueUse 是基于 组合式API&#xff08;Composition API&#xff09; 的实用函数集合&#xff0c;为Vue 3开发者提供了丰富的可复用逻辑功能。它通过提供大量预构建的组合函数&…...

《自动驾驶轨迹规划实战:Lattice Planner实现避障路径生成(附可运行Python代码)》—— 零基础实现基于离散优化的避障路径规划

《自动驾驶轨迹规划实战&#xff1a;Lattice Planner实现避障路径生成&#xff08;附可运行Python代码&#xff09;》 —— 零基础实现基于离散优化的避障路径规划 一、为什么Lattice Planner成为自动驾驶的核心算法&#xff1f; 在自动驾驶的路径规划领域&#xff0c;Lattice…...

嵌入式笔试题+面试题

一、嵌入式笔试题 1) int a; 2) int *a; 3) int **a; 4) int a[10]; 5) int *a[10]; 6) int (*a)[10]; 7) int (*a)(int); 8) int (*a[10])(int); (1) 一个整型数 (2) 一个指向整型数的指针 (3) 一个指向指针的的指针&#xff0c;它指向的指针是指向一个整型数 (4) 一个有10个…...

【Go语言生态】

在Go语言生态中&#xff0c;以下工具和方法可以实现类似Laravel的dump()或Symfony的VarDumper的结构体美化打印和调试功能&#xff1a; 使用spew库 spew是Go社区广泛使用的结构化输出库&#xff0c;提供深度嵌套结构的可读性展示&#xff1a; import "github.com/davec…...

PyTorch——卷积操作(2)

二维矩阵 [[ ]] 这里面conv2d(N,C,H,W)里面的四个是 N就是batch size也就是输入图片的数量&#xff0c;C就是通道数这只是一个二维张量所以通道为1&#xff0c;H就是高&#xff0c;W就是宽&#xff0c;所以是1 1 5 5 卷积核 reshape 第一个参数是batch size样本数量 第二个参数…...

【JavaWeb】SpringBoot原理

1 配置优先级 在前面&#xff0c;已经学习了SpringBoot项目当中支持的三类配置文件&#xff1a; application.properties application.yml application.yaml 在SpringBoot项目当中&#xff0c;我们要想配置一个属性&#xff0c;通过这三种方式当中的任意一种来配置都可以&a…...

BSRR对比BRR对比ODR

✅ 三种操作方式的本质区别 寄存器功能原子操作特点BSRR同时支持置位(1)和复位(0)✔️ 是单指令完成任意位操作&#xff0c;无竞争风险ODR直接读写输出状态❌ 否需"读-改-写"&#xff0c;多线程/中断中需关中断保护BRR只能复位(0)✔️ 是仅清零功能&#xff0c;无置…...

ubuntu22.04安装taskfile

sh -c "$(curl --location https://taskfile.dev/install.sh)" -- -dsudo mv ./bin/task /usr/local/bin/测试 task --version...

记录被mybatis一级缓存坑的问题

背景 我之前有个方法需要多次调用数据库拿数据&#xff0c;由于每次查询数据比较少&#xff0c;所以我前期都是直接查数据库拿的&#xff0c;准备后面再改缓存 // 查询代码 假设在A方法中 List<LeftOrderType> leftOrderTypes orderTypeMapper.selectList(wrapper); …...

遥感影像建筑物变化检测

文章目录 效果1、环境安装2、项目下载3、数据集下载4、模型训练5、模型推理6、推理结果7、批量推理效果 1、环境安装 参考文章 搭建Pytorch的GPU环境超详细 win10安装3DGS环境(GPU)超详细 测试GPU环境可用 2、项目下载 https://gitcode.com/gh_mirrors/ch/change_detectio…...

【数据库】《DBA实战手记》- 读书笔记

《DBA实战手记》基本介绍 作者&#xff1a;薛晓刚 等出版时间&#xff1a;2024年6月出版社&#xff1a;机械工业出版社ISBN&#xff1a;9787111757665 本书是一本指导DBA进行数据库开发和运维的实用手册&#xff0c;本书共9章&#xff0c;包括漫谈数据库、如何提升数据库性能…...

多模态大语言模型arxiv论文略读(103)

Are Bigger Encoders Always Better in Vision Large Models? ➡️ 论文标题&#xff1a;Are Bigger Encoders Always Better in Vision Large Models? ➡️ 论文作者&#xff1a;Bozhou Li, Hao Liang, Zimo Meng, Wentao Zhang ➡️ 研究机构: 北京大学 ➡️ 问题背景&…...

汇编语言基础: 搭建实验环境

环境配置 1.Visual Studio 创建空项目 创建成功 2.平台框架改为为WIN32 右键点击项目 点击属性 点击配置管理器 平台改为Win32(本文使用32位的汇编) 3.生成采用MASM 在项目属性里点击"生成依赖项"的"生成自定义" 勾选 masm 4.创建第一个汇编程序 右…...

SIFT 算法原理详解

SIFT 算法原理详解 SIFT&#xff08;尺度不变特征变换&#xff0c;Scale-Invariant Feature Transform&#xff09;是一种经典的局部特征检测和描述算法&#xff0c;它能够在不同的尺度、旋转和光照变化下稳定地检测图像特征。SIFT 主要包括以下几个步骤&#xff1a;尺度空间极…...

基于springboot的益智游戏系统的设计与实现

博主介绍&#xff1a;java高级开发&#xff0c;从事互联网行业六年&#xff0c;熟悉各种主流语言&#xff0c;精通java、python、php、爬虫、web开发&#xff0c;已经做了六年的毕业设计程序开发&#xff0c;开发过上千套毕业设计程序&#xff0c;没有什么华丽的语言&#xff0…...

短剧系统开发文案:打造沉浸式互动娱乐新体验

一、项目背景 随着短视频与碎片化娱乐的兴起&#xff0c;短剧市场呈现爆发式增长。用户对剧情紧凑、节奏明快、互动性强的内容需求激增&#xff0c;传统影视平台已难以满足个性化与参与感需求。「XX短剧系统」应运而生&#xff0c;致力于打造集内容创作、分发、互动于一体的短…...

第十二节:第四部分:集合框架:List系列集合:LinkedList集合的底层原理、特有方法、栈、队列

LinkedList集合的底层原理 LinkedList集合的应用场景之一 代码&#xff1a;掌握LinkedList集合的使用 package com.itheima.day19_Collection_List;import java.util.LinkedList; import java.util.List;//掌握LinkedList集合的使用。 public class ListTest3 {public static …...

多模态大语言模型arxiv论文略读(104)

Talk Less, Interact Better: Evaluating In-context Conversational Adaptation in Multimodal LLMs ➡️ 论文标题&#xff1a;Talk Less, Interact Better: Evaluating In-context Conversational Adaptation in Multimodal LLMs ➡️ 论文作者&#xff1a;Yilun Hua, Yoav…...

【C++高级主题】多重继承下的类作用域

目录 一、类作用域与名字查找规则&#xff1a;理解二义性的根源 1.1 类作用域的基本概念 1.2 单继承的名字查找流程 1.3 多重继承的名字查找特殊性 1.4 关键规则&#xff1a;“最近” 作用域优先&#xff0c;但多重继承无 “最近” 二、多重继承二义性的典型类型与代码示…...

基于Android的一周穿搭APP的设计与实现 _springboot+vue

开发语言&#xff1a;Java框架&#xff1a;springboot AndroidJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7数据库工具&#xff1a;Navicat12开发软件&#xff1a;eclipse/myeclipse/ideaMaven包&#xff1a;Maven3.6 系统展示 APP登录 A…...

机器学习——使用多个决策树

使用单一决策树的弱点之一是决策树对数据中的微小变化非常敏感&#xff0c;一个使算法不那么敏感或更健壮的解决方案&#xff0c;不是建立一个决策树&#xff0c;而是要建立大量的决策树&#xff0c;我们称之为树合奏。 在这个例子中&#xff0c;我们一直在使用最好的特性来分…...

C# 中的对话框与导航:构建流畅用户交互的完整指南

在现代应用程序开发中&#xff0c;良好的用户交互体验是成功的关键因素之一。作为.NET开发者&#xff0c;熟练掌握C#中的对话框与导航技术&#xff0c;能够显著提升应用程序的易用性和专业性。本文将全面探讨Windows Forms、WPF、ASP.NET Core和MAUI等平台下的对话框与导航实现…...

DeepSeek - 尝试一下GitHub Models中的DeepSeek

1.简单介绍 当前DeepSeek使用的人很多&#xff0c;各大AI平台中也快速引入了DeekSeek&#xff0c;比如Azure AI Foundary(以前名字是Azure AI Studio)中的Model Catalog, HuggingFace, GitHub Models等。同时也出现了一些支持DeepSeek的.NET类库。微软的Semantic Kernel也支持…...

【判断酒酒花数】2022-3-31

缘由对超长正整数的处理&#xff1f; - C语言论坛 - 编程论坛 void 判断酒酒花数(_int64 n) {//缘由https://bbs.bccn.net/thread-508634-1-1.html_int64 t n; int h 0, j 0;//while (j < 3)h t % 10, t / 10, j;//整数的个位十位百位之和是其前缀while (t > 0)h t…...