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)没有特殊要求的话,通常不手动设置
// 服务器会根据请求处理的逻辑自动设置响应状态码和响应头
相关推荐
源代码•宸7 分钟前
分布式缓存-GO(分布式算法之一致性哈希、缓存对外服务化)
开发语言·经验分享·分布式·后端·算法·缓存·golang
云和数据.ChenGuang18 分钟前
PHP-FPM返回的File not found.”的本质
开发语言·php·运维工程师·运维技术
It's now18 分钟前
Spring AI 基础开发流程
java·人工智能·后端·spring
cxh_陈19 分钟前
线程的状态,以及和锁有什么关系
java·线程·线程的状态·线程和锁
计算机毕设VX:Fegn089521 分钟前
计算机毕业设计|基于springboot + vue图书商城系统(源码+数据库+文档)
java·数据库·vue.js·spring boot·后端·课程设计
R.lin34 分钟前
Java 8日期时间API完全指南
java·开发语言·python
毕设源码-赖学姐40 分钟前
【开题答辩全过程】以 高校教学质量监控平台为例,包含答辩的问题和答案
java·eclipse
高山上有一只小老虎1 小时前
翻之矩阵中的行
java·算法
yangpipi-1 小时前
《C++并发编程实战》 第4章 并发操作的同步
开发语言·c++
火钳游侠1 小时前
java单行注释,多行注释,文档注释
java·开发语言