一.Axios
Axios 是一个基于 Promise 的 HTTP 库,可以用在浏览器和 Node.js 中。它主要用于向服务器发送 HTTP 请求并处理响应,是开发者进行 API 调用的常用工具之一。
实例:
const { data: res } = await $axios.get(path)
在 Axios 中,response
是指服务器响应 HTTP 请求后返回的数据。response
对象包含了多种信息,主要包括请求结果、状态码、响应头以及实际的数据内容。
在 Axios 中,response
对象的属性是由 Axios 库内部定义和生成的。具体来说,这些属性是根据 HTTP 请求的返回结果动态创建的,并通过 Axios 的内部逻辑进行包装和处理。
Axios 内部定义和实现
-
库代码定义:
- Axios 的代码库定义了如何处理 HTTP 请求的响应,并将其包装成标准的
response
对象。这个过程涉及到对原生的 XMLHttpRequest(浏览器环境)或者 http/https 模块(Node.js 环境)进行封装和扩展。 - 相关代码通常位于 Axios 的核心文件中,如
lib/core/settle.js
和lib/core/Axios.js
。
- Axios 的代码库定义了如何处理 HTTP 请求的响应,并将其包装成标准的
-
TypeScript 类型定义:
- 如果使用 TypeScript,可以查看 Axios 的类型定义文件(例如
index.d.ts
),其中详细定义了response
对象的结构。
- 如果使用 TypeScript,可以查看 Axios 的类型定义文件(例如
export interface AxiosResponse<T = any> {
data: T;
status: number;
statusText: string;
headers: any;
config: AxiosRequestConfig;
request?: any;
}
response 对象属性的生成过程
- 发送请求:
- 当你调用
axios.get()
或axios.post()
等方法时,Axios 会创建一个请求对象,并发送 HTTP 请求。
- 当你调用
- 接收响应:
- 请求完成后,Axios 会接收服务器返回的响应数据。
- 封装响应:
- Axios 会将原生的响应对象(例如 XMLHttpRequest 的响应)进行处理,创建一个标准化的
response
对象。这个对象包括data
、status
、statusText
、headers
、config
和request
等属性。
- Axios 会将原生的响应对象(例如 XMLHttpRequest 的响应)进行处理,创建一个标准化的
示例代码解析
以下是 Axios 处理响应的简化示例代码:
// 假设这是从服务器接收到的原生响应对象
const rawResponse = {
data: { name: 'John Doe' },
status: 200,
statusText: 'OK',
headers: {
'content-type': 'application/json'
},
config: { /* 请求配置 */ },
request: { /* 请求对象 */ }
};
// Axios 会将其封装成标准的 response 对象
const response = {
data: rawResponse.data,
status: rawResponse.status,
statusText: rawResponse.statusText,
headers: rawResponse.headers,
config: rawResponse.config,
request: rawResponse.request
};
// 你在 then 方法中接收到的 response 对象
console.log(response.data); // { name: 'John Doe' }
console.log(response.status); // 200
console.log(response.statusText); // 'OK'
console.log(response.headers); // { 'content-type': 'application/json' }
console.log(response.config); // 请求配置对象
console.log(response.request); // 请求对象
参考 Axios 的源码
如果你对 Axios 的内部实现有更深入的兴趣,可以参考其源码,了解具体的封装和处理逻辑。你可以在 Axios 的 GitHub 仓库 中找到所有的源码,并查看相关的实现细节
二.sessionStorage
sessionStorage
是一种Web存储方式,它允许你在浏览器的会话中存储数据。数据存储在浏览器的会话中,当页面会话结束(例如,浏览器标签页关闭)时,数据将被清除。与 localStorage
不同,sessionStorage
仅在会话期间有效。
以下是 sessionStorage
的常见用法示例:
存储数据
// 存储字符串数据
sessionStorage.setItem('key', 'value');
// 存储对象数据,需先将对象转化为字符串
const obj = { name: 'John', age: 30 };
sessionStorage.setItem('user', JSON.stringify(obj));
获取数据
// 获取字符串数据
const value = sessionStorage.getItem('key');
console.log(value); // 输出 'value'
// 获取并解析对象数据
const user = JSON.parse(sessionStorage.getItem('user'));
console.log(user.name); // 输出 'John'
删除数据
// 删除特定项
sessionStorage.removeItem('key');
// 清除所有数据
sessionStorage.clear();
检查数据
// 检查是否有某个键
if (sessionStorage.getItem('key') !== null) {
console.log('Key exists');
} else {
console.log('Key does not exist');
}
示例:结合Vue.js使用
我们来详细展示如何在Vue.js中使用 sessionStorage
。
1. 在 Vue 组件中存储和获取数据
<template>
<div>
<h1>{{ message }}</h1>
<input v-model="inputMessage" placeholder="Enter a message" />
<button @click="storeMessage">Store Message in SessionStorage</button>
<button @click="retrieveMessage">Retrieve Message from SessionStorage</button>
</div>
</template>
<script>
export default {
data() {
return {
message: '',
inputMessage: ''
};
},
methods: {
storeMessage() {
// 存储输入框中的消息到 sessionStorage
sessionStorage.setItem('greetMessage', this.inputMessage);
alert('Message stored in SessionStorage');
},
retrieveMessage() {
// 从 sessionStorage 中获取消息
this.message = sessionStorage.getItem('greetMessage') || 'No message stored';
}
},
mounted() {
// 页面加载时尝试获取存储的消息
this.retrieveMessage();
}
};
</script>
<style scoped>
h1 {
font-size: 2em;
}
button {
margin: 10px;
}
</style>
2. 修改 App.vue
在 src/App.vue
中引入并使用上述组件:
<template>
<div id="app">
<SessionStorageDemo />
</div>
</template>
<script>
import SessionStorageDemo from './components/SessionStorageDemo.vue';
export default {
name: 'App',
components: {
SessionStorageDemo
}
};
</script>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
运行效果
- 打开页面后,你可以在输入框中输入消息,然后点击“Store Message in SessionStorage”按钮将其存储到
sessionStorage
。 - 关闭标签页并重新打开,点击“Retrieve Message from SessionStorage”按钮可以从
sessionStorage
中获取消息(如果会话未结束)。
通过这种方式,你可以在Vue.js应用中方便地使用sessionStorage
来存储和检索数据。
三.@RequestBody
`@RequestBody` 注解是Spring框架中用于处理HTTP请求体的注解。它通常用于将HTTP请求体中的数据绑定到方法参数上,从而实现数据的自动反序列化。以下是关于`@RequestBody`的一些详细说明和示例:
`@RequestBody`的作用
1. 绑定HTTP请求体:将HTTP请求体中的数据自动绑定到方法参数上。
2. 自动反序列化:Spring会根据请求的Content-Type,将请求体中的数据自动反序列化为Java对象,通常使用Jackson库将JSON数据转换为Java对象。
3. 简化数据处理:避免手动解析请求体数据,简化了数据处理过程。
使用示例
假设我们有一个用户登录的例子,用户通过发送包含用户名和密码的JSON数据来进行登录。我们可以使用`@RequestBody`注解来接收这些数据并进行处理。1. 创建一个用户登录请求对象
public class LoginRequest {
private String username;
private String password;
// Getters and setters
}
2. 在控制器中使用`@RequestBody`
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/auth")
public class AuthController {
@PostMapping("/login")
public ResponseEntity<String> login(@RequestBody LoginRequest loginRequest) {
String username = loginRequest.getUsername();
String password = loginRequest.getPassword();
// 处理登录逻辑
if ("admin".equals(username) && "admin".equals(password)) {
return ResponseEntity.ok("Login successful");
} else {
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("Invalid credentials");
}
}
}
3. 发送HTTP请求
客户端可以发送如下的HTTP POST请求:
POST /auth/login HTTP/1.1
Host: localhost:8080
Content-Type: application/json
Content-Length: 44
{
"username": "admin",
"password": "admin"
}
4. 处理流程
1. 客户端发送包含JSON数据的POST请求到`/auth/login`端点。
2. Spring框架接收到请求,并使用`@RequestBody`注解将请求体中的JSON数据自动反序列化为`LoginRequest`对象。
3. `login`方法处理反序列化后的`LoginRequest`对象,并返回相应的响应。
总结
`@RequestBody`注解在Spring MVC中用于将HTTP请求体中的数据自动绑定到方法参数上,并将JSON数据反序列化为Java对象,从而简化了请求数据的处理过程。这在处理需要从客户端接收复杂数据结构(如JSON)的场景中非常有用。
5.所以http请求必须包含和LoginRequest类中一样的属性名的信息,这样才能一一对应吗
是的,HTTP请求体中的JSON数据的属性名必须与Java类(如`LoginRequest`类)中的属性名匹配,这样Spring框架才能正确地将JSON数据反序列化为对应的Java对象。这种匹配是基于属性名的。
详细解释
当你使用`@RequestBody`注解时,Spring会使用Jackson库(默认情况下)将JSON数据转换为Java对象。为了正确地进行转换,JSON数据中的键名需要与Java类中的属性名相同。如果属性名不匹配,Spring无法正确地进行映射,可能会导致属性没有正确赋值。
示例
LoginRequest`类
public class LoginRequest {
private String username;
private String password;
// Getters and setters
}
正确的HTTP请求
{
"username": "admin",
"password": "admin"
}
错误的HTTP请求
{
"user_name": "admin",
"pass": "admin"
}
在上面的错误示例中,JSON数据的属性名`user_name`和`pass`与`LoginRequest`类中的`username`和`password`不匹配,因此无法正确映射到Java对象。
解决方法
如果无法更改JSON数据的属性名,可以使用Jackson的注解来指定映射的属性名。
使用`@JsonProperty`注解
import com.fasterxml.jackson.annotation.JsonProperty;
public class LoginRequest {
@JsonProperty("user_name")
private String username;
@JsonProperty("pass")
private String password;
// Getters and setters
}
修改后的HTTP请求
{
"user_name": "admin",
"pass": "admin"
}
在这个例子中,使用`@JsonProperty`注解指定了JSON数据中的属性名,使得Jackson可以正确地将JSON数据映射到Java对象,即使属性名不匹配。
总结
- 属性名匹配:默认情况下,JSON数据中的属性名需要与Java类中的属性名匹配,Spring才能正确地进行映射。
- 注解支持:如果属性名不匹配,可以使用Jackson的`@JsonProperty`注解来指定映射关系,解决属性名不一致的问题。
这样可以确保HTTP请求中的数据能够正确地映射到对应的Java对象上,保证应用的正常运行。