目录


HttpServletResponse简介

Web服务器收到客户端的http请求,会针对每一次请求,分别创建一个用于代表请求的request对象、和代表响应的 response对象

Requestresponse 对象,既然代表请求和响应,那么我们要 获取客户端提交过来的数据,只要找到request对象就OK了;要向客户机输出数据,只要找response对象就OK了


向客户机写数据

需要一个响应行响应头响应数据 ;这些 HttpServletResponse 对象都提供方法来完成 ;

  • 响应行就是一个状态码:

    设置状态码: setStatus(int) ;

  • 响应头

    写响应头 : setHeader(键,值)

    添加响应头: addHeader(键,值)

    response.setHeader("xxxx","yyyy");

    二者区别:如果已经有某一个头存在了。那么前者会覆盖掉这个头,后者会添加新的 ;

    关于添加和写响应头,Sun 公司还提供了另个添加特别的头的方法:

    添加整数: setIntHeader(头名字,int)

    添加时间: setDataHear(头名字,long)

    不然,我们将时间、整数转换为字符串,还需要做特定转换;

    HttpServletResponse 并没有输出流的方法,他输出流的方法,来自其父类ServlrtResponse ,这个类有两个输出流,一个字节流,一个字符流

//  字字流输出
ServletOutputStream getOutputStream() throws IOException;
// 字符流输出
PrintWriter getWriter() throws IOException;
  • 检测是否包含某个头

    containsHeader(头名字)


HttpServletResponse应用

下面都是具体的应用

打印中文,让浏览器显示不乱码 ;

思路:在往 response 里面写数据的时候,我们要 指定数据的解码方式;并且还要 添加响应头来告诉浏览器用什么码表来编码 ,否则,虽然我们对网页指定了编码,但是浏览器不知道我们是啥码表编码的;


  • 方式一(通过响应头来控制浏览器--使用OutputStream)
//      准备发送给浏览器的汉字
String name = "中国";
// 在响应头中写上编码方式
response.setHeader("content-type", "text/html;charset=utf-8");
// 因为我们使用的是字节流,因此,将字符串转换为字节
// 通过getByte()方法,是可以指定解码的码表,不写就是默认按照平台的码表
response.getOutputStream().write(name.getBytes("utf-8"));

  • 方式二(通过meta标签)
  meta 标签是可以控制浏览器的行为的;

<meta http-equiv='content-type' content='text/html;charset=utf-8'>


这句标签的意思是告诉,向你输出的是一个HTML页面,编码是utf-8

//        准备发送给浏览器的汉字
String name = "我独自穿越这条伤心的街\n" +
"\n" +
"怎么忘记你回过头的身影\n" +
"\n" +
"我鼓起勇气忘记这个距离\n" +
"\n" +
"怎么告诉你爱已慢慢烧尽\n" +
"\n" +
"不如远走高飞自己解围";
// 获取输出流
ServletOutputStream outputStream = response.getOutputStream(); // meta标签这句话全是英文,英文无论在哪个码表,码值都是一样的,
// 因此,可以使用任何一张码表进行解码,这里 getBytes() 没有指定使用什么码表,
// 因此默认使用平台的编码表
outputStream.write("<meta http-equiv='content-type' content='text/html;charset=utf-8'>".getBytes());
outputStream.write("<hr>".getBytes());
//name是汉字字符串,因此进行编码
outputStream.write(name.getBytes("utf-8"));

  • 方式三(通过PrintWriter 标签)

上面两种方式,都是通过字节流输出文字的,第三种则通过字符流输出 ;

 String message = "你都如何回忆我" +
"<br>" +
"带着笑或是很沉默";
// 避免乱码问题,我们要为response指定码表
// 写数据,这里不指定码表的话,它会默认使用老外的iso码表 ;
// 这张码表里面根本就没有汉字;因此,汉字编码时查表都是问号 ??
response.setCharacterEncoding("utf-8");
// 还要告诉浏览器,我们的编码方式
response.setHeader("content-type","text/html;charset=utf-8");
//// 这一句代码可以完成上面的两步操作
// response.setContentType("text/html;charset=utf-8"); // 获得printWriter
PrintWriter writer = response.getWriter() ; writer.write(message);

下载文件

只要在浏览器的响应头中,添加一个响应头:content-disposition","attachment;filename=

如果下载文件的名字是中文的话,需要URL编码 : URLEncoder.encode(name,"UTF-8")

//        下载文件,需要获取文件的名字,因此使用获得绝对路径的方法
String path = this.getServletContext().getRealPath("/download/古风.jpg") ;
// 从绝对路径中截取出文件的名字
String name = path.substring(path.lastIndexOf("\\")+1) ; // 告诉浏览器用下载的方式打开文件
// 下载文件的文件的文件名是中文,
// 需要URL编码,URLEncoder.encode
// 这里写明URL编码,
response.setHeader("content-disposition","attachment;filename="+ URLEncoder.encode(name,"UTF-8")); // 读取照片资源,
InputStream in = new FileInputStream(path) ;
// 将数据写回到浏览器
ServletOutputStream out = response.getOutputStream();
int len = 0 ;
byte[] buf = new byte[1024] ;
while((len = in.read(buf))!=-1){
out.write(buf,0,len);
out.flush();
} in.close();
out.close();

输出随机图片(验证码)

BufferImage 类,在内存创建图片(明日更新)


不要缓存

注意:在输出验证码的时候,需要告诉浏览器,不要缓存验证码图片 ;,我们需要把三个头都写上,为了所有浏览器都能不缓存;

  • 代码控制

response.setDateHeader("Expires",-1);

response.setHeader("Cache-Control","no-cache");

response.setHeader("Pragma","no-cache");

  • <mate>标签控制

当然我们还可以使用标签来模拟响应头,控制浏览器的行为 ;

  1. <meta http-equiv="Expires" content="0">
  2. <meta http-equiv="Cache-Control", content="no-cache">
  3. <meta http-equiv="Progma" content="no-cache">

图片的src地址

图片的 src 地址,跟在浏览器中访问的地址是一样的,但是不需要写明端口 ;

验证码: <img src="/javaWeb/suiji"><br>


点击图片就换一张图

需要使用到JavaScript的知识;so easy
   <script type="text/javascript">
function changeImg(img){
// 点击图片,再次将图片的src赋值为当前的src
// 就是重新去访问,图片的地址,达到换一张图片的目的
// 但是,我们需要在这个地址后面,加上一些东西
// 否则,点击图片,不会去重新访问服务器的
// 直接拿之前的缓存,这里的缓存跟前面的缓存,不是一回事
img.src = img.src + "?" + new Date().getDate() ;
}
</script>

让鼠标在图片上变成小手样式

style="cursor: hand" 在标签属性里面写上 ;


控制浏览器缓存

向浏览器发送一个响应头,字段为:expires ;后面的参数为 当前时间+要缓存的时间千万不要直接写缓存时间,这个时间是从1970 开始计算的

获取当前系统的时间的方法:System.currentTimeMills()


控制浏览器定时刷新

发送头:refresh ,参数是 时间 ;两个都是字符串;

  • 定时刷新

    每3秒刷新一次

response.setHeader("refresh", "3");
  • 可以完成指定浏览器访问某地址 ;

    可在第二个参数里面添加url地址。这样,时间到,就会跳转到那个地址

response.setHeader("refresh", "3;url='https://www.baidu.com'");

实现请求重定向

实现方式: sendRedirect(地址)

       response.sendRedirect("/javaWeb/1.html");

实现原理:利用 302状态码和localtion头

方法的出现,是为了简化代码 ;

重定向能不用,就不用,它请求两次,会加重服务器压力


response细节

getOutputStreamgetWriter 方法分别用于得到 输出二进制数据、输出文本数据的servletOutputStreamPrintWriter 对象 ;

  • 方法互斥

getOutputStreamgetWriter 这两个方法相互排斥,调用了其中的任何一个方法后,就不能再调用另一个方法

  • response中数据——> http正文

Servlet程序向ServletOutputStream或者PrintWriter对象中写入的数据被Servlet引擎从response里面获取,Servlet引擎将这些数据当做响应消息的正文,然后再与响应状态行和各响应头组合后输出到客户端

  • 关闭close

Servlet的service方法结束后,Servlet引擎将检查getWriter或者getOutputStream方法返回的输出流对象是否已经调用过close方法,如果没有,servlet引擎将调用close方法关闭输出流对象

(五)Respose 知识点总结 (来自那些年的笔记)的更多相关文章

  1. (一)HTTP协议的一些知识点(来自那些年的笔记)

    目录 http协议1.0.1.1两个版本的区别 访问几次服务器? Http请求行和请求方式详解 可以在超链接上传一些数据 HTTP请求头各个头字段的详解 HTTP响应和响应行状态详解 断点下载 HTT ...

  2. Python 五个知识点搞定作用域

    Python 五个知识点搞定作用域 1.块级作用域 想想此时运行下面的程序会有输出吗?执行会成功吗? #块级作用域 if 1 == 1: name = "lzl" print(na ...

  3. 第五十个知识点:什么是BLS基于对的签名方案?

    第五十个知识点:什么是BLS基于对的签名方案? BLS签名方案使用了椭圆曲线上了Weil对,本质上是一个在曲线上除n划分的双线性形式,使用 \(n^{th}\) 个单位根. 假设我们有一个椭圆曲线\( ...

  4. 第五个知识点 复杂性为NP类是什么意思

    第五个知识点 复杂性为NP类是什么意思 原文地址:http://bristolcrypto.blogspot.com/2014/11/52-things-number-5-what-is-meant- ...

  5. 第十五个知识点:RSA-OAEP和ECIES的密钥生成,加密和解密

    第十五个知识点:RSA-OAEP和ECIES的密钥生成,加密和解密 1.RSA-OAEP RSA-OAEP是RSA加密方案和OAEP填充方案的同时使用.现实世界中它们同时使用.(这里介绍的只是&quo ...

  6. 第二十五个知识点:使用特殊的素数定义$GF(p)$和$GF(2^n)$的方法。

    第二十五个知识点:使用特殊的素数定义\(GF(p)\)和\(GF(2^n)\)的方法. 在我们之前看到的博客中,当实现密码学方案时,一个最频繁调用的操作就是模运算.不幸的是,尽管模块化的使用非常广泛, ...

  7. 第三十五个知识点:给针对ECDLP问题的Pollard rho,Pollard "Kangaroo",parallel Pollard rho攻击的一个粗略的描述

    第三十五个知识点:给针对ECDLP问题的Pollard rho,Pollard "Kangaroo",parallel Pollard rho攻击的一个粗略的描述 我们的目标是对任 ...

  8. 第四十五个知识点:描述一些对抗RSA侧信道攻击的基础防御方法

    第四十五个知识点:描述一些对抗RSA侧信道攻击的基础防御方法 原文地址:http://bristolcrypto.blogspot.com/2015/08/52-things-number-45-de ...

  9. Python开发【杂货铺】:五个知识点搞定作用域

    1.块级作用域 想想此时运行下面的程序会有输出吗?执行会成功吗? #块级作用域 if 1 == 1: name = "lzl" print(name) for i in range ...

随机推荐

  1. php cookie 操作

    创建 cookie <?php setcookie(); ?> 取回 Cookie 的值 <?php // Print a cookie echo $_COOKIE["us ...

  2. docker 笔记--运行中的容器如何添加端口映射

    解决: iptables -t nat -A DOCKER -p tcp --dport ${YOURPORT_1} -j DNAT --to-destination ${CONTAINERIP}:$ ...

  3. bzoj2406 矩阵

    我们不妨想一想,这道题目又有\(abs\)又有\(Max\)不是很好算对吧. 所以我们二分答案,考虑怎么\(check\). 对于一个点,显然它能够取的范围是\([l,r]\),接着是对于一行一列都有 ...

  4. elasticsearch alias

    索引别名API允许使用一个名字来作为一个索引的别名,所有API会自动将别名转换为实际的索引名称. 别名也可以映射到多个索引,别名不能与索引具有相同的名称.别名可以用来做索引迁移和多个索引的查询统一,还 ...

  5. 深入理解JVM虚拟机5:虚拟机字节码执行引擎

    虚拟机字节码执行引擎   转自https://juejin.im/post/5abc97ff518825556a727e66 所谓的「虚拟机字节码执行引擎」其实就是 JVM 根据 Class 文件中给 ...

  6. [Andorid] 通过JNI实现kernel与app进行spi通讯

    CPU:RK3399 系统:Android 7.1 人脸识别的要求越来越高,因此主板增加了 SE 加密芯片,加密芯片通过 spi 接口与 CPU 通讯. 对于 kernel 层的代码,Linux 原始 ...

  7. little difference

    把一个数字分解成有限个相差不超过1的因子: 这里如果是2的n次幂就不可以,因为比如4,可以拆成 2,2,或者2,2,1,或者2,2,1,1,...所有这个不可以,没想到这个 数据是1E18,一开始想觉 ...

  8. THINKPHP扩展PHPEXCEL,PHP7.2以上版本无法导出Excel

     THINKPHP扩展PHPEXCEL与PHP7.3高版本兼容问题 框架:THINKPHP5,PHPEXCEL版本:1.81 无法导出EXCEL原因为Shared/OLE.php第290行使用cont ...

  9. Android:Recents和AMS中历史任务的区别

    1.1 任务和返回栈 - 实际数据模型  这个是指在调度体系里实际保存的TaskRecord实例,而ActivityRecord-TaskRecord-ActivityStack之间的关系建议看官方文 ...

  10. [Java复习] 分布式事务 Part 2

    分布式事务了解吗?如果解决分布式事务问题的? 面试官心里: 只要聊到你做了分布式系统,必问分布式事务,起码得知道有哪些方案,一般怎么来做,每个方案的优缺点是什么. 为什么要有分布式事务? 分布式事务实 ...