Http请求响应——响应

上文(Http请求响应------请求Http概述 Http协议(HyperText Transfer Protocol,超文本传输协 - 掘金)提到Http中的请求,Http协议采用的是"请求-响应"模型本文讲解Http中的响应

Http响应

响应数据格式

首先先看一个简单的请求,请求www.baidu.com 然后百度的服务器会给我们响应什么数据:

这是请求www.baidu.com 时,百度的服务器接收到浏览器请求之后给浏览器响应回来的响应数据,这样一个响应数据和请求数据一样,也是由三个部分组成:

响应行

响应行是响应数据的第一行,其中包含Http协议版本、响应的状态码、响应状态码对应的描述信息 。如上图所示,请求百度之后,百度服务器返回的响应数据的响应行看出,这次请求使用的是Http协议,版本是1.1;响应的状态码是200,代表本次请求响应成功;描述状态码的信息是OK,也是代表本次请求响应成功。

响应头

从响应数据的第二行开始,以key: value的格式出现 。用于提供有关响应的额外信息 ,比如内容类型、缓存控制等,响应头信息是告诉客户端如何更好的处理响应内容、如何缓存资源等。

常见的响应头
Content-Type

指定响应内容的类型,比如text/html、application/json等。

Content-Length

指定响应体的大小(以字节为单位),我们可以看到请求www.baidu.com ,百度的服务器响应回来的响应体是一个Html的页面(也就是我们看到的百度):

Edge浏览器将响应体单独拿出来了,按理来说实际上响应体和请求体一样,在响应头的一个空行的下方。

Cache-Control

指定缓存策略

Server

指定响应所用的服务器软件(百度是BWS/1.1)

Location

在发生重定向时,指定新的URL,这里十分重要,下文会详细讲解

设置客户端的cookie

还有很多响应头,此处不一一列举,响应头的很多原理和请求头是一致的。

响应状态码
1XX

表示响应中,是临时的状态码;表示请求已经接收了,告诉客户端应该继续请求或客户端已经完成则可以忽略(常见于WebSocket技术)。

2XX

成功,该请求已经被成功接收,并且也成功处理,其中200是大家最想看见的。

3XX

重定向,上文介绍Location响应头时提到过,表示重定向到其他地方了,让客户端再次发起一次请求可以完成整个处理。

比如:请求百度:http://www.baidu.com ,百度的请求路径是https://www.baidu.com,但是请求也会成功 是因为第一次请求http的时候,百度的服务器能够接收,会响应一个307状态码,告诉浏览器需要重定向访问正确的百度 ,并且会在响应头中添加Location:https://www.baidu.com 这个响应头,浏览器就会根据这个响应的location 再次发起请求,这次就会成功请求到正确的百度 在重定向中,一共有两次请求响应的过程 ,第一次是请求到了错误的路径,但是服务器成功接收,返回3XX的状态码和在请求头中添加Location:(正确的路径) ;浏览器看到状态码是3XX,就会根据Location的路径发起第二次请求, 但是都是由浏览器在极短的时间内完成的,用户无法察觉

4XX

客户端的错误,处理发生错误,责任在于客户端 。如:请求了不存在的资源、客户端未被授权、禁止访问等,常见404

5XX

服务器错误,处理发生错误,责任在于服务端 。如:客户端程序抛出了异常(500就是服务器端抛异常了)。

HttpServletResponse

HttpServletRequest一样,Tomcat也封装了一个HttpServletResponse对象,我们可以直接操作这个对象来修改响应数据:

java 复制代码
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.io.IOException;

@RestController
public class HttpController {
    @RequestMapping("response")
    public void response(HttpServletResponse response) throws IOException {
        // 设置响应状态码
        response.setStatus(302);
        // 设置响应头
        response.setHeader("Location", "https://www.baidu.com");
        // 设置响应体
        // 响应体需要使用流写入,HttpServletResponse中自带IO流,打开后就可以直接写
        response.getWriter().write("<h1>Hello Response<h1>");
    }
}

我们可以看到,在使用HttpServletResponse类的时候,方法无需返回值,因为服务端会自动将HttpServletResponse响应给客户端,我们将其状态码修改为302,浏览器接收到响应数据时,解析后将重定向到Location指定的URL:

并且,我们可以在响应体中写一些HTML的代码,浏览器会自动解析。

ResponseEntity

Spring框架还提供了一个ResponseEntity对象来完成同样的功能,更加简单,但是原理相同,此处不做过多赘述:

java 复制代码
/**
 * 除了Tomcat服务器的封装,Spring提供了操作响应数据的对象ResponseEntity,可以通过ResponseEntity对象
 * 更加便捷的操作响应数据
 *
 * @return ResponseEntity
 */
@RequestMapping("/response2")
public ResponseEntity<String> response() {
    return ResponseEntity.status(307)
            .header("Location", "https://www.baidu.com")
            .body("<h1>Spring Response<h1>");
}
// 但是需要注意的是:响应状态码(status)和响应头(header)没有特殊要求的话,通常不手动设置
// 服务器会根据请求处理的逻辑自动设置响应状态码和响应头
相关推荐
黄名富几秒前
Kafka 主题管理
java·分布式·kafka
哥谭居民00017 分钟前
学技术步骤,(tomcat举例)jar包api手写tomcat静态资源基础服务器
java·服务器·tomcat
苹果酱05677 分钟前
React性能优化: 使用React.lazy与Suspense提高加载效率
java·vue.js·spring boot·mysql·课程设计
Merlin-Ice17 分钟前
C#Struct堆栈
开发语言·c#
飞的肖25 分钟前
前端全局水印, 拖拉拽图片 ,拽入等比压缩,上传服务器后,java 转base64 加水印,然后前端http预览,确认保存,拽出删除。
java·开发语言·前端·图片上传
java熊猫29 分钟前
Erlang语言的软件工程
开发语言·后端·golang
Good Note30 分钟前
Golang笔记——rune和byte
开发语言·笔记·golang
Linux520小飞鱼35 分钟前
Perl语言的网络编程
开发语言·后端·golang
玩电脑的辣条哥40 分钟前
怎么用python写个唤醒睡眠电脑的脚本?
开发语言·python·电脑
serendipity_hky1 小时前
【Redis学习 | 第5篇】Redis缓存 —— 缓存的概念 + 缓存穿透 + 缓存雪崩 + 缓存击穿
java·数据库·redis·学习·缓存