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

javaweb--09

一、Response 继承体系与核心概念

1. 继承结构

plaintext

ServletResponse(Java 提供的响应对象根接口,通用协议响应) ↑ 继承 HttpServletResponse(Java 提供的对 HTTP 协议封装的响应对象接口,HTTP 专用) ↑ 实现 ResponseFacade(Tomcat 定义的实现类,Tomcat 内部使用,开发者面向接口编程)
  • 核心逻辑:Tomcat 为每个请求创建Response对象,传入 Servlet 的service()方法,用于设置 HTTP 响应数据,请求处理完成后销毁。

2. Request & Response 分工

  • Request:获取客户端发送的 HTTP 请求数据(请求行、请求头、请求体)
  • Response:设置服务器返回给客户端的 HTTP 响应数据(响应行、响应头、响应体)

二、Response 设置响应数据(3 大部分)

HTTP 响应分为响应行、响应头、响应体三部分,对应不同的设置方法:

1. 响应行相关方法

响应行格式:HTTP/1.1 200 OK

  • 核心方法:void setStatus(int sc)
    • 作用:设置响应状态码
    • 常用状态码:200(成功)、302(重定向)、404(资源未找到)、500(服务器内部错误)

2. 响应头相关方法

响应头是服务器发送的键值对信息,如Content-Type: text/html

  • 核心方法:void setHeader(String name, String value)
    • 作用:设置响应头键值对
    • 常用响应头:Content-Type(告知浏览器响应数据类型)、Location(重定向地址)、Refresh(定时刷新)

3. 响应体相关方法

响应体是服务器返回给客户端的核心数据(如 HTML、文本、文件等)

  • PrintWriter getWriter():获取字符输出流,用于输出文本数据(HTML、普通字符串等)
  • ServletOutputStream getOutputStream():获取字节输出流,用于输出二进制数据(图片、文件下载等)

三、Response 响应字符数据(常用场景)

1. 基础使用步骤

java

运行

// 1. 通过Response对象获取字符输出流 PrintWriter writer = resp.getWriter(); // 2. 写数据(文本/HTML) writer.write("aaa"); writer.write("<h1>aaa</h1>");

2. 解决中文乱码问题(关键)

必须在获取流之前,设置响应的编码格式和Content-Type,让浏览器以 UTF-8 解析:

java

运行

// 推荐写法:一行代码同时设置编码和Content-Type response.setContentType("text/html;charset=utf-8"); // 等价写法(不推荐,分两步) // response.setHeader("content-type", "text/html"); // response.setCharacterEncoding("utf-8"); // 再获取流、写数据 PrintWriter writer = response.getWriter(); writer.write("你好"); writer.write("<h1>aaa</h1>");
  • 核心要求:必须在第一次获取流之前调用设置编码的方法,否则设置无效

四、Response 两种输出流核心对比

表格

流类型获取方法适用场景编码问题
字符输出流PrintWriter getWriter()输出文本、HTML 等字符数据需手动设置 UTF-8,解决中文乱码
字节输出流ServletOutputStream getOutputStream()输出图片、文件等二进制数据无编码问题,直接写字节

五、字符输出流(getWriter())详解

1. 基础使用步骤

java

运行

// 1. 通过Response对象获取字符输出流 PrintWriter writer = resp.getWriter(); // 2. 写数据(文本/HTML) writer.write("aaa"); writer.write("<h1>aaa</h1>");

2. 关键注意事项

  • 流的关闭:该流不需要手动关闭,随着响应结束、response 对象销毁,由服务器自动关闭
  • 中文乱码问题
    • 乱码原因:字符输出流默认编码为ISO-8859-1(不支持中文)
    • 解决方案:在获取流之前,设置响应编码和 Content-Type

      java

      运行

      // 推荐写法:一行代码同时设置编码和Content-Type resp.setContentType("text/html;charset=utf-8");
    • 必须在第一次获取流之前调用,否则设置无效

六、字节输出流(getOutputStream())详解

1. 基础使用步骤

java

运行

// 1. 通过Response对象获取字节输出流 ServletOutputStream outputStream = resp.getOutputStream(); // 2. 写数据(字节数组/二进制数据) outputStream.write(字节数据);

2. 工具类简化:IOUtils(commons-io)

(1)导入 Maven 依赖

xml

<dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>2.6</version> </dependency>
(2)使用方法

java

运行

// 一行代码完成流的复制,简化文件下载等操作 IOUtils.copy(输入流, 输出流);
  • 适用场景:文件下载、图片回显等需要传输二进制数据的场景
  • 优势:无需手动循环读写,自动处理流的关闭

七、重定向(Redirect):资源跳转方式

1. 重定向原理

重定向是一种客户端发起的资源跳转,流程如下:

  1. 浏览器请求资源 A,资源 A 返回302状态码 +Location: 资源B路径响应头
  2. 浏览器收到响应,自动向资源 B 发起新的请求
  3. 资源 B 处理请求,返回响应给浏览器

2. 实现方式

方式 1:原生写法(分步设置)

java

运行

// 设置302状态码 resp.setStatus(302); // 设置Location响应头,指定跳转路径 resp.setHeader("location", "/request-demo/resp2");
方式 2:简化写法(推荐)

java

运行

// 一行代码完成重定向,自动设置302和Location response.sendRedirect("/request-demo/resp2");

3. 重定向特点

  • 浏览器地址栏路径会发生变化(变为资源 B 的路径)
  • 可以跳转到任意外部资源(其他服务器、其他网站)
  • 两次请求,无法使用request共享数据(每次请求对应独立的 request 对象)

八、请求转发(Forward):服务器内部跳转

1. 转发原理

请求转发是服务器内部的资源跳转,流程如下:

  1. 浏览器请求资源 A,资源 A 在服务器内部将请求转发给资源 B
  2. 资源 B 处理请求,返回响应给浏览器
  3. 整个过程浏览器只发起一次请求,感知不到转发

2. 实现方式

java

运行

// 获取请求转发器,指定资源B路径,调用forward方法完成转发 req.getRequestDispatcher("资源B路径").forward(req, resp);

3. 转发特点

  • 浏览器地址栏路径不发生变化(始终是资源 A 的路径)
  • 只能转发到当前服务器的内部资源
  • 一次请求,可以在转发的资源间通过request共享数据

4. Request 域对象(转发共享数据)

通过request对象在转发的资源间传递数据,方法如下:

表格

方法作用
void setAttribute(String name, Object o)存储数据到 request 域中
Object getAttribute(String name)根据 key 获取值
void removeAttribute(String name)根据 key 删除该键值对

九、重定向 vs 请求转发 核心对比

表格

对比维度重定向(Redirect)请求转发(Forward)
跳转本质客户端跳转(两次请求)服务器内部跳转(一次请求)
地址栏变化变化(显示目标资源路径)不变(显示原资源路径)
跳转范围可跳外部资源(任意 URL)仅可跳当前服务器内部资源
请求共享无法共享 request 数据可共享 request 数据
状态码302200
路径要求需加虚拟目录(项目访问路径)无需加虚拟目录

十、路径问题(开发高频坑点)

1. 核心规则:谁使用路径?

  • 浏览器使用的路径:必须加虚拟目录(项目访问路径)
  • 服务器端使用的路径:不需要加虚拟目录

2. 常见场景对照表

表格

场景使用者是否加虚拟目录示例
<a href="路径">超链接浏览器必须加<a href="/request-demo/resp1">跳转</a>
<form action="路径">表单提交浏览器必须加<form action="/request-demo/resp2">
resp.sendRedirect("路径")重定向浏览器必须加response.sendRedirect("/request-demo/resp3");
req.getRequestDispatcher("路径")请求转发服务器不需要加request.getRequestDispatcher("resp4").forward(req, resp);

3. 动态获取虚拟目录(推荐,避免硬编码)

java

运行

// 动态获取项目虚拟目录,适配不同部署环境 String contextPath = request.getContextPath(); // 重定向时拼接 response.sendRedirect(contextPath + "/resp2");

十一、完整实战示例(Servlet 综合使用)

java

运行

@WebServlet("/resp1") public class ResponseDemo1 extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 1. 设置响应编码,解决中文乱码 response.setContentType("text/html;charset=utf-8"); // 2. 响应字符数据 PrintWriter writer = response.getWriter(); writer.write("<h1>这是响应测试</h1>"); writer.write("你好,Response"); // 3. 重定向示例 // response.sendRedirect(request.getContextPath() + "/resp2"); // 4. 请求转发示例(共享数据) request.setAttribute("msg", "转发测试数据"); request.getRequestDispatcher("/resp2").forward(request, response); } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } } @WebServlet("/resp2") public class ResponseDemo2 extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=utf-8"); // 获取转发共享的数据 Object msg = request.getAttribute("msg"); response.getWriter().write("<h1>resp2 收到数据:" + msg + "</h1>"); } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
http://www.jsqmd.com/news/654185/

相关文章:

  • VMware虚拟机扩容
  • 2026年质量好的数字压力变送器/卫生型压力变送器/投入式液位压力变送器最新TOP厂家排名 - 品牌宣传支持者
  • nli-distilroberta-base效果实测:不同长度句子对(5-200字)NLI准确率稳定性报告
  • 2026年知名的包装/高性能泡沫塑料包装/EPS包装/医药试剂底托泡沫包装生产商哪家强 - 品牌宣传支持者
  • 2026年知名的工业气膜/气膜建筑/气膜煤棚/基坑气膜优质供应商推荐 - 行业平台推荐
  • HTML怎么生成订单预览_HTML只读订单信息结构【操作】
  • 2026年知名的折叠PP中空板周转箱/电子元件PP中空板周转箱厂家推荐及选购指南 - 品牌宣传支持者
  • 暖玛士发布农业大棚供暖定制方案
  • Jimeng LoRA保姆级教程:Z-Image-Turbo底座LoRA兼容性测试矩阵说明
  • 免费开源教务管理系统:SchoolCMS让中小学校园管理更智能高效
  • 2026年知名的玻纤塑料粒子/塑料粒子厂家推荐及采购参考 - 品牌宣传支持者
  • Python鸭子多态
  • Hyper-V虚拟化平台GPU分区与半虚拟化技术深度解析及选型指南
  • 你还在手动整理会议笔记?2026奇点大会演示的AI学习助手已实现“语义意图捕获→知识脉络自构→能力缺口反推”全链路闭环
  • Qwen3本地部署教程:使用VMware虚拟机搭建测试环境
  • 2026年热门的pp塑料中空板/PP塑料中空板卷材厂家选购全指南(完整版) - 品牌宣传支持者
  • 通义千问1.5-1.8B-Chat-GPTQ-Int4 轻量化模型部署对比:GPTQ-Int4 vs. 原生FP16效果与资源占用
  • 2026年数字IC设计华为笔试带答案解析
  • 2026年质量好的洗车海绵/海绵/海绵拖把/洗澡海绵厂家选购指南与推荐 - 行业平台推荐
  • 第四周第一篇
  • 颠覆性设计转代码:3步将Figma设计变成生产级代码
  • 网络安全入行门槛越来越高:这 4 个证书没用,这 3 个才值钱
  • 2026年口碑好的哈尔滨二手车买卖/哈尔滨二手车出售热门交易推荐 - 行业平台推荐
  • Phi-4-mini-reasoning轻量推理新选择:开源可部署+128K上下文实战评测
  • Qwen3-ASR-1.7B在呼叫中心语音分析中的应用
  • 实战指南:用 Python + NLP 搭建一套轻量级 AI 舆情监控系统
  • 别再死记硬背了!用Python和NumPy玩转三维平面方程(附可视化代码)
  • 实战解析:从应急响应到内网渗透的完整攻击链分析
  • ACE-Step创作体验:输入简单描述,生成专业级音乐片段,小白友好
  • 微信小程序调用Pixel Couplet Gen:灰度发布与版本回滚策略