Java Web学习 Response

3 Response对象

(1) Request继承体系

ServletResponse(Java提供的请求对象根接口)
    |extends
HttpServletResponse(Java提供的对HTTP协议封装的请求对象接口)
//ServletResponse和HttpServletResponse是继承关系,并且两个都是接口,接口是无法创建对象
    |implements
ResponseFacade(Tomcat定义的实现类)
//该类实现了HttpServletResponse接口,也间接实现了ServletResponse接口。
//要想了解ResponseFacade中都提供了哪些方法,我们可以直接查看JavaEE的API文档中关于ServletResponse和HttpServletResponse的接口文档,因为ResponseFacade实现了其接口就需要重写接口中的方法

(2) Response设置响应数据功能介绍

<1> 获取响应行数据
设置响应状态码
void setStatus(int sc);
<2> 获取响应头数据
设置响应头键值对
void setHeader(String name,String value);
<3> 获取响应体数据//response也可以没有响应体
//对于响应体,是通过字符、字节输出流的方式往浏览器写
<3.1> 获取字符输出流
PrintWriter getWriter();
<3.2> 获取字节输出流
ServletOutputStream getOutputStream();

(3) Respones请求重定向

<1> Response重定向(redirect):一种资源跳转方式
<1.1> 浏览器发送请求给服务器,服务器中对应的资源A接收到请求
<1.2> 资源A现在无法处理该请求,就会给浏览器响应一个302的状态码+location的一个访问资源B的路径
<1.3> 浏览器接收到响应状态码为302就会重新发送请求到location对应的访问地址去访问资源B
<1.4> 资源B接收到请求后进行处理并最终给浏览器响应结果,这整个过程就叫重定向
<2> 重定向的实现方式
resp.setStatus(302);
resp.setHeader("location","资源B的访问路径");
*简化的编写方式//一般使用该方式
resposne.sendRedirect("/request-demo/resp2")
//路径必须为完整的虚拟路径,request-demo为模块名,resp2为servlet路径
//servlet路径访问时,不受文件夹路径影响,即使移动servlet类到其他文件夹,原有的servlet路径仍可访问。
<3> 重定向的特点
//与请求转发完全相反,使用哪个,需要根据具体的业务来决定。
<3.1>浏览器地址栏路径发送变化
//当进行重定向访问的时候,由于是由浏览器发送的两次请求,所以地址会发生变化
<3.2>可以重定向到任何位置的资源(服务内容、外部均可)
//因为第一次响应结果中包含了浏览器下次要跳转的路径,所以这个路径是可以任意位置资源。
<3.3>两次请求,不能在多个资源使用request共享数据
//因为浏览器发送了两次请求,是两个不同的request对象,就无法通过request对象进行共享数据

(4) 路径问题

<1> 何时加虚拟路径
<1.1> 浏览器使用:需要加虚拟目录(项目访问路径)
//对于重定向来说,路径最终是由浏览器来发送请求(浏览器要通过response中路径去寻找重定向后的资源),就需要添加虚拟目录。
//超链接、表单从浏览器发送,需要加
<1.2> 服务端使用:不需要加虚拟目录
//对于转发来说,因为是在服务端进行的(服务器通过该代码中路径找到转发目的地的资源),所以不需要加虚拟目录
<2> 动态获取虚拟目录
String contextPath = request.getContextPath();
response.sendRedirect(contextPath+"/resp2");

(5) Response响应字符数据

要想将字符数据写回到浏览器,我们需要三个步骤:
<1> 设置响应的数据格式及数据的编码: response.setContentType("text/html或text;charset=utf-8");
//告诉浏览器返回的数据类型是HTML类型数据,这样浏览器才会解析HTML标签
//TOMCAT在获取流的时候采用的编码是ISO-8859-1,若输入中文必须修改编码方式
<2> 通过Response对象获取字符输出流: PrintWriter writer = resp.getWriter();
<3> 通过字符输出流写数据: writer.write("<h1>你好,世界!</h1>");
//注意:一次请求响应结束后,response对象就会被销毁掉,所以不要手动关闭流。

(6) Response响应字节数据

<1> 要想将字节数据写回到浏览器,我们需要两个步骤:
<1.1> 通过Response对象获取字节输出流:ServletOutputStream outputStream = resp.getOutputStream();
<1.2> 通过字节输出流写数据: outputStream.write(字节数据);
<2> 代码实现

//1. 读取文件
FileInputStream fis = new FileInputStream("d://a.jpg");
//2. 获取response字节输出流
ServletOutputStream os = response.getOutputStream();
//3. 完成流的copy
byte[] buff = new byte[1024];
int len = 0;
while ((len = fis.read(buff))!= -1){
    os.write(buff,0,len);
}
fis.close();

<3> 优化后的代码
<3.1> pom.xml添加依赖

<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.6</version>
</dependency>

<3.2> 调用工具类方法

//1. 读取文件
FileInputStream fis = new FileInputStream("d://a.jpg");
//2. 获取response字节输出流
ServletOutputStream os = response.getOutputStream();
//3. 完成流的copy
IOUtils.copy(fis,os);
fis.close();
posted @ 2023-03-17 16:03  10kcheung  阅读(71)  评论(0)    收藏  举报