java&vue(一)

后端部分

1. 熟悉后台开发工具,搭建开发环境

  • idea
    20241216193747

  • mysql
    20241216194850

2. 学习网络基础知识,了解网络请求整个过程

20241216195159

引用https://blog.csdn.net/qq_40959677/article/details/94873075

所以其流程大致如下:

  1. DNS 解析域名得到 IP 地址
  2. 客户端与服务器建立连接(TCP 三次握手)
  3. 客户端发起请求
  4. 服务器接收到请求根据端口号.路径等找到对应资源文件,响应源代码给客户端
  5. 客户端拿到请求到的数据(html 页面的源代码),开始解析页面以及请求资源
  6. 客户端渲染页面
  7. web 服务器断开连接(四次挥手)

a. url 的组成

URI:统一资源标识符

URL:统一资源定位符

URN:统一资源名称

20241216195414

url 由请求协议(如 http、https、ftp、tcp 等协议)+域名+端口号+虚拟目录部分+文件名+问号传参+哈希定位

b. DNS 解析过程

1、在浏览器中输入 www . qq .com 域名,操作系统会先检查自己本地的 hosts 文件是否有这个网址映射关系,如果有,就先调用这个 IP 地址映射,完成域名解析。
2、如果 hosts 里没有这个域名的映射,则查找本地 DNS 解析器缓存,是否有这个网址映射关系,如果有,直接返回,完成域名解析。
3、如果 hosts 与本地 DNS 解析器缓存都没有相应的网址映射关系,首先会找 TCP/ip 参数中设置的首选 DNS 服务器,在此我们叫它本地 DNS 服务器,此服务器收到查询时,如果要查询的域名,包含在本地配置区域资源中,则返回解析结果给客户机,完成域名解析,此解析具有权威性。
4、如果要查询的域名,不由本地 DNS 服务器区域解析,但该服务器已缓存了此网址映射关系,则调用这个 IP 地址映射,完成域名解析,此解析不具有权威性。
5、如果本地 DNS 服务器本地区域文件与缓存解析都失效,则根据本地 DNS 服务器的设置(是否设置转发器)进行查询,如果未用转发模式,本地 DNS 就把请求发至 13 台根 DNS,根 DNS 服务器收到请求后会判断这个域名(.com)是谁来授权管理,并会返回一个负责该顶级域名服务器的一个 IP。本地 DNS 服务器收到 IP 信息后,将会联系负责.com 域的这台服务器。这台负责.com 域的服务器收到请求后,如果自己无法解析,它就会找一个管理.com 域的下一级 DNS 服务器地址(http://qq.com)给本地DNS服务器。当本地DNS服务器收到这个地址后,就会找http://qq.com域服务器,重复上面的动作,进行查询,直至找到www . qq .com 主机。
6、如果用的是转发模式,此 DNS 服务器就会把请求转发至上一级 DNS 服务器,由上一级服务器进行解析,上一级服务器如果不能解析,或找根 DNS 或把转请求转至上上级,以此循环。不管是本地 DNS 服务器用是是转发,还是根提示,最后都是把结果返回给本地 DNS 服务器,由此 DNS 服务器再返回给客户机。

即递归查询+迭代查询

20241216195903

c. TCP 三次握手

第一次握手:客户端发送一个带 SYN=1,Seq=X 的数据包到服务器端口(第一次握手,由浏览器发起,告诉服务器我要发送请求了)
第二次握手服务器发回一个带 SYN=1, ACK=X+1, Seq=Y 的响应包以示传达确认信息(第二次握手,由服务器发起,告诉浏览器我准备接受了,你赶紧发送吧)
第三次握手:客户端再回传一个带 ACK=Y+1, Seq=Z 的数据包,代表“握手结束”(第三次握手,由浏览器发送,告诉服务器,我马上就发了,准备接受吧)

c. TCP 四次挥手

第一次挥手:发起方向被动方发送报文,Fin、Ack、Seq,表示已经没有数据传输了。并进入 FIN_WAIT_1 状态。(第一次挥手:由浏览器发起的,发送给服务器,我请求报文发送完了,你准备关闭吧)

第二次挥手:被动方发送报文,Ack、Seq,表示同意关闭请求。此时主机发起方进入 FIN_WAIT_2 状态。(第二次挥手:由服务器发起的,告诉浏览器,我请求报文接受完了,我准备关闭了,你也准备吧)

第三次挥手:被动方向发起方发送报文段,Fin、Ack、Seq,请求关闭连接。并进入 LAST_ACK 状态。(第三次挥手:由服务器发起,告诉浏览器,我响应报文发送完了,你准备关闭吧)

第四次挥手:发起方向被动方发送报文段,Ack、Seq。然后进入等待 TIME_WAIT 状态。被动方收到发起方的报文段以后关闭连接。发起方等待一定时间未收到回复,则正常关闭。(第四次挥手:由浏览器发起,告诉服务器,我响应报文接受完了,我准备关闭了,你也准备吧)

d. 浏览器渲染过程

浏览器解析渲染页面分为一下五个步骤: 1.根据 HTML 解析出 DOM 树 2.根据 CSS 解析生成 CSS 规则树 3.结合 DOM 树和 CSS 规则树,生成渲染树 4.根据渲染树计算每一个节点的信息 5.根据计算好的信息绘制页面

e. 异步的请求

在 web2.0 时代,即使在页面渲染后客户端还是持续与服务器端通信,这个模式被称为 AJAX,是“Asynchronous JavaScript And XML”的缩写。

JS 的解析是由浏览器中的 JS 解析引擎完成的。JS 是单线程运行,也就是说,在同一个时间内只能做一件事,所有的任务都需要排队,前一个任务结束,后一个任务才能开始。但是又存在某些任务比较耗时,如 IO 读写等,所以需要一种机制可以先执行排在后面的任务,这就是:同步任务(synchronous)和异步任务(asynchronous)。JS 的执行机制就可以看做是一个主线程加上一个任务队列(task queue)。同步任务就是放在主线程上执行的任务,异步任务是放在任务队列中的任务。所有的同步任务在主线程上执行,形成一个执行栈;异步任务有了运行结果就会在任务队列中放置一个事件;脚本运行时先依次运行执行栈,然后会从任务队列里提取事件,运行任务队列中的任务,这个过程是不断重复的,所以又叫做事件循环(Event loop)。

浏览器在解析过程中,如果遇到请求外部资源时,请求过程是异步的,并不会影响 HTML 文档进行加载,但是当文档加载过程中遇到 JS 文件,HTML 文档会挂起渲染过程,不仅要等到文档中 JS 文件加载完毕还要等待解析执行完毕,才会继续 HTML 的渲染过程。原因是因为 JS 有可能修改 DOM 结构,这就意味着 JS 执行完成前,后续所有资源的下载是没有必要的,这就是 JS 阻塞后续资源下载的根本原因。CSS 文件的加载不影响 JS 文件的加载,但是却影响 JS 文件的执行。JS 代码执行前浏览器必须保证 CSS 文件已经下载并加载完毕。

3. 熟悉 springboot 基础知识,了解一些基础注解的使用

  1. @Controller 应用在 MVC 层(控制层),DispatcherServlet 会自动扫描注解了此注解的类,然后将 web 请求映射到注解了@RequestMapping 的方法上。
  2. @Service 应用在 service 层(业务逻辑层)
  3. @Reponsitory 应用在 dao 层(实现类)(数据访问层)
  4. @component 表示一个带注释的类是一个组件
  5. @Autowired 根据类型进行注入
  6. @Resource 设置具体的实现的 bean 名称
  7. @Value 指定数据的值
  8. @Qualifier 自动装配时设置具体的实现类型,必须结合如 Autowired 使用
  9. @Data 提高代码的简洁
  10. @RequestMapping 用来映射 web 请求(访问路径和参数),处理类和方法的。(getmapper、putmapper)
  11. @RequestParam 将请求参数绑定到你控制器的方法参数上
  12. @PathVariable @PathVariable 放置在参数前,用来接受路径参数。
  13. @ResponseBody 将返回值放在 response 体内。返回的是数据而不是页面。在异步请求返回 json 数据时使用。
  14. @RequestBody 允许 request 的参数在 request 体中,而不是在直接链接在地址的后面。此注解放置在参数前。
  15. @RestController 组合注解,组合了@Controller@ResponseBody
  16. @SpringBootApplication 启动
  17. @EnableAutoConfiguration 自动配置
  18. @Configuration 配置文件
  19. @ComponentScan 自动扫描
  20. @Aspect 切面
  21. @SpringBootTest 测试注解
  22. @Transactiona 事务声明

4.实现 get,post 请求接口;以及数据的封装

4.1 controller

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
package com.nianxi.controller;

import com.nianxi.entity.User;
import com.nianxi.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequestMapping("/user")
public class UserController {

@Autowired
private UserService userService;

// GET请求:根据用户ID查询用户信息
@GetMapping("/{id}")
public User getUserById(@PathVariable("id") Long id) {
return userService.getUserById(id);
}

// POST请求:添加新用户
@PostMapping
public String addUser(@RequestBody User user) {
boolean success = userService.addUser(user);
return success ? "User added successfully" : "Failed to add user";
}

// GET请求:查询所有用户
@GetMapping
public List<User> getAllUsers() {
return userService.getAllUsers();
}
}

4.2 entity

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package com.nianxi.entity;

import lombok.*;

/**
* @author Jie.
* @description: TODO
* @date 2024/12/17
* @version: 1.0
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
@ToString
public class User {
private Long id;
private String name;
private Integer age;
private String email;
}

4.3 service

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
package com.nianxi.service;

import com.nianxi.entity.User;
import com.nianxi.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class UserService {

@Autowired
private UserMapper userMapper;

public User getUserById(Long id) {
return userMapper.selectById(id);
}

public boolean addUser(User user) {
int result = userMapper.insert(user);
return result > 0;
}

public List<User> getAllUsers() {
return userMapper.selectAll();
}
}

4.4 mapper

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
package com.nianxi.mapper;

import com.nianxi.entity.User;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;

import java.util.List;

/**
* @author Jie.
* @description: TODO
* @date 2024/12/17
* @version: 1.0
*/
@Mapper
public interface UserMapper {
@Select("SELECT * FROM user WHERE id = #{id}")
User selectById(Long id);

@Select("SELECT * FROM user")
List<User> selectAll();

@Insert("INSERT INTO user (name, age, email) VALUES (#{name}, #{age}, #{email})")
int insert(User user);
}

5. 熟悉 mysql 和 mybaits

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
-- 创建数据库
CREATE DATABASE IF NOT EXISTS testdb;

-- 使用数据库
USE testdb;

-- 创建数据表
CREATE TABLE IF NOT EXISTS user (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100),
age INT,
email VARCHAR(100)
);

-- 插入测试数据
INSERT INTO user (name, age, email) VALUES ('John Doe', 30, 'john.doe@example.com');
INSERT INTO user (name, age, email) VALUES ('Jane Smith', 25, 'jane.smith@example.com');
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
server:
port: 8080

spring:
profiles:
# 设置当前环境,用来区分不同环境的配置
active: dev
main:
# 设置banner模式,用来关闭启动时的图标
allow-circular-references: true
# 配置Spring boot数据源
datasource:
driver-class-name: ${star.datasource.driver-class-name}
url: ${star.datasource.url}
username: ${star.datasource.username}
password: ${star.datasource.password}

# 配置mybatis-plus
mybatis-plus:
configuration:
# 配置驼峰命名(实体类属性与数据库字段名称的下划线规则)
map-underscore-to-camel-case: true
# 日志
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
# 实体类别名
type-aliases-package: com.nianxi.entity
# 全局配置
global-config:
db-config:
# 主键类型
id-type: auto
# 映射文件位置
mapper-locations: classpath:mapper/*Mapper.xml

# 日志配置
logging:
level: # 日志级别
com:
nianxi:
mapper: debug # mapper包下的日志级别为debug
service: info
controller: info

6. 完成完整的接口请求功能

  • GET 请求:根据参数查询数据库并返回数据
    URL: GET /user/{id}
    示例: GET /user/1
    该接口会根据请求的 id 查找用户信息,并返回该用户的信息。

  • POST 请求:将数据存入数据库
    URL: POST /user
    示例请求体:

1
2
3
4
5
{
"name": "Alice",
"age": 28,
"email": "alice@example.com"
}

该接口会接收 POST 请求体中的数据,插入到数据库中,并返回插入成功的消息。

测试

1
2
3
4
5
6
{
"id": 1,
"name": "John Doe",
"age": 30,
"email": "john.doe@example.com"
}
1
2
3
4
5
{
"name": "Alice",
"age": 28,
"email": "alice@example.com"
}

响应:

1
"User added successfully"

总结

学习了网络基础知识,了解网络请求整个过程
以上实例展示了如何实现一个简单的 RESTful 接口,包括 GET 和 POST 请求的实现,以及 MySQL 数据库的基本操作。通过使用 Spring Boot、Mybatis 和 MySQL,可以快速实现数据的查询和插入功能,同时还涉及到了数据的封装和接口的设计。