Response 介绍及应用。

目录

1、继承体系

▶ 体系图

▶ Response 响应数据 

2、 Respones 请求重定向

▶ 重定向的实现方式

▶ 路径问题

3、Response响应字符数据

▶ 响应字符数据

▶ 案例演示

4、 Response响应字节数据

▶ 响应字节数据

▶ 简化代码


1、继承体系

▶ 体系图

Response : 使用response对象来设置响应数据

▶ Response 响应数据 

HTTP响应数据总共分为三部分内容,分别是响应行、响应头、响应体

▷ 响应行

  设置响应状态码:

void setStatus(int sc);

▷ 响应头

 设置响应头键值对:

void setHeader(String name,String value);

▷ 响应体

 对于响应体,是通过字符、字节输出流的方式往浏览器写,

 ● 获取字符输出流:

PrintWriter getWriter();

 ● 获取字节输出流:

ServletOutputStream getOutputStream();

2、 Respones 请求重定向

 ▷ Response重定向(redirect) : 一种资源跳转方式。

○ 浏览器发送请求给服务器,服务器中对应的资源A接收到请求

○ 资源A现在无法处理该请求,就会给浏览器响应一个302的状态码+location的一个访问资源B的路径

○ 浏览器接收到响应状态码为302就会重新发送请求到location对应的访问地址去访问资源B

○ 资源B接收到请求后进行处理并最终给浏览器响应结果,这整个过程就叫重定向

▶ 重定向的实现方式

resp.setStatus(302);
resp.setHeader("location","资源B的访问路径");

▷ 需求

▷ 实现

(1)创建ResponseDemo1类

@WebServlet("/resp1")
public class ResponseDemo1 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("resp1....");
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doGet(request, response);
    }
}

(2)创建ResponseDemo2类

@WebServlet("/resp2")
public class ResponseDemo2 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("resp2....");
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doGet(request, response);
    }
}

(3)在ResponseDemo1的doGet方法中给前端响应数据

@WebServlet("/resp1")
public class ResponseDemo1 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("resp1....");
        //重定向
        //1.设置响应状态码 302
        response.setStatus(302);
        //2. 设置响应头 Location
        response.setHeader("Location","/request-demo/resp2");
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doGet(request, response);
    }
}

(4)启动测试

 访问`http://localhost:8080/request-demo/resp1`,就可以在控制台看到如下内容:

 说明`/resp1`和`/resp2`都被访问到了。到这重定向就已经完成了。

▷ 简化

 虽然功能已经实现,但是从设置重定向的两行代码来看,会发现除了重定向的地址不一样,其他的内容都是一模一样,所以request对象给我们提供了简化的编写方式为:

resposne.sendRedirect("/request-demo/resp2")

所以第3步中的代码就可以简化为:

@WebServlet("/resp1")
public class ResponseDemo1 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("resp1....");
        //重定向
        resposne.sendRedirect("/request-demo/resp2");
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doGet(request, response);
    }
}

▷ 重定向的特点

● 浏览器地址栏路径发送变化。当进行重定向访问的时候,由于是由浏览器发送的两次请求,所以地址会发生变化:

 

● 可以重定向到任何位置的资源(服务内容、外部均可)。因为第一次响应结果中包含了浏览器下次要跳转的路径,所以这个路径是可以任意位置资源。

● 两次请求,不能在多个资源使用 request共享数据。因为浏览器发送了两次请求,是两个不同的 request对象,就无法通过request对象进行共享数据

▷ 请求重定向和请求转发的对比:

▶ 路径问题

▷ 问题1:请求转发的时候路径上没有加`/request-demo`而重定向加了,那么到底什么时候需要加,什么时候不需要加呢?

 判断规则:

 ● 浏览器使用: 需要加虚拟目录(项目访问路径)

  ○ 对于转发来说,因为是在服务端进行的,所以不需要加虚拟目录
 ● 服务端使用: 不需要加虚拟目录

  ○ 对于重定向来说,路径最终是由浏览器来发送请求,就需要添加虚拟目录。

▷ 常见的:  

 ● `<a href='路劲'>`

   ○ 超链接,从浏览器发送,需要加
 ● `<form action='路径'>`

   ○ 表单,从浏览器发送,需要加
 ● req.getRequestDispatcher("路径")

   ○ 转发,是从服务器内部跳转,不需要加
 ● resp.sendRedirect("路径")

   ○ 重定向,是由浏览器进行跳转,需要加。

▷ 问题2:在重定向的代码中,`/request-demo`是固定编码的,如果后期通过Tomcat插件配置了项目的访问路径,那么所有需要重定向的地方都需要重新修改,该如何优化?

 我们可以在代码中动态去获取项目访问的虚拟目录,具体如何获取,我们可以借助前一篇文章的request对象中的getContextPath()方法,修改后的代码如下:

@WebServlet("/resp1")
public class ResponseDemo1 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("resp1....");

        //简化方式完成重定向
        //动态获取虚拟目录
        String contextPath = request.getContextPath();
        response.sendRedirect(contextPath+"/resp2");
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doGet(request, response);
    }
}

重新启动访问测试,功能依然能够实现,此时就可以动态获取项目访问的虚拟路径,从而降低代码的耦合度。

3、Response响应字符数据

▶ 响应字符数据

要想将字符数据写回到浏览器,我们需要两个步骤:

● 通过Response对象获取字符输出流:

PrintWriter writer = resp.getWriter();

●  通过字符输出流写数据:

writer.write("aaa");

▶ 案例演示

1. 返回一个简单的字符串`aaa`

@WebServlet("/resp3")
public class ResponseDemo3 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html;charset=utf-8");
        //1. 获取字符输出流
        PrintWriter writer = response.getWriter();
         writer.write("aaa");
    }
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doGet(request, response);
    }
}

2. 返回一串html字符串,并且能被浏览器解析

PrintWriter writer = response.getWriter();

//content-type,告诉浏览器返回的数据类型是HTML类型数据,这样浏览器才会解析HTML标签
response.setHeader("content-type","text/html");
writer.write("<h1>aaa</h1>");

  

注意 : 一次请求响应结束后,response对象就会被销毁掉,所以不要手动关闭流。

3. 返回一个中文的字符串`你好`,需要注意设置响应数据的编码为`utf-8`

//设置响应的数据格式及数据的编码
response.setContentType("text/html;charset=utf-8");
writer.write("你好");

4、 Response响应字节数据

▶ 响应字节数据

要想将字节数据写回到浏览器,我们需要两个步骤:

● 通过Response对象获取字节输出流:

ServletOutputStream outputStream = resp.getOutputStream();

● 通过字节输出流写数据:

outputStream.write(字节数据);

▶ 案例演示

1. 返回一个图片文件到浏览器:图片路径根据自己情况而定

@WebServlet("/resp4")
public class ResponseDemo4 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //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();
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doGet(request, response);
    }
}

▶ 简化代码

 对于流的copy的代码还是比较复杂的,所以我们可以使用别人提供好的方法来简化代码的开发,具体的步骤是:

(1) pom.xml 添加依赖

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

(2) 调用工具类方法

//fis:输入流
//os:输出流
IOUtils.copy(fis,os);

▷ 优化后的代码

@WebServlet("/resp4")
public class ResponseDemo4 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        //1. 读取文件
        FileInputStream fis = new FileInputStream("d://a.jpg");

        //2. 获取response字节输出流
        ServletOutputStream os = response.getOutputStream();

        //3. 完成流的copy
        IOUtils.copy(fis,os);

        fis.close();
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doGet(request, response);
    }
}

  • 108
    点赞
  • 106
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小黎的培培笔录

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值