【Servlet篇】Response对象详细解读

news2024/11/27 16:44:11

文章目录

  • 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 {
    @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);
    }
}

第二步:创建 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);
    }
}

第三步:在 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 {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html;charset=utf-8");
        PrintWriter writer = response.getWriter();
        writer.write("helloWorld");
    }

    @Override
    protected 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 {
    @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. 完成流的复制
        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);
    }
}

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 {
    @Override
    protected 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();

    }

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

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

下期见。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/372881.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Pyinstaller 打包EXE(七) 百篇文章学PyQT

本文章是百篇文章学PyQT6的第七篇&#xff0c;本文讲述如何使用Pyinstaller打包UI界面和代码&#xff0c;将程序打包成EXE来更为方便的进行部署&#xff0c;在写博客和学习的过程中会遇到很多问题&#xff0c;例如&#xff1a;PyQT6在网上很多博客都是PyQT5、或者PyQT4大部分都…

Could not extract response: no suitable HttpMessageConverter

版本&#xff1a;spring-cloud-openfeign-core-2.1.1.RELEASE.jar&#xff0c;spring-webmvc-5.1.14.RELEASE.jar&#xff0c;jetty-server-9.4.41.v20210516.jar&#xff0c;tomcat-embed-core-9.0.48.jar 问题背景 生产服务请求下游服务时偶发抛出下面的异常&#xff0c;下…

git入门

目录 1. git简介 1.1 git是什么 1.2 git与svn的区别 2. github 2.1 创建仓库 2.2 删除仓库 2.3 新建文件及文件夹 3. git的基本操作 3.1 配置账户及邮箱 3.2 git文件状态与工作区域 3.3 常用命令 3.4 克隆&#xff08;clone&#xff09; 3.5 查看git仓库的状态 3.…

[音视频] BMP 图片格式分析

BMP 格式是什么 BMP&#xff08;Bitmap&#xff09;是一种常见的无损位图图像文件格式&#xff0c;是Windows操作系统中最早使用的图像格式之一&#xff0c;也是目前很多应用程序所使用的标准图像格式之一。 整体结构图&#xff0c;如下图所示 格式 BMP文件格式有多个版本&a…

QT中级(5)多线程读取一个文件,并在另一个文件夹中合成这个文件(1)

1 先实现一个简单程序 1.1 功能 用户可以输入一个源文件的路径和目标路径点击开始&#xff0c;程序启动读取和合成合成进度可见、合成步骤可见 1.2 思路 一个线程顺序读取文件&#xff0c;达到设定的缓存块就发给另一个合成线程&#xff0c;主线程用来进行数据传递、显示进…

电子技术——A类输出阶

电子技术——A类输出阶 因为射极跟随器具有较低的输出阻抗&#xff0c;射极跟随器是A类输出阶的典型代表。我们之前已经学习过射极跟随器的小信号模型&#xff0c;本节我们讨论其大信号模型。 传输特性 下图展示了一个射极跟随器的原理图&#xff1a; 其中 Q1Q_1Q1​ 为射极…

并发编程-学习总结(下)

目录 1、Future 1.1、Callable和Runnable的不同 1.2、Future的主要功能 1.3、常用方法 1.4、Future使用注意事项 1.5、CompletableFuture(旅游平台问题) 1.5.1、需求 1.5.2、解决方案1&#xff1a;串行 1.5.3、解决方案2&#xff1a;线程池 1.5.4、解决方案3&#xf…

Prometheus本地存储和VictoriaMetrics远端存储

文章目录Prometheus本地存储简介blockWAL本地存储配置参数VictoriaMetrics简介单机版部署使用安装VictoriaMetrics配置Prometheus使用Victoriametrics配置Grafana以Victoriametrics作为数据源集群版部署使用部署vmstorage部署vmselect部署vminsert配置Prometheus使用vminsert配…

LearnOpenGL-入门-你好,三角形

本人刚学OpenGL不久且自学&#xff0c;文中定有代码、术语等错误&#xff0c;欢迎指正 我写的项目地址&#xff1a;https://github.com/liujianjie/LearnOpenGLProject LearnOpenGL中文官网&#xff1a;https://learnopengl-cn.github.io/ 文章目录图形渲染管线基本介绍着色器…

文献计量三大定律之一---洛特卡定律及普赖斯定律

科学生产率是洛特卡定律的基础&#xff0c;科学生产率”(Scientific Productivity)&#xff09;是指科学家&#xff08;科研人员&#xff09;在科学上所表现出的能力和工作效率&#xff0c;通常用其生产的科学文献的数量来衡量。 1926年&#xff0c;洛特卡在一篇论文中提出了科…

Windows作为操作系统的典型特征和主要功能

我是荔园微风&#xff0c;作为一名在IT界整整25年的老兵&#xff0c;今天我们来重新审视一下Windows这个我们熟悉的不能再熟悉的系统。我们每天都在用Windows操作系统&#xff0c;但是其实我们每天直接在打交道的并不是Windows操作系统的内核&#xff0c;而是Windows操作系统的…

Docker部署Springboot项目(含MySQL+Redis)

使用Docker部署之前写的一个博客项目&#xff0c;主要用到了MySQL和Redis&#xff0c;Redis作网站访问量统计。下面会对具体的部署方式作详细讲解 一、服务器安装Docker 1、删除docker旧版本 sudo yum remove docker \docker-client \docker-client-latest \docker-common \…

(三十五)大白话MySQL一个事务多次查询一条数据读到的都是不同的值,这就是不可重复读?

上一讲我们说完了多个事务并发执行时候&#xff0c;对MySQL的缓存页里的同一行数据同时进行更新或者查询的时候&#xff0c;可能发生的脏写和脏读的问题 我们也都理解了&#xff0c;之所以会发生脏写和脏读&#xff0c;最关键的&#xff0c;其实是因为你一个事务写或者查的是人…

黑盒测试的常用方法

这里我们先设置一个示例,后面的文章中会根据示例来进行讲解 假设有一个程序是判断一个整形数字是否属于1-100 目录 1.等价类法 2.边界值法 3.判定表法 4.场景设计法 5.错误猜测法 6.正交法 1.等价类法 概念:系统性的确定要输入的测试条件的方法可以看出概念非常抽象,那…

命令执行漏洞 | iwebsec

文章目录1 靶场环境2 命令执行漏洞介绍3 靶场练习01-命令执行漏洞02-命令执行漏洞空格绕过03-命令执行漏洞关键命令绕过04-命令执行漏洞通配符绕过05-命令执行漏洞base64编码绕过4 命令执行漏洞危害01-读写系统文件02-执行系统命令03-种植恶意木马04-反弹shellpython反弹shellp…

Android 基础知识4-3.4 ImageView(图像视图)详解

一、ImageView简介 ImageView是Android开发中最常用的组件之一&#xff0c;主要用于显示图片&#xff0c;但是它不只是能显示图片&#xff0c;任何Drawable对象都可以使用它来显示。 二、ImageView 的继承关系 ImageView的继承关系 如下&#xff1a; java.lang.Object 《-- …

生成式语言大模型压缩技术思考——以ChatGPT为例

ChatGPT引领了生成式语言大模型的应用与技术热潮&#xff0c;首先简单回顾ChatGPT应用范式&#xff1a;将其应用于指定的下游任务时&#xff08;如知识问答、翻译、编码&#xff09;&#xff0c;ChatGPT需要经历三个阶段的训练&#xff08;增强人类语境的猜想&#xff09;&…

基于nodejs+vue的平面设计课程管理系统vscode

后台由管理员&#xff0c;教师和学生三个角色&#xff0c;其主要功能包括首页&#xff0c;个人中心&#xff0c;学生管理&#xff0c;教师管理&#xff0c;课程类型管理&#xff0c;课程学习管理&#xff0c;试题讲解管理&#xff0c;作业信息管理&#xff0c;作业提交管理&…

Flutter3引用原生播放器-IOS(Swift)篇

前言由于Flutter项目中需要使用到播放器功能&#xff0c;因此对flutter中各种播放器解决方案进行了一番研究和比对&#xff0c;最后决定还是自己通过Plugin的方法去引用原生播放器符合自己的需求&#xff0c;本篇文章会对各种解决方案做一个简单的比较&#xff0c;以及讲解一下…

STM32—DMA

什么是DMA&#xff1f; DMA(Direct Memory Access&#xff0c;直接存储器访问) 提供在外设与内存、存储器和存储器、外设与外设之间的高速数据传输使用。它允许不同速度的硬件装置来沟通&#xff0c;而不需要依赖于CPU&#xff0c;在这个时间中&#xff0c;CPU对于内存的工作来…