【Servlet篇】Response对象详细解读

news/2024/10/30 6:41:19/

文章目录

  • Response 继承体系
  • Response 设置响应数据
    • 设置响应行数据
    • 设置响应头数据
    • 设置响应体数据
    • Response 重定向
  • Response 响应字符数据
  • Response 响应字节数据

Response 继承体系

前面说到,我们使用 Request 对象来获取请求数据,使用 Response 对象来设置响应数据。如图:

其实 Response 的继承体系和 Request 有很多相似的地方,如图:

image-20230210224413110

Java 语言提供了响应对象根接口和封装了 HTTP 协议的响应对象接口,两者都是接口,并且两者属于继承关系。

Servlet 类中的 services() 方法,doGet() 方法,doPost() 等方法,都是由 Web 服务器 TomCat 来调用的,所以 TomCat 提供了方法参数接口的具体实现类,并完成了对象的创建,这个实现类就是 ResponseFacade 类。

学习 Response 对象,主要从以下几个方面入手:

  • Response 设置响应数据
  • Response 完成重定向
  • Response 响应字符数据
  • Response 响应字节数据

Response 设置响应数据

HTTP 响应数据总共分为三部分内容,分别是响应行,响应头和响应体。通过对应的 API 就可以简单的实现设置响应数据的功能。

设置响应行数据

对于响应行的数据的设置,主要是设置响应状态码,如下:

image-20230210225730623

void setStatus(int sc);

设置响应头数据

响应头的数据格式为 key : value 。Response 提供了方法设置响应头的键值对数据,如下:

image-20230210225923882

void setHeader(String name,String value);

设置响应体数据

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

获取字符输出流:

PrintWriter getWriter();

获取字节输出流:

ServletOutputStream getOutputStream();

Response 重定向

Response 重定向也是一种资源的跳转方式,与请求转发不同的是,重定向时浏览器发送了两次请求,所以浏览器地址栏的路径会发生变化,并且我们可以重定向到任何位置的资源,不管是服务器内部的还是外部的。

image-20230210231908524

浏览器发送请求给服务器,服务器中对应的资源 a 接收到了请求,如果资源 a 无法处理该请求,就会响应给浏览器一个 302 状态码和一个访问资源 b 的路径 location 。

浏览器接收到状态码 302 以后就会重新发送请求到 location 对应的访问地址其访问资源 b。资源 b 接收到了请求以后进行处理步最终给浏览器返回响应结果,这一个过程就叫做重定向。

重定向的实现方式:

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

下面练习 Response 重定向。

  1. 创建一个 ResponseDemo1 类,接收 /res1的请求,在 doGet() 方法中打印 resp1…
  2. 创建一个 ResponseDemo2 类,接收 /res2 的请求,在 doGet() 方法中打印 resp2…
  3. 在 ResponseDemo1 的方法中实现重定向
  4. 测试

第一步:创建 ResponseDemo1 类

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

第二步:创建 ResponseDemo2 类

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

第三步:在 ResponseDemo1 类方法中实现重定向

//重定向
//1.设置响应状态码302
response.setStatus(302);
//2.设置响应头 location
response.setHeader("location","/servlet-project/resp2");

第四步:测试

启动服务器,访问 http://location:8080/servlet-project/resp1,此时控制台输出:

image-20230210233449932

这里 /resp1 和 /resp2 都被访问到了,表示重定向成功了。其实 Response 还提供了一种更加简便的方式来实现重定向,如下:

resposne.sendRedirect("/servlet-project/resp2")

Response 响应字符数据

服务器接收到浏览器发送的请求之后经过一系列的逻辑处理后就要发送响应给浏览器,而把数据写回浏览器是十分重要的一部分,我们一般使用输出流的方式将响应数据写回浏览器。

Response 对字符数据和字节数据的响应方式是不同的,要想将字符数据写到浏览器,需要完成下面两个步骤:

  1. 获取字符输出流
  2. 通过字符输出流写数据

下面练习将一个简单的字符串写到浏览器。

@WebServlet("/demo")
public class ServletDemo extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {response.setContentType("text/html;charset=utf-8");PrintWriter writer = response.getWriter();writer.write("helloWorld");}@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {this.doGet(request, response);}
}

下面练习将一个 html 字符串返回给浏览器,并且被浏览器解析。

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

注意:返回的中文字符数据时要把字符编码方式设置为 utf-8。在一次请求结束后,response 对象会被销毁,所以这里的流对象不需要手动释放。

Response 响应字节数据

要想将字节数据写到浏览器,只需要下面两个步骤:

  1. 获取字节输出流对象
  2. 通过字节输出流写数据

下面练习将一个图片文件写回到浏览器。

@WebServlet("/demo")
public class ResponseDemo extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//1. 用于读取文件FileInputStream fis = new FileInputStream("d://a.jpg");//2. 获取response字节输出流ServletOutputStream os = response.getOutputStream();//3. 完成流的复制byte[] buff = new byte[1024];int len = 0;while ((len = fis.read(buff))!= -1){os.write(buff,0,len);}fis.close();}@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {this.doGet(request, response);}
}

Java 的 IO 流操作是开发中比较常用的技术,但是如果每次都使用原生的 IO 流来操作会显得比较繁琐。我们可以使用 commons-io 来简化操作,commons-io 是一个工具包,用来帮助 IO 功能的开发,感兴趣的朋友可以去了解一下。

使用前我们要先往 pom.xml 配置文件中添加对应的依赖坐标。

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

此时,将图片返回给浏览器的代码可以优化为:

@WebServlet("/demo")
public class ServletDemo extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {FileInputStream fis  = new FileInputStream("C:\\Users\\24091\\Desktop\\46cfac1918ae3f7831e746684c0bd42.jpg");ServletOutputStream os = response.getOutputStream();IOUtils.copy(fis,os);fis.close();}@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {this.doGet(request, response);}
}

你问我青春还剩几年?我的回答是,趁现在,正当时。身边朋友都在问我怎样学好一门编程语言,怎样学好Java?怎样通过 Java 找到一份满意的工作?推荐学习此专栏:Java编程基础教程系列(零基础小白搬砖逆袭)

下期见。


http://www.ppmy.cn/news/28211.html

相关文章

HDMI协议介绍(四)--Video

目录 视频格式 RGB444 YUV444 YUV422 YUV420 Color Depth Video控制信号 Pixel Repetition HDMI支持多种视频格式和分辨率。以hdmi1.4和2.0协议来说&#xff0c;视频格式支持RGB444、YUV444、YUV422和YUV420&#xff0c;其中RGB444和YUV444一般都是要求支持的。 视频格式…

tun驱动之open

tun驱动对应的设备文件是&#xff1a;/dev/net/tun&#xff0c;其详细信息如下&#xff1a; crw-rw-rw- 1 root root 10, 200 2月 26 08:05 tun 主次设备号的定义如下&#xff1a; #define MISC_MAJOR 10 #define TUN_MINOR 200 由于tun驱动属于misc设备驱动&#xff0c;因此用…

Java 主流日志工具库

日志系统 java.util.logging (JUL) JDK1.4 开始&#xff0c;通过 java.util.logging 提供日志功能。虽然是官方自带的log lib&#xff0c;JUL的使用确不广泛。 JUL从JDK1.4 才开始加入(2002年)&#xff0c;当时各种第三方log lib已经被广泛使用了JUL早期存在性能问题&#x…

2023年三月份图形化三级打卡试题

活动时间 从2023年3月1日至3月21日&#xff0c;每天一道编程题。 本次打卡的规则如下&#xff1a; 小朋友每天利用10~15分钟做一道编程题&#xff0c;遇到问题就来群内讨论&#xff0c;我来给大家答疑。 小朋友做完题目后&#xff0c;截图到朋友圈打卡并把打卡的截图发到活动群…

【C++】类与对象理解和学习(下)

放在专栏【C知识总结】&#xff0c;会持续更新&#xff0c;期待支持&#x1f339;建议先看完【C】类与对象理解和学习&#xff08;上&#xff09;【C】类与对象理解和学习&#xff08;中&#xff09;本章知识点概括Ⅰ本章知识点概括Ⅱ初始化列表前言在上一篇文章中&#xff0c;…

【数据结构】二叉树的四种遍历方式——必做题

写在前面学完上一篇文章的二叉树的遍历之后&#xff0c;来尝试下面的习题吧开始做题144. 二叉树的前序遍历 - 力扣&#xff08;LeetCode&#xff09;94. 二叉树的中序遍历 - 力扣&#xff08;LeetCode&#xff09;145. 二叉树的后序遍历 - 力扣&#xff08;LeetCode&#xff09…

C#:Krypton控件使用方法详解(第九讲) ——kryptonRadioButton

今天介绍的Krypton控件中的kryptonRadioButton&#xff0c;这是一个单选按钮控件。下面开始介绍这个控件的属性&#xff1a;首先介绍的是外观属性&#xff0c;如下图所示&#xff1a;Cheacked属性&#xff1a;表示设置kryptonRadioButton控件的初始选中状态是什么样的&#xff…

Java-重排序,happens-before 和 as-if-serial 语义

目录1. 如何解决重排序带来的问题2. happens-before1. 如何解决重排序带来的问题 对于编译器&#xff0c;JMM 的编译器重排序规则会禁止特定类型的编译器重排序。对于处理器重排序&#xff0c;JMM 的处理器重排序规则会要求编译器在生成指令序列时&#xff0c;插入特定类型的内…