板块一 Servlet编程:第四节 HttpServletResponse对象全解与重定向 来自【汤米尼克的JAVAEE全套教程专栏】
板块一 Servlet编程:第四节 HttpServletResponse对象全解与重定向
- 一、什么是HttpServletResponse
- 二、响应数据的常用方法
- 三、响应乱码问题
- 字符流乱码
- 字节流乱码
- 四、重定向:sendRedirect
- 请求转发和重定向的区别
在上一节中,我们系统的学习了请求响应在Servlet中
service()
方法的第一个形参HttpServletRequest(请求)对象,这一节中我们将学习它的兄弟,service()
方法的第二个形参HttpServletResponse(响应)对象
一、什么是HttpServletResponse
在我们已然熟悉的浏览器访问Servlet的过程中。Request和Response 对象分别代表请求和响应:通过Request对象获取客户端数据;通过 Response 对象向客户端输出数据:
service()
方法中形参接收的是HttpServletResponse接口的实例化对象,它继承自ServletResponse接口,专门用来封装HTTP响应消息,由于HTTP响应消息分为状态行、响应消息头、消息体三部分(详见HTTP协议理论与服务器请求响应原理小节),因此在HttpServletResponse中定义了状态行、响应消息头、消息体三部分。
- 状态行部分
响应消息头包含了关于响应的附加信息,例如内容类型、内容长度、缓存控制等。由setStatus(int status)
方法实现,该方法用于设置HTTP响应消息的状态码,并生成相应代码;默认会生成一个状态码为200的状态行; - 响应消息头部分
响应消息头包含了关于响应的附加信息,例如内容类型、内容长度、缓存控制等。可以使用setHeader(String name, String value)
方法设置响应消息头的字段和值,例如setHeader("Content-Type", "text/html")
设置内容类型为HTML。如果要设置相同字段的多个值,可以使用addHeader(String name, String value)
方法,例如addHeader("Set-Cookie", "cookie1=value1")
。此外还可以使用一些特定的方法来设置常见的响应消息头,例如setContentType(String type)
、setContentLength(int len)
等 - 消息体部分
消息体包含了实际的响应数据。可以通过获取ServletOutputStream或PrintWriter对象来写入响应消息体。getOutputStream()
方法返回一个可以写入二进制数据的ServletOutputStream对象。
getWriter()
方法返回一个可以写入字符数据的PrintWriter对象。
可以使用这些对象的方法将数据写入响应消息体,例如print(String s)、write(byte[] b)
等。
二、响应数据的常用方法
接收到客户端请求后,可以通过HttpServletResponse对象直接进行响应,响应时需要获取输出流。
有两种形式:
getWriter()
获取字符流(只能响应字符串)getOutputStream()
获取字节流(能响应一切数据)
响应回的数据到客户端被浏览器解析
注意:两者不能同时使用
实例
在start.java导入PrintWriter类,并在service()中写入测试代码
// 获取字符输出流
PrintWriter writer = resp.getWriter();
//输出数据
writer.write("Hello");
启动服务器,在浏览器中访问得
在start.java中导入ServletOutputStream类,并在service()中写入测试代码
//得到字节输出流
ServletOutputStream out = resp.getOutputStream();
// 输出数据
out.write("Hi".getBytes());
启动服务器,在浏览器中访问得
但当两者同时使用时
start.java
package www.caijiyuan;import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;@WebServlet("/start")
public class start extends HttpServlet {@Overrideprotected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {// 获取字符输出流PrintWriter writer = resp.getWriter();//输出数据writer.write("Hello");//得到字节输出流ServletOutputStream out = resp.getOutputStream();// 输出数据out.write("Hi".getBytes());}
}
启动服务器,在浏览器中访问,只得到了第一个的打印内容
这是为什么呢?查看报错信息
原来是
getWriter()
已经调用过response对象了,如果再响应一次response对象就已经不存在了
三、响应乱码问题
在上一节中我们使用request.setCharacterEncoding("UTF-8");
解决了请求时中文乱码的问题,同样,在响应时也存在中文乱码问题。这是因为服务器响应的数据也会经过网络传输,服务器端有一种编码方式,在客户端也存在一种编码方式,当两端使用的编码方式不同时则出现乱码。
字符流乱码
对于getWriter()
获取到的字符流,响应中文必定出乱码,由于服务器端在进行编码时默认会使用ISO-8859-1格式的编码,该编码方式并不支持中文。要解决该种乱码只能在服务器端告知服务器使用一种能够支持中文的编码格式,这也是我们在解决请求时中文乱码的方法
response.setCharacterEncoding("UTF-8");
此时还只完成了一半的工作
要保证数据正确显示,还需要指定客户端的解码方式
response.setHeader("content-type", "text/html; charset=UTF-8");
两端指定编码后,乱码就解决了。一句话:保证发送端和接收端的编码一致
实例
我们在start.java的service()中写入测试测试代码,试图打印中文
// 获取字符输出流
PrintWriter writer = resp.getWriter();
//输出数据
writer.write("汤米尼克");
启动服务器,在浏览器中访问,发现输出中文乱码
设置服务器和客户端的编码格式统一
// 设置服务端的编码
resp.setCharacterEncoding("UTF-8");
// 设置客户端的响应类型及编码
resp. setHeader("content-type", "text/html; charset=UTF-8");
// 获取字符输出流
PrintWriter writer = resp.getWriter();
// 输出数据
writer.write("汤米尼克");
重启浏览器,再在浏览器中访问就解决问题了
理解了原理,其实我们还可以同时设置客户端和服务端的编码方式
response.setContentType( "text/html; charset=UTF-8");
这一句就可以替换上面的两句
字节流乱码
对于getOutputStream()
方式获取到的字节流,响应中文时,由于本身就是传输的字节,所以此时可能出现乱码,也可能正确显示。当服务器端给的字节恰好和客户端使用的编码方式一致时则文本正确显示,否则出现乱码。无论如何我们都应该准确掌握服务器和客户端使用的是那种编码格式,以确保数据正确显示。
因此,字节流乱码的解决方式与上面字符流乱码的解决方式一样,在响应发出之前同时设置服务器和客户端的编码格式统一即可
response.setContentType( "text/html; charset=UTF-8");
四、重定向:sendRedirect
重定向是一种服务器为指导的客户端行为。
怎么理解这句话呢?客户端发出一个请求,被服务器接收处理后进行响应,在响应的同时,服务器会给客户端一个新的地址(下次请求的地址),当客户端接收到响应后,会立刻、马上自动根据服务器给的新地址发起第二个请求,服务器接收请求并作出响应,重定向完成。可以看出这个过程中有两个请求存在,其中两个Servlet的Request对象并不共享、不能传值,属于客户端行为。
在Servlet中重定向的语句为
response.sendRedirect("url");
实例:从start.java重定向到after.java的过程
在start.java的service()
中写入重定向前的测试代码
System.out.println("这里是start");
resp.sendRedirect("after");
在after.java的service()
中写入重定向到底测试代码
System.out.println("这里是after");
启动服务器,在浏览器中输入start的地址
回车访问后地址立即跳转到after,说明重定向的地址栏会发生改变
同时控制台输出了
那么重定向在服务器中的响应头是如何实现的?
如下图,在开发者工具中打开响应头的内容
会发现start文件响应行的状态码是302,这就是重定向的状态码
并且响应头键值对中Location键的值就是要重定向到的地址:after文件
这与我们在第一节 HTTP协议理论与服务器请求响应原理中学习的响应头的知识首尾呼应起来了
请求转发和重定向的区别
上一节中我们学习了Request对象的请求转发,这一节又学习了Response对象的重定向,两兄弟让人傻傻分不清,必须好好区分区分
请求转发 | 重定向 |
---|---|
request.getRequestDispatcher("url").forward(request, response); | response.sendRedirect("url"); |
服务器端行为 | 客户端行为 |
一次请求,Request域中数据共享 | 两次请求,Request域中数据不共享 |
地址栏不发生变化 | 地址栏发生变化 |
跳转只能在当前站点内 | 跳转任意地址 |
在这一节中我们学习了HttpServletResponse对象,学习了字符流字节流响应方法、重定向方法。不禁思考,Servlet作为“后端”,在Web交互中最重要的作用就是传递各种数据,但目前我们学到的传值的方法还知之甚少,在下一节中我们将学习Cookie对象、HttpSession对象、ServletContext对象,它们作为不同特点的容器在Servlet上可以实现不同范围的传值
相关文章:

板块一 Servlet编程:第四节 HttpServletResponse对象全解与重定向 来自【汤米尼克的JAVAEE全套教程专栏】
板块一 Servlet编程:第四节 HttpServletResponse对象全解与重定向 一、什么是HttpServletResponse二、响应数据的常用方法三、响应乱码问题字符流乱码字节流乱码 四、重定向:sendRedirect请求转发和重定向的区别 在上一节中,我们系统的学习了…...
漫谈:C/C++ char 和 unsigned char 的用途
C/C的字符默认是有符号的,这一点非常的不爽,因为很少有人用单字节表达有符号数,毕竟,ASCII码是无符号的,对字符的绝大多数处理都是基于无符号的。 这一点在其它编程语言上就好很多,基本上都提供了byte这种类…...

安全保护制度
安全保护制度 第九条 计算机信息系统实行安全等级保护。安全等级的划分标准和安全等级保护的具体办法,由公安部会同有关部门制定。 第十条 计算机机房应当符合国家标准和国家有关规定。 在计算机机房附近施工,不得危害计算机信息系统的安全。 第十一条 进行国际联网的计算…...
沁恒CH32V30X学习笔记07---多功能按键框架使用
多功能按键框架使用 参考开源框架: GitHub - 0x1abin/MultiButton: Button driver for embedded system 框架使用说明: ch32gpio基本驱动 https://blog.csdn.net/u010261063/article/details/136157718 MultiButton 简介 MultiButton 是一个小巧简单易用的事件驱动型按…...

如何看显卡是几G?
created: 2024-02-20T09:22:13 (UTC 08:00) tags: [] source: https://www.sysgeek.cn/windows-check-gpu-model/ author: 海猴子 6 种简单方法:如何在 Windows 中轻松查看显卡型号 - 系统极客 Excerpt 不确定你的显卡型号?使用这 6 个简单有效的方法&a…...

虚拟机--pc端和macOS端互通
windows开启虚拟化 要在Windows系统中开启虚拟化,您可以按照以下步骤操作: 准备工作: 确保您的计算机CPU支持虚拟化技术。在BIOS中开启相应的虚拟化支持。 开启虚拟化: 打开控制面板,点击程序或功能项&am…...

(14)Hive调优——合并小文件
目录 一、小文件产生的原因 二、小文件的危害 三、小文件的解决方案 3.1 小文件的预防 3.1.1 减少Map数量 3.1.2 减少Reduce的数量 3.2 已存在的小文件合并 3.2.1 方式一:insert overwrite (推荐) 3.2.2 方式二:concatenate 3.2.3 方式三ÿ…...

Linux 驱动开发基础知识——LED 模板驱动程序的改造:设备树(十一)
个人名片: 🦁作者简介:学生 🐯个人主页:妄北y 🐧个人QQ:2061314755 🐻个人邮箱:2061314755qq.com 🦉个人WeChat:Vir2021GKBS 🐼本文由…...
学习文档:QT QTreeWidget及其代理
学习文档:QT QTreeWidget及其代理 1. QT QTreeWidget简介 QT QTreeWidget是QT框架中的一个重要组件,用于显示树形数据结构。它提供了一种方便的方式来展示并操作带有层次关系的数据。QTreeWidget可以显示包含多个列的树形视图,每个项目可以…...
代码随想录算法训练营——总结篇
不知不觉跟完了代码训练营为期两个月的训练,现在来做个总结吧~ 记得去年12月上旬的时候,我每天都非常浮躁。一方面,经历了三个多月的秋招,我的日常学习和实验室进展被完全打乱,导致状态很差;另一方面&#…...

更改WordPress作者存档链接author和用户名插件Change Author Link Structure
WordPress作者存档链接默认情况为/author/Administrator(用户名),为了防止用户名泄露,我们可以将其改为/author/1(用户ID),具体操作可参考『如何将WordPress作者存档链接中的用户名改为昵称或ID…...

Kernelized Correlation Filters KCF算法原理详解(阅读笔记)(待补充)
KCF 目录 KCF预备知识1. 岭回归2. 循环移位和循环矩阵3. 傅里叶对角化4. 方向梯度直方图(HOG) 正文1. 线性回归1.1. 岭回归1.2. 基于循环矩阵获取正负样本1.3. 基于傅里叶对角化的求解 2. 使用非线性回归对模型进行训练2.1. 应用kernel-trick的非线性模型…...

安卓游戏开发之图形渲染技术优劣分析
一、引言 随着移动设备的普及和性能的提升,安卓游戏开发已经成为一个热门领域。在安卓游戏开发中,图形渲染技术是关键的一环。本文将对安卓游戏开发中常用的图形渲染技术进行分析,比较它们的优劣,并探讨它们在不同应用场景下的适用…...

python+django+vue汽车票在线预订系统58ip7
本课题使用Python语言进行开发。基于web,代码层面的操作主要在PyCharm中进行,将系统所使用到的表以及数据存储到MySQL数据库中 使用说明 使用Navicat或者其它工具,在mysql中创建对应名称的数据库,并导入项目的sql文件; 使用PyChar…...
2024-2-19
编译安装php下载依赖包时遇到的报错 [rootmasternamed ~]# yum -y install php-mcrypt \ > libmcrypt \ > libmcrypt-devel \ > autoconf \ > freetype \ > gd \ > libmcrypt \ > libpng \ > libpng-devel \ > libjpeg \ > libxml2 \…...

ARM体系在linux中的中断抢占
上一篇说到系统调用等异常通过向量el1_sync做处理,中断通过向量el1_irq做处理,然后gic的工作都是为中断处理服务,在rtos中,我们一般都会有中断嵌套和优先级反转的概念,但是在linux中,中断是否会被其他中断抢…...

STM32的FLASH操作
时间记录:2024/2/19 一、STM32F103C8T6FLASH介绍 (1)flash大小64K,地址0x08000000-0x08010000 (2)此芯片内存大小属于中容量产品,根据数据手册可知中容量产品一个扇区的大小为1K (…...

electron Tab加载动画开启和关闭
记个开发中的bug,以此为鉴。眼懒得时候手勤快点儿,不要想当然!!! 没有转载的价值,请勿转载搬运呦。 WebContents API: Event: did-finish-load 导航完成时触发,即选项卡的旋转…...

深度学习发展的艺术
将人类直觉和相关数学见解结合后,经过大量研究试错后的结晶,产生了一些成功的深度学习模型。 深度学习模型的进展是理论研究与实践经验相结合的产物。科学家和工程师们借鉴了人类大脑神经元工作原理的基本直觉,并将这种生物学灵感转化为数学模…...

las数据转pcd数据
las数据转pcd数据 一、算法原理1.介绍las2.主要函数 二、代码三、结果展示3.1 las数据3.2 las转换为pcd 四、相关数据链接 一、算法原理 1.介绍las LAS文件按每条扫描线排列方式存放数据,包括激光点的三维坐标、多次回波信息、强度信息、扫描角度、分类信息、飞行航带信息、飞…...

Lombok 的 @Data 注解失效,未生成 getter/setter 方法引发的HTTP 406 错误
HTTP 状态码 406 (Not Acceptable) 和 500 (Internal Server Error) 是两类完全不同的错误,它们的含义、原因和解决方法都有显著区别。以下是详细对比: 1. HTTP 406 (Not Acceptable) 含义: 客户端请求的内容类型与服务器支持的内容类型不匹…...
脑机新手指南(八):OpenBCI_GUI:从环境搭建到数据可视化(下)
一、数据处理与分析实战 (一)实时滤波与参数调整 基础滤波操作 60Hz 工频滤波:勾选界面右侧 “60Hz” 复选框,可有效抑制电网干扰(适用于北美地区,欧洲用户可调整为 50Hz)。 平滑处理&…...

渗透实战PortSwigger靶场-XSS Lab 14:大多数标签和属性被阻止
<script>标签被拦截 我们需要把全部可用的 tag 和 event 进行暴力破解 XSS cheat sheet: https://portswigger.net/web-security/cross-site-scripting/cheat-sheet 通过爆破发现body可以用 再把全部 events 放进去爆破 这些 event 全部可用 <body onres…...
spring:实例工厂方法获取bean
spring处理使用静态工厂方法获取bean实例,也可以通过实例工厂方法获取bean实例。 实例工厂方法步骤如下: 定义实例工厂类(Java代码),定义实例工厂(xml),定义调用实例工厂ÿ…...

论文浅尝 | 基于判别指令微调生成式大语言模型的知识图谱补全方法(ISWC2024)
笔记整理:刘治强,浙江大学硕士生,研究方向为知识图谱表示学习,大语言模型 论文链接:http://arxiv.org/abs/2407.16127 发表会议:ISWC 2024 1. 动机 传统的知识图谱补全(KGC)模型通过…...

前端开发面试题总结-JavaScript篇(一)
文章目录 JavaScript高频问答一、作用域与闭包1.什么是闭包(Closure)?闭包有什么应用场景和潜在问题?2.解释 JavaScript 的作用域链(Scope Chain) 二、原型与继承3.原型链是什么?如何实现继承&a…...
【JavaSE】绘图与事件入门学习笔记
-Java绘图坐标体系 坐标体系-介绍 坐标原点位于左上角,以像素为单位。 在Java坐标系中,第一个是x坐标,表示当前位置为水平方向,距离坐标原点x个像素;第二个是y坐标,表示当前位置为垂直方向,距离坐标原点y个像素。 坐标体系-像素 …...

图表类系列各种样式PPT模版分享
图标图表系列PPT模版,柱状图PPT模版,线状图PPT模版,折线图PPT模版,饼状图PPT模版,雷达图PPT模版,树状图PPT模版 图表类系列各种样式PPT模版分享:图表系列PPT模板https://pan.quark.cn/s/20d40aa…...
Spring AI与Spring Modulith核心技术解析
Spring AI核心架构解析 Spring AI(https://spring.io/projects/spring-ai)作为Spring生态中的AI集成框架,其核心设计理念是通过模块化架构降低AI应用的开发复杂度。与Python生态中的LangChain/LlamaIndex等工具类似,但特别为多语…...
return this;返回的是谁
一个审批系统的示例来演示责任链模式的实现。假设公司需要处理不同金额的采购申请,不同级别的经理有不同的审批权限: // 抽象处理者:审批者 abstract class Approver {protected Approver successor; // 下一个处理者// 设置下一个处理者pub…...