百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术文章 > 正文

HttpServletResponse详情

zhezhongyun 2025-01-02 20:29 111 浏览

HttpServletResponse

第一章 HTTP响应详解

前面的文章我们学习了HTTP请求协议及HttpServletRequest对象,今天我们来学习HTTP协议中的另一部分:HTTP响应协议及HttpServletResponse对象。

1、HTTP响应报文

HTTP是基于请求和响应的协议,一次请求对应一次响应。请求和响应的数据格式都遵从HTTP的超文本传输协议。与HTTP的请求一样,HTTP响应的数据也分为3部分:响应行响应头响应体 这3部分组成。请求是通过浏览器将数据传送到服务器,而响应是将服务器处理的结果回送到浏览器。

2、使用抓包工具查看响应数据

创建一个web项目,在web项目的web文件夹下创建一个hello.html页面。将下面的代码复制到hello.html页面中,启动项目,通过:url:http://localhost:8080/hello.html访问这个页面。使用chrome工具抓包。

【示例】hello.html静态页面

xml复制代码<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body> 
    <h2>get请求</h2>
    <form action="/getServlet" method="get">
        用户名:<input type="text" name="username" value="suoge" /> <br/>
        密码:<input type="text" name="password" value="1234" /> <br/>
        <input type="submit" value="get提交" />
    </form>
     <h2>post请求</h2>
    <form action="/postServlet" method="post">
        用户名:<input type="text" name="username" value="suoge" /> <br/>
        密码:<input type="text" name="password" value="1234" /> <br/>
        <input type="submit" value="post提交" />
    </form>
</body>
</html>

分别创建GetServlet和PostServlet,代码如下:

GetServlet的代码如下:

scala复制代码@WebServlet("/getServlet")
public class GetServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //给浏览器响应数据
        response.getWriter().print("hello response");
    }
}

PostServlet的代码如下:

scala复制代码@WebServlet("/postServlet")
public class PostServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //给浏览器响应数据
        response.getWriter().print("hello response");
    }
}

抓取的响应报文如下图所示:

说明:

1)由于浏览器的原因,浏览器会把请求行和响应行信息放在了一起;

2)get和post请求的响应没有区别;

【响应行】

响应行格式:协议/版本 状态码

如:HTTP/1.1 200 ;

常见状态码:

状态码

状态码描述

说明

200

OK

请求已成功,请求所希望的响应头或数据体将随此响应返回。出现此状态码是表示正常状态。

302

Move temporarily

重定向,请求的资源临时从不同的 地址响应请求。

304

Not Modified

浏览器缓存中读取数据,不从服务器重新获取数据。例如,用户第一次从浏览器访问服务器端图片资源,以后在访问该图片资源的时候就不会再从服务器上加载而直接到浏览器缓存中加载,这样效率更高。

404

Not Found

请求资源不存在。通常是用户路径编写错误,也可能是服务器资源已删除。

403

Forbidden

服务器已经理解请求,但是拒绝执行它

405

Method Not Allowed

请求行中指定的请求方法不能被用于请求相应的资源

500

Internal Server Error

服务器内部错误。通常程序抛异常

【响应头】

响应头也是用的键值对key:value,服务器基于响应头通知浏览器的行为。

常见的响应头

响应头Key

响应头value

location

指定响应的路径,需要与状态码302配合使用,完成重定向

content-Type

响应正文的类型(MIME类型,属于服务器里面的一种类型,例如文件在window系统有自己的类型,.txt .doc .jpg。文件在服务器中也有自己的类型),同时还可以解决乱码问题。例如:text/html;charset=UTF-8

content-disposition

通过浏览器以附件形式解析正文,例如:attachment;filename=xx.zip

refresh

页面刷新,例如:3;url=www.itcast.cn //三秒刷新页面到www.itcast.cn

说明:

MimeType:标识数据类型

bash复制代码最早的HTTP协议中,并没有附加的数据类型信息,所有传送的数据都被客户程序解释为超文本标记语言HTML 文档,而为了支持多媒体数据类型,HTTP协议中就使用了附加在文档之前的MIME数据类型信息来标识数据类型。
    MIME意为多功能Internet邮件扩展,它设计的最初目的是为了在发送电子邮件时附加多媒体数据,让邮件客户程序能根据其类型进行处理。然而当它被HTTP协议支持之后,它的意义就更为显著了。它使得HTTP传输的不仅是普通的文本,而变得丰富多彩。
    每个MIME类型由两部分组成,前面是数据的大类别,例如声音audio、图象image等,后面定义具体的种类。
常见的MIME类型(通用型):
                windows    tomcat
超文本标记语言文本 .html      text/html ***
xml文档 .xml              text/xml
XHTML文档 .xhtml          application/xhtml+xml
普通文本 .txt               text/plain ***
PDF文档 .pdf              application/pdf
Microsoft Word文件 .word  application/msword
PNG图像 .png              image/png ***
GIF图形 .gif              image/gif
JPEG图形 .jpeg,.jpg       image/jpeg
......

【响应体】

响应体,就是服务器发送给浏览器的数据。当前浏览器向服务器请求的资源是hello.html,所以服务器给浏览器响应的数据是一个html页面。

请求资源路径:

响应结果:

如果请求是servlet,那么浏览器的响应体接收到的是servlet响应的数据:

总结:

响应行:协议版本号 状态码 200(一切正常) 404(找不到资源路径) 500(服务器报异常) 302(和location一起使用,实现重定向) 304(从浏览器缓存中读取数据) 405(服务器的servlet没有重写doGet和doPost方法)

响应头:

location 指定响应的路径

content-type:告诉浏览器文件格式,告诉浏览器不要解析html文件,解决中文乱码问题

refresh 定时刷新

content-disposition 以附件形式展示图片等资源

响应体:

服务器处理的结果响应到浏览器中

第二章 HttpServletResponse对象

遇到问题 : 服务器接受客户端的请求之后,处理请求之后,服务器如何将对应的数据响应给客户端呢?

解决方案 : 一切皆对象,Servlet程序接受客户端请求之后,通过HttpServletResponse对象来完成向客户端的响应。

通过该对象,将数据返回给客户端。

1、HttpServletResponse对象作用

HttpServletResponse对象代表服务器响应,tomcat创建HttpServletResponse对象,并将该对象作为参数传递给servlet的service方法。

这个对象的作用

设置响应行、头、体

下面,就这几方面对HttpServletResponse对象的常用API进行详细讲解。

2、HttpServletResponse对象常用API

2.1【响应行】

响应行:协议/版本 如:HTTP/1.1 200 。这里边的信息,我们通常只会用到状态码,操作状态码的方法setStatus(int code);

方法

说明

setStatus(int code)

向浏览器发送状态码

【常用状态码】

对应的状态码响应状态码常量

说明

200

响应成功

404

资源路径错误或资源被删除

500

服务器内部错误

302

重定向

2.2 【响应头】

方法

说明

setHeader(String name,String value)

设置响应头信息

【常见响应头】

响应头Key

响应头value

refresh

页面刷新,例如:3;url=www.itcast.cn //三秒刷新页面到www.itcast.cn

content-type

设置响应数据的类型(MIME类型)编码格式 例如:text/html;charset=UTF-8

location

指定响应的路径,需要与状态码302配合使用,完成重定向。

content-disposition

通过浏览器以附件形式解析正文,例如:attachment;filename=xx.zip。

2.2.1.常见响应头

【练习】响应头---定时刷新

需求:1. 访问到Servlet类3秒后跳转到百度;

scala复制代码@WebServlet("/refreshServlet")
public class RefreshServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //实现refresh关键字跳转功能 响应头API
        //方法具有2个参数  关键字  跳转地址
        response.setHeader("refresh","3;url=http://www.baidu.com");
    }
}

浏览器输入地址:http://localhost:8080/refreshServlet

注意:3秒以后自动跳转到百度主页,前提你要联网啊。

【练习】content-type 设置响应数据的类型。告诉浏览器不要解析html格式数据。

scala复制代码@WebServlet("/contentServlet")
public class ContentServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //告诉浏览器不要解析html格式数据
        //每次写这些方法,代码太多,而且API还经常使用  setContentType(text/plain)
//        response.setHeader("content-type","text/plain");
        response.setContentType("text/plain");
        response.getWriter().print("<html><body><h1>itcast</h1></body></html>");
    }
}

说明:text/plain的意思是将文件设置为纯文本的形式,浏览器在获取到这种文件时并不会对其进行处理。

抓包查看浏览器信息:

效果图:

2.2.2.处理响应乱码

2.2.2.1乱码产生的原因

服务器如果需要响应给浏览器中文数据,tomcat使用getWriter()输出字符时,对于中文需要进行编码处理,而tomcat8 默认编码是ISO-8859-1,该码表是不支持中文编码的。所以响应给浏览器,出现乱码。

代码如下:

css复制代码 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.getWriter().print("<html><body><h1>程序员</h1></body></html>");
    }

2.2.2.2响应乱码解决方案

因为HttpServletResponse实现类是由tomcat服务器提供的。所以服务器在向浏览器输出数据之前,对于中文要采用支持中文的编码进行编码,通过response.setContentType("text/html;charset=utf-8"); :

  1. 设置响应的数据类型(text/html);
  2. 设置响应的数据编码(utf-8);

2.2.2.3处理响应乱码的API

方法

说明

response.setHeader("content-type","text/html;charset=utf-8");

设置响应头

response.setContentType("text/html;charset=utf-8");

简写方式

【注意事项】

  1. 开发中通常使用response.setContentType("text/html;charset=utf-8");来处理响应乱码;
  2. 处理响应乱码必须书写在响应数据之前才起作用;

【练习】content-type 设置响应数据的类型和编码

scala复制代码@WebServlet("/encodeServlet")
public class EncodeServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //设置响应头:content-type

        //乱码产生的原因:编解码不一致
        //tomcat的编码是:ISO-8859-1

        //通过设置响应头
        //1.设置响应的数据格式;
        //2.设置响应数据的编码格式;
//         response.setHeader("content-type","text/html;charset=utf-8");
        //简化API
        response.setContentType("text/html;charset=utf-8");
        response.getWriter().print("程序员");
    }
}

效果图:如果没有进行响应乱码的处理,则浏览器显示的是乱码.处理之后的效果如下所示:

2.2.3.重定向(掌握)

【重定向原理分析】

【重定向API】: 重定向可以去一个servlet,也可以去一个html静态资源.

方法

说明

response.setStatus(302); response.setHeader("location", "/otherServlet");

通过设置响应状态码和响应头实现重定向

response.sendRedirect("/otherServlet");

重定向的简写方式

【注意事项】

  1. 开发中通常使用response.sendRedirect("/otherServlet");来实现重定向。

【练习】通过设置响应头location和响应行的状态码302完成重定向。

方法:

arduino复制代码     //方式一:
     //location+302 共同完成重定向
     response.setHeader("location", "url");
    //响应行
     response.setStatus(302);
    //方式二:
    //简化的API
     response.sendRedirect("url");

班长的servlet,【MonitorServlet.java】:

scala复制代码@WebServlet("/monitorServlet")
public class MonitorServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //使用重定向
//        response.setHeader("location","/suogeServlet");
//        response.setStatus(302);
        response.sendRedirect("/suogeServlet");
    }
}

【SuogeServlet.java】

scala复制代码@WebServlet("/suogeServlet")
public class SuogeServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //处理响应乱码
        response.setContentType("text/html;charset=utf-8");
        response.getWriter().print("一起学习Java");
    }
}

浏览器地址栏输入访问网站效果:

http://localhost:8080/monitorServlet

回车之后,浏览器地址栏变为:

2.3、转发和重定向的区别

完成重定向操作之后,同学们心里有一个疑问:之前学习的转发和现在的重定向都可以完成跳转,都可以跳转到一个servlet,也可以跳转到一个html静态资源,功能相同。那么他们之间有什么区别呢?

【转发和重定向区别】

转发和重定向的另一种解释:

2.3.1、转发和重定向的区别

区别点

转发

重定向

实现原理

服务器内部

浏览器执行

请求次数

一次

两次

浏览器地址栏地址

不变化

变为第二次请求的地址

能否共享request域

能够共享

不能共享

作用

共享request域对象

完成跳转

2.3.2、转发和重定向怎么选择

  1. 如果需要共享request域,必须使用转发;
  2. 如果需要将浏览器地址栏地址变为第二次请求的地址,必须使用重定向;


作者:also_lucky
链接:https://juejin.cn/post/7240088790424256569

相关推荐

Python入门学习记录之一:变量_python怎么用变量

写这个,主要是对自己学习python知识的一个总结,也是加深自己的印象。变量(英文:variable),也叫标识符。在python中,变量的命名规则有以下三点:>变量名只能包含字母、数字和下划线...

python变量命名规则——来自小白的总结

python是一个动态编译类编程语言,所以程序在运行前不需要如C语言的先行编译动作,因此也只有在程序运行过程中才能发现程序的问题。基于此,python的变量就有一定的命名规范。python作为当前热门...

Python入门学习教程:第 2 章 变量与数据类型

2.1什么是变量?在编程中,变量就像一个存放数据的容器,它可以存储各种信息,并且这些信息可以被读取和修改。想象一下,变量就如同我们生活中的盒子,你可以把东西放进去,也可以随时拿出来看看,甚至可以换成...

绘制学术论文中的“三线表”具体指导

在科研过程中,大家用到最多的可能就是“三线表”。“三线表”,一般主要由三条横线构成,当然在变量名栏里也可以拆分单元格,出现更多的线。更重要的是,“三线表”也是一种数据记录规范,以“三线表”形式记录的数...

Python基础语法知识--变量和数据类型

学习Python中的变量和数据类型至关重要,因为它们构成了Python编程的基石。以下是帮助您了解Python中的变量和数据类型的分步指南:1.变量:变量在Python中用于存储数据值。它们充...

一文搞懂 Python 中的所有标点符号

反引号`无任何作用。传说Python3中它被移除是因为和单引号字符'太相似。波浪号~(按位取反符号)~被称为取反或补码运算符。它放在我们想要取反的对象前面。如果放在一个整数n...

Python变量类型和运算符_python中变量的含义

别再被小名词坑哭了:Python新手常犯的那些隐蔽错误,我用同事的真实bug拆给你看我记得有一次和同事张姐一起追查一个看似随机崩溃的脚本,最后发现罪魁祸首竟然是她把变量命名成了list。说实话...

从零开始:深入剖析 Spring Boot3 中配置文件的加载顺序

在当今的互联网软件开发领域,SpringBoot无疑是最为热门和广泛应用的框架之一。它以其强大的功能、便捷的开发体验,极大地提升了开发效率,成为众多开发者构建Web应用程序的首选。而在Spr...

Python中下划线 ‘_’ 的用法,你知道几种

Python中下划线()是一个有特殊含义和用途的符号,它可以用来表示以下几种情况:1在解释器中,下划线(_)表示上一个表达式的值,可以用来进行快速计算或测试。例如:>>>2+...

解锁Shell编程:变量_shell $变量

引言:开启Shell编程大门Shell作为用户与Linux内核之间的桥梁,为我们提供了强大的命令行交互方式。它不仅能执行简单的文件操作、进程管理,还能通过编写脚本实现复杂的自动化任务。无论是...

一文学会Python的变量命名规则!_python的变量命名有哪些要求

目录1.变量的命名原则3.内置函数尽量不要做变量4.删除变量和垃圾回收机制5.结语1.变量的命名原则①由英文字母、_(下划线)、或中文开头②变量名称只能由英文字母、数字、下画线或中文字所组成。③英文字...

更可靠的Rust-语法篇-区分语句/表达式,略览if/loop/while/for

src/main.rs://函数定义fnadd(a:i32,b:i32)->i32{a+b//末尾表达式}fnmain(){leta:i3...

C++第五课:变量的命名规则_c++中变量的命名规则

变量的命名不是想怎么起就怎么起的,而是有一套固定的规则的。具体规则:1.名字要合法:变量名必须是由字母、数字或下划线组成。例如:a,a1,a_1。2.开头不能是数字。例如:可以a1,但不能起1a。3....

Rust编程-核心篇-不安全编程_rust安全性

Unsafe的必要性Rust的所有权系统和类型系统为我们提供了强大的安全保障,但在某些情况下,我们需要突破这些限制来:与C代码交互实现底层系统编程优化性能关键代码实现某些编译器无法验证的安全操作Rus...

探秘 Python 内存管理:背后的神奇机制

在编程的世界里,内存管理就如同幕后的精密操控者,确保程序的高效运行。Python作为一种广泛使用的编程语言,其内存管理机制既巧妙又复杂,为开发者们提供了便利的同时,也展现了强大的底层控制能力。一、P...