Web开发-后端基础篇
与其花时间编写解释你写出的糟糕的代码的注释,不如花时间清理那堆糟糕的代码。
Maven
概述
Maven 是一个 基于 POM(Project Object Model) 的构建工具,它通过一个 pom.xml 文件来管理项目的配置,包括依赖、插件、构建流程等。
Maven的作用包括以下几点:
- 依赖管理 :自动下载并管理项目所需的第三方库(如JUnit,Spring,MySQL驱动),避免手动引入jar包。
- Jar包:用于打包Java类、资源文件和元数据的压缩文件格式。
- 标准化项目结构 :Maven 提倡统一的项目目录结构,关于具体的结构我们下面再讲。
- 构建自动化 :一条命令即可完成编译、测试、打包、安装、部署等流程。
- 插件机制 :支持丰富的插件。

Maven项目结构
1 | |
Maven Wrapper
Maven Wrapper 是一种让项目自带Maven的“启动器”,它的关键作用是:
- 保证团队成员使用相同版本的Maven,避免版本不一致的尴尬问题
- 不需要预先在系统中全局安装Maven,项目开箱即用
- 常用于CL/CD环境,如GitHub Action,Jenkins,GitLab CL等。
- CL(持续集成):频繁地(每天多次)将代码集成到主分支,并自动构建、测试 ,从而快速发现问题。
- CD(持续交付):CI 之后,自动将构建好的产物发布到“可上线”的环境(如测试、预发布环境)
Maven Wrapper 包含的文件
1 | |
当你通过mvnw允许命令时:
1 | |
- 检查
.mvn/wrapper/maven-wrapper.properties中指定的 Maven 版本。 - 如果没有这个Maven版本,自动下载。
- 使用对应版本的Maven执行
clean install<span> </span>命令
所以在拿到手一个新的Maven项目时,可以优先使用mvnw命令,以确保使用相同的版本减少错误的发生。
Maven配置
Maven官网:Welcome to Apache Maven – Maven
Maven的安装包解压后目录如下:
- 我们需要将
bin目录添加到环境变量中 conf中存储的为Maven的全局配置文件- 如果想要用户等级的配置文件,在目录
${user.home}/.m2/settings.xml
- 如果想要用户等级的配置文件,在目录
配置阿里云公共镜像
代开maven的配置文件 conf/settings.xml,在 <mirrors></mirrors>标签中添加 mirror 子节点:
1 | |
配置IDEA
全局Maven配置
全局配置环境需要我们在不打开任何项目时进行配置。
若打开任意项目,进行配置,则为当前项目进行配置,过程一致。
首先点击左下角的齿轮,然后打开设置。
找到Maven设置:

- Maven主路径:选择Maven文件夹的根目录
- 用户设置文件:如果添加了私服等,请重重新选择你的配置文件。
- 或者将你的配置文件放在默认路径下
然后选择运行java程序版本:

最后在Java编译器中也选择相同的Java版本:

创建Maven项目
IDEA中创建Maven项目我们首先新建项目:

填写项目名,以及组织名:

Groupid和ArtifactId组成了项目的唯一标识符。- 不同的
Groupid用来区分不同来源的库。 - 依赖声明:
Groupid和ArtifactId是引入依赖的重要依据。
项目创建完成:

依赖管理
添加依赖
我们打开 pom.xml
- 添加标签
<dependencies></dependencies>:
1 | |
在
<dependencies>中使用<dependency>引入坐标点击刷新按钮,修改生效

Maven仓库:Maven Repository: Search/Browse/Explore
可以在Maven仓库中搜索想要的插件。
依赖传递
直接依赖:在当前项目中通过依赖配置建立的依赖关系。
间接依赖:被依赖的资源如果依赖其他资源,当前项目间接依赖其他资源。

排除依赖

若项目A 依赖项目B,却并不想要导入项目B中的某个依赖,可以使用依赖排除。
- 排除依赖:排除依赖指主动断开依赖的资源,被排除的资源无需指定版本。
1 | |
导入B包,却排除B包依赖的junit
依赖范围
Maven 依赖的 作用范围 (scope)决定了依赖在 编译、测试、运行、打包 等阶段的可用性。
默认情况下,依赖是 compile 范围,可在任何地方使用。
通过 <scope>...</scope> 标签设置依赖范围。
| scope 值 | 主程序 (main) | 测试程序 (test) | 打包/运行 (package) | 示例依赖 | 典型用途 |
|---|---|---|---|---|---|
| compile (默认) | ✅ 可用 | ✅ 可用 | ✅ 参与 | log4j | 常规依赖,编译、测试、运行都需要 |
| test | ❌ 不可用 | ✅ 可用 | ❌ 不参与 | junit | 仅测试阶段需要 |
| provided | ✅ 可用 | ❌ 不可用 | ❌ 不参与 | servlet-api | 编译需要,但运行环境会提供 |
| runtime | ❌ 不可用 | ❌ 不可用 | ✅ 参与 | JDBC 驱动 | 运行时需要,编译不需要 |
使用示例:
1 | |
生命周期
Maven 构建生命周期包含三个基本的生命周期:
- clean:清理项目
- default(build):核心构建流程
- site:生成项目文档

在Maven中,当你执行生命周期中的任意一个阶段时,都会顺序执行该阶段前面的所有阶段。
但是三大生命周期之间的关系是独立的,例如执行 site不会执行 build和 clean。
常用阶段:
| 生命周期阶段 | 作用 |
|---|---|
| clean | 移除上一次构建生成的文件 |
| compile | 编译项目源代码。 |
| test | 运行单元测试。 |
| package | 将项目打包成可分发的文件,如 .jar或 .war。 |
| install | 将打包文件安装到本地仓库。 |
运行生命周期
方式一:在IDEA中直接双击对应生命周期

方式二:终端中直接输入 mvn + clean周期 + build周期 + site周期

生命周期的运行原理
生命周期本都是一个个抽象的概念,本身并不执行任何操作。其所有的操作都是由绑定的插件来完成的。

Web入门
spring 官网:Spring | Home
Spring 是一个 轻量级、开源的 Java 企业级应用开发框架 ,目标是通过 IoC(控制反转) 和 AOP(面向切面编程) 简化企业应用开发,提升代码的可维护性与扩展性。
常见子项目:
| 子项目 | 作用 |
|---|---|
| Spring Boot | 快速构建独立可运行应用 |
| Spring Data | 简化数据库访问 |
| Spring Security | 安全与权限控制 |
| Spring Cloud | 微服务架构支持 |
| Spring Batch | 批处理任务 |
Spring发展到今天已经形成一种开发生态圈,Spring提供了若干子项目,每个项目用于完成特定的功能。
SpringBoot入门
Spring Boot 是 基于 Spring 框架的快速开发框架 ,旨在 简化 Spring 应用的创建、配置与部署 ,让开发者专注于业务逻辑,而不是繁琐的环境搭建与配置。
创建SpringBoot项目

我们不直接创建Maven项目,而是直接创建SpringBoot项目。然后点击下一步:

这里我们选择一些我们需要安装的包,这里我只选择了Spring Web包。
创建完毕:

简单体验SpringBoot
文件 SpringbootQuickStartApplication.java是SpringBoot的启动类。我们通过该类启动SpringBoot项目。
1 | |
我们相对于启动类创建java类:controller/HelloSpring.java
1 | |
直接点击上方启动按钮启动服务:

web服务器默认监听端口:8080

Http协议
Http概述
HTTP (Hyper Text Transfer Protocol,超文本传输协议)
- 定义:规定了 浏览器 与 服务器 之间数据传输的规则
- 作用:用于传输 HTML、JSON、图片、视频等各种资源
核心特点:
| 特点 | 说明 | 影响 |
|---|---|---|
| 基于 TCP 协议 | 面向连接,数据传输可靠 | 需要三次握手,安全性高 |
| 请求-响应模型 | 一次请求对应一次响应 | 客户端主动发起,服务端被动响应 |
| 无状态协议 | 不记录事务处理的上下文 | - 缺点:多次请求间无法共享数据``- 优点:处理速度快、资源占用少 |

Http-请求协议
HTTP 请求报文由 请求行 + 请求头 + 请求体 组成。

请求行(Request Line)
- 格式:
请求方法 请求路径 协议版本 - 示例:
GET /brand/findAll?name=OPPO&status=1 HTTP/1.1POST /brand HTTP/1.1
- 作用:告诉服务器要做什么(方法)、访问哪个资源(路径)、使用哪个协议版本
常见请求方法:
- GET :获取资源
- POST :提交数据
- PUT :更新资源(整体替换)
- PATCH :部分更新资源
- DELETE :删除资源
请求头(Request Headers)
- 从第二行开始,格式为
Key: Value - 用于传递客户端环境信息、请求参数、数据格式等
常见请求头:
| 请求头 | 说明 |
|---|---|
| Host | 请求的主机名 |
| User-Agent | 浏览器版本,例如 Chrome 浏览器的标识类似 Mozilla/5.0 ... Chrome/79,IE 浏览器的标识类似 Mozilla/5.0 (Windows NT ...) like Gecko |
| Accept | 表示浏览器能接受的资源类型,如 text/*、/image/* 或 */* 表示所有 |
| Accept-Language | 表示浏览器偏好的语言,服务器可以据此返回不同语言的网页 |
| Accept-Encoding | 表示浏览器可以支持的压缩类型,例如 gzip、deflate 等 |
| Content-Type | 请求主体的数据类型 |
| Content-Length | 请求主体的大小(单位:字节) |
请求体
- 仅在部分方法(如 POST、PUT、PATCH)中存在
- 用于传递数据(表单、JSON、XML 等)
示例:
1 | |
GET与POST对比
| 对比项 | GET | POST |
|---|---|---|
| 数据位置 | URL 查询参数 | 请求体 |
| 数据长度 | 有限制(取决于浏览器/服务器) | 理论无限制 |
| 安全性 | 参数暴露在 URL 中 | 参数在请求体中,相对更隐蔽 |
| 常用场景 | 查询数据 | 提交数据、上传文件 |
HTTP-响应协议
HTTP 响应报文由 响应行 + 响应头 + 响应体 三部分构成。

响应行
- 位置 :响应数据的第一行
- 格式 :
协议版本 状态码 状态描述 - 示例:
1 | |
- 作用 :告知客户端响应的协议版本、处理结果状态及简要说明
状态码大全:HTTP 响应状态码
状态码分类:
| 状态码范围 | 分类 | 说明 |
|---|---|---|
| 1xx | 临时状态码 | 请求已接收,提示客户端继续请求或忽略 |
| 2xx | 成功 | 请求已成功接收并处理完成 |
| 3xx | 重定向 | 需要客户端发起新的请求以完成处理 |
| 4xx | 客户端错误 | 请求有误,责任在客户端(如资源不存在、未授权、禁止访问等) |
| 5xx | 服务器错误 | 处理出错,责任在服务端(如程序异常) |
响应头
- 从第二行开始,格式为
Key: Value - 用于描述响应的元信息(数据类型、长度、连接方式等)
常见响应头:
| 响应头 | 说明 |
|---|---|
| Content-Type | 响应内容的类型,例如 text/html、application/json |
| Content-Length | 响应内容的长度(字节数) |
| Content-Encoding | 响应内容的压缩算法,例如 gzip |
| Cache-Control | 缓存策略,例如 max-age=300 表示最多缓存 300 秒 |
| Set-Cookie | 设置 Cookie 到浏览器,用于会话或状态管理 |
响应体
- 位于响应头之后的空行后
- 存放实际返回的数据内容(HTML、JSON、图片等)
示例(JSON 数据):
1 | |
HTTP-协议解析
Http协议解析用于解析客户端发送的HTTP请求,并发送标准的Http响应。通常我们并不自己手动完成这一部分。我们可以直接借助于第三方Web服务器解析http请求,如Tomcat、Jetty、WebLogic、WebSphere等
Web服务器
一种软件程序,对 HTTP 协议 的操作进行封装,使开发者无需直接处理协议细节,从而简化 Web 开发。
核心作用:
- 协议封装 :屏蔽底层 HTTP 请求/响应的复杂性。
- 资源提供 :向客户端(浏览器)提供 HTML、CSS、JS、图片等资源。
- 动态处理 :与后端应用(如 Servlet、PHP、Node.js)协作,生成动态内容。
Tomcat
Tomcat官网:Apache Tomcat® - Welcome!
Tomcat是Apache软件基金会一个核心项目,是一个开源免费的轻量级Web服务器,支持Servlet/JSP少量JavaEE规范。
Tomcat也被称为Web容器、Servlet容器。Servlet程序需要依赖于Tomcat才能运行。
Tomcat安装目录:

启动:执行 bin/start.bat脚本
关闭:
- 直接关闭窗口
- 执行
bin/shutdown.bat - Ctrl + C
端口配置:
conf/server:(默认8080)

HTTP协议默认端口号为80,如果将Tomcat端口号改为80,则将来访问Tomcat时,将不用输入端口号。
部署应用程序:将项目放在webapps目录下即可。
SpringBoot中的依赖
起步依赖
Spring Boot 提供了 Starter 机制,利用maven的依赖传递,将常用依赖打包成一个统一入口,简化配置。
| 依赖名 | 版本 | 作用 |
|---|---|---|
spring-boot-starter-web |
2.7.4 | Web 应用开发的核心依赖,包含 Spring MVC、JSON 处理、内嵌 Tomcat 等 |
spring-boot-starter-test |
2.7.4 | 单元测试依赖,包含 JUnit、Mockito、Spring Test 等 |
SpringBoot-Web程序的启动依赖于内置Tomcat服务器。
所有的起步依赖:Spring Boot Reference Documentation
在SpringBoot中,起步依赖的的引入无需指定版本version:
1 | |
这是由于所有的SpringBoo项目都继承于一个版本的SpringBoot父工程:
1 | |
在父工程中会自动引入与版本号对应的起步依赖。
请求响应
SpringMVC流程
SpringBoot本身只是一个Spring 应用的快速开发脚手架,真正负责处理Web请求的是SpringBoot起步依赖 start-web包中的SpringMVC框架。


流程:
| 阶段 | 主要参与者 | 关键动作 | 备注 |
|---|---|---|---|
| 1. 请求进入 | 浏览器 → Tomcat | 浏览器发起 HTTP 请求 | URL 可能包含路径参数、查询参数 |
| 2. 封装请求 | Tomcat | 创建 HttpServletRequest / HttpServletResponse 对象 |
由 Servlet 容器负责 |
| 3. 前端控制器 | DispatcherServlet |
统一入口,拦截请求 | 在 web.xml 或 Java Config 中注册 |
| 4. 查找处理器 | HandlerMapping |
根据 URL 找到对应的 Handler(通常是 Controller 方法) |
支持多种映射策略(注解、XML 等) |
| 5. 调用处理器 | HandlerAdapter |
适配并调用目标 Controller 方法 | 负责参数绑定、类型转换 |
| 6. 返回结果 | Controller | 返回 ModelAndView 或其他类型(如 @ResponseBody) |
REST 接口可能直接返回 JSON |
| 7. 视图解析 | ViewResolver |
将视图名解析为具体视图(JSP、Thymeleaf 等) | REST 场景可跳过 |
| 8. 渲染视图 | 视图对象 | 将模型数据渲染为 HTML/JSON | 输出写入 HttpServletResponse |
| 9. 响应返回 | Tomcat | 将响应发送给浏览器 | HTTP 状态码、响应头、响应体 |
BS架构:浏览器 / 服务器架构
CS架构:客户端 / 服务器架构
Postman
postman官网:Postman
Postman是一款功能强大的网页调试与发送网页HTTP请求的Chrome插件。
作用:常用于进行接口测试。

可以模拟浏览器发送各种请求,用来测试程序API
获取简单参数
原始方式
HttpServletRequest 对象代表了客户端发送给Servlet的HTTP请求。通过这个对象,你可以获取到请求的所有信息。
1 | |
常用方法:
getParameter(String name):获取指定名称的请求参数的值(返回String)。如果参数不存在或有多个同名参数,行为可能不确定。getParameterValues(String name): 获取指定名称的所有请求参数的值(返回String[])。getParameterMap(): 获取所有请求参数的Map<String, String[]>。
使用GET请求:

SpringMVC方法
参数名与形参变量名相同,定义形参即可接收参数。
1 | |
RequestMapping允许所有的请求方式
- 当没有客户端没有发送形参名一致的参数时,值为
null
使用post请求:

@RequestParam
如果方法形参名与请求参数名称不匹配,或者需要对于参数进行一些额外配置,可以使用RequestParam。
基本用法:
1 | |
常用属性:
| 属性名 | 类型 | 说明 | 默认值 |
|---|---|---|---|
value / name |
String |
请求参数名(两者等价,二选一即可) | 必填(除非参数名与方法形参名一致且开启参数名推断) |
required |
boolean |
是否必须提供该参数 | true |
defaultValue |
String |
当参数缺失或为空时使用的默认值,设置后 required 自动失效 |
null |
实体参数
创建实体
实体参数就是将Http请求的参数封装到一个实体对象中。
首先我们创建User类:Model/User.java
1 | |
要想能够成功封装,一下两个条件满足一个即可:
- 只有一个
public有参构造函数,若有多个构造方法,Spring不知道该用哪个。- 有无参构造方法(优先使用),以及有对饮成员的set方法。
推荐的方法:将 User 定义成标准 JavaBean
- 提供 public 无参构造器;
- 提供字段的 getter/setter;
- 这样 Spring 的 DataBinder 就能通过无参构造创建实例并按名称填充属性。
1 | |
实体变量
1 | |
Spring会自动将参数封装进入变量,没有参数对应的值为null;

实例嵌套
我们再创建一个Address类,并且Address类是User类的一个成员变量:
Model/Address.java
1 | |
Model/User.java:
1 | |
如果没有嵌套类的getter,导致 Spring 无法自动创建并绑定 address,最终为 null。

数组集合参数
数组参数:请求参数名与形参数组名称相同且请求参数为多个,定义数组类型形参即可接收参数
1 | |
集合参数:请求参数名与形参集合名称相同且请求参数为多个,@RequestParam绑定参数关系
1 | |
这里
@RequestParam用于绑定集合参数。
日期时间类型的参数
请求示例:
1 | |
控制器示例:
1 | |
@DateTimeFormat 注解:
- 将请求参数的字符串按指定格式解析为
LocalDateTime、LocalDate、LocalTime等日期类型。 - 常用属性:
pattern:日期时间格式化模式(必须与请求参数格式一致)。- 常见模式:
yyyy-MM-dd、yyyy-MM-dd HH:mm:ss
请求参数的日期格式必须与pattern完全一致,否则抛出400错误。
Json参数
postman发送json请求

Sping接收Json数据
首先定义好与Json数据对应数据模型如:User 类,Address类。
1 | |
@RequestBody注解用于将请求体中的json数据绑定到Java对象。
路径参数
声明动态参数:
1 | |
@PathVariable注解:用于获取路径参数
示例:
1 | |
响应
@ResponseBody
类型 :方法注解 / 类注解
位置 :
- 方法上 :仅作用于该方法
- 类上 :作用于类中所有方法
功能 :
- 将方法返回值直接写入 HTTP 响应体(Response Body)
- 如果返回值是 实体对象 / 集合 ,会自动序列化为 JSON 格式响应
示例:
1 | |
如果一整个类的方法都直接返回数据,可以直接使用 @RestController注解。
等价于:
1 | |
@Controller:
- 用于标注一个类是控制器组件(Controller),由SpringMVC扫描并注册到容器中,用来接收和处理前端请求。
统一响应封装
背景问题:
- 不同接口返回类型不一致(
String、对象、集合),前端解析复杂 - 缺乏统一的响应格式,不便于状态码、提示信息、数据的统一管理
设定一个返回类,所有的返回信息由Result类进行包装:
1 | |
静态资源
static目录作用:
- 存放静态资源 (无需 Controller 处理,直接由 Spring MVC 静态资源处理器返回)
- 常见文件类型:
- HTML、CSS、JavaScript
- 图片(JPG、PNG、GIF…)
- 字体文件(TTF、WOFF…)
- 其他前端静态资源
默认静态资源目录(优先级)
Spring Boot 内置了静态资源映射,默认会从以下位置查找(优先级从高到低):
classpath:/META-INF/resources/classpath:/resources/classpath:/static/← 最常用classpath:/public/${user.dir}/public/(运行目录下的public)
优先级规则 :同名文件会返回优先级高的目录中的版本。
访问规则
URL访问路径 = 应用根路径 + 文件名
例如:
1 | |
访问:
1 | |
与Controller的优先级
如果URL同时匹配Controller路径和静态资源路径:
- Controller优先
例如:、
/foo有一个 Controller 方法/static/foo下也有一个文件- 访问
/foo→ 返回 Controller 的结果
默认首页
如果静态资源目录下有index.html,访问 /会直接返回它。
获取resources文件夹下的资源
ClassLoader方式(简单)
假设我们要读取 src/main/resources/readme.txt
1 | |
在 Controller中:
1 | |
成功读取:

Spring的 ClassPathResource
1 | |
分层解耦
三层架构

controller:控制层,接收前端发送的请求,对请求进行处理,并返回响应数据service:业务逻辑层,处理具体的业务逻辑dao:数据访问层 / 持久层, 负责数据访问操作,包括数据的增、删、改、查(CRUD)
IOC & DI
对象的创建与依赖管理交给外部容器,而不是由代码自己 new 出来。
| 概念 | 全称 | 定义 | 作用 |
|---|---|---|---|
| IOC | Inversion of Control(控制反转) | 对象的创建控制权由程序自身转移到外部容器 | 降低代码耦合度,让对象的依赖关系由容器管理 |
| DI | Dependency Injection(依赖注入) | 容器在运行时将应用所需的依赖资源注入到对象中 | 让对象无需自己创建依赖,专注于业务逻辑 |
| Bean | - | IOC 容器中创建和管理的对象 | 统一生命周期管理,可被注入到其他对象中 |
没有IOC/DI时:
- 每个 Controller 可能会自己
new一个 Service 实例
- 结果:
- 对象创建分散、重复
- 耦合度高(Controller 依赖具体实现类)
- Service 的状态和配置无法统一管理
有IOC/DI时:
- Service对象 由 IOC 容器 创建并管理(通常是单例 Bean)。
- 多个 Controller 只需声明依赖(
@Autowired),容器会自动将依赖注入。 - 容器会在运行时将同一个 Service 实例注入到不同的 Controller 中。
IOC/DI入门
@Component
作用
- 声明一个类是 Spring 管理的 Bean
- 相当于告诉 IOC 容器:“这个类需要被扫描、实例化,并纳入容器管理”
- 默认 Bean 名是类名首字母小写(可通过
@Component("beanName")自定义)
衍生注解:
| 注解 | 说明 | 位置 |
|---|---|---|
| @Component | 声明 bean 的基础注解 | 不属于以下三类时,用此注解 |
| @Controller | @Component 的衍生注解 | 标注在控制器类上 |
| @Service | @Component 的衍生注解 | 标注在业务类上 |
| @Repository | @Component 的衍生注解 | 标注在数据访问类上(由于与 MyBatis 整合,用的少) |
针对经典的三层架构,Spring已经预设了经典的类型注解,平时我们优先使用 @Controller 、@Service、@Repository
不属于这几类我们再使用:@Component
@Autowired注解
作用
- 自动注入依赖对象 (DI 的实现方式之一)
- 告诉 Spring:在容器中找到匹配的 Bean,并注入到当前字段、构造器或 Setter 方法中
注入规则
默认按类型(byType)匹配
- 容器中必须有且只有一个该类型的 Bean
若有多个同类型 Bean
- 再按名称(byName)匹配(字段名或参数名)
可配合
@Qualifier("beanName")- 精确指定要注入的 Bean
- 默认按类型注解,有多个同类型注解
@Qualifier才生效
1
2@Autowired
@Qualifier("dogA") // 精确指定注入 dogA
其他相关注解:
@Primary:指定优先对象。被@Primary注解修饰的对象将优先注解。1
2@Primary
@Component@Resource:通过名称Bean进行依赖注入(来源JDK 包)1
2@Resource(name = "dogA")
//无需Autowired注解