JavaWeb 课程概述

课程中的项目 基于springBoot3+ vue3 技术进行开发,开发模式选用前后端分离模式

  1. 需求分析 -> 页面原型和需求文档

  2. 项目设计^1^

  3. 数据库设计^1^

    基于页面原型和需求文档设计对应的表结构和功能接口

  4. 前后端程序开发

  5. 前后端程序联调测试

  6. 项目部署

Part1: 前端Web基础 (2天)

Part2: 后端Web基础 (4天)

https://heuqqdmbyk.feishu.cn/wiki/MQ95wDTtji6ob6kiRkyc9jamnwg

  • MySQL
  • JDBC
  • Mybatis

https://heuqqdmbyk.feishu.cn/wiki/UmHJwg2cqi0kYUkOFDIcHGfvnld

https://heuqqdmbyk.feishu.cn/wiki/WgPdwfw7PiWSd5knBiYcWE1aneM

Part3: 后端Web实战 (6天)

1. 部门管理

  • 前后端联调测试

image-20260606103347636

Controller接收请求参数(Query 参数)

image-20260606105122810

image-20260606105323433

image-20260606105402730

image-20260606105604260

image-20260606105653645

如果要封装到复杂的类型像list集合这种,就不可以省略@requestParam

image-20260606105732652

image-20260606105915744

DML语句返回值是影响的记录数

image-20260606110138118

Controller接收Json格式的请求参数

image-20260606110453810

image-20260606110711347

image-20260606111007353

Controller接收路径参数

image-20260606131216105

image-20260606131619569

修改

image-20260606131941898

image-20260606132029746

image-20260606132049270

image-20260606132133934

日志技术

  1. 日志技术

  2. 概述

  • 什么是日志?

    • 日志就好比生活中的日记,可以随时随地记录你生活中的点点滴滴。
    • 程序中的日志,是用来记录应用程序的运行信息、状态信息、错误信息的。
  • 为什么要在程序中记录日志呢?

    • 便于追踪应用程序中的数据信息、程序的执行过程。
    • 便于对应用程序的性能进行优化。
    • 便于应用程序出现问题之后,排查问题,解决问题。
    • 便于监控系统的运行状态。
    • … …
  • 之前我们编写程序时,也可以通过 System.out.println(...) 来输出日志,为什么我们还要学习单独的日志技术呢?

​ 这是因为,如果通过 System.out.println(...) 来记录日志,会存在以下几点问题:

  • 硬编码。所有的记录日志的代码,都是硬编码,没有办法做到灵活控制,要想不输出这个日志了,只能删除掉记录日志的代码。
  • 只能输出日志到控制台。
  • 不便于程序的扩展、维护。

所以,在现在的项目开发中,我们一般都会使用专业的日志框架,来解决这些问题。

  1. 日志框架

img

  • JUL**:**这是JavaSE平台提供的官方日志框架,也被称为JUL。配置相对简单,但不够灵活,性能较差。
  • Log4j**:**一个流行的日志框架,提供了灵活的配置选项,支持多种输出目标。
  • **Logback:**基于Log4j升级而来,提供了更多的功能和配置选项,性能由于Log4j。
  • Slf4j**:**(Simple Logging Facade for Java)简单日志门面,提供了一套日志操作的标准接口及抽象类,允许应用程序使用不同的底层日志框架。
  1. Logback入门

1). 准备工作:引入logback的依赖(springboot中无需引入,在springboot中已经传递了此依赖

1
2
3
4
5
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.4.11</version>
</dependency>

2). 引入配置文件 logback.xml (资料中已经提供,拷贝进来,放在 src/main/resources 目录下; 或者直接AI生成)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!-- 控制台输出 -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度 %msg:日志消息,%n是换行符 -->
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50}-%msg%n</pattern>
</encoder>
</appender>

<!-- 日志输出级别 <root level="OFF"> 关闭日志 -->
<root level="ALL">
<appender-ref ref="STDOUT" />
</root>
</configuration>

3). 记录日志:定义日志记录对象Logger,记录日志

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class LogTest {

//定义日志记录对象
private static final Logger log = LoggerFactory.getLogger(LogTest.class);

@Test
public void testLog(){
log.debug("开始计算...");
int sum = 0;
int[] nums = {1, 5, 3, 2, 1, 4, 5, 4, 6, 7, 4, 34, 2, 23};
for (int i = 0; i < nums.length; i++) {
sum += nums[i];
}
log.info("计算结果为: "+sum);
log.debug("结束计算...");
}

}

运行单元测试,可以在控制台中看到输出的日志,如下所示:

img

我们可以看到在输出的日志信息中,不仅输出了日志的信息,还包括:日志的输出时间、线程名、具体在那个类中输出的。

  1. Logback配置文件

Logback日志框架的配置文件叫 logback.xml

该配置文件是对Logback日志框架输出的日志进行控制的,可以来配置输出的格式、位置及日志开关等。

常用的两种输出日志的位置:控制台、系统文件。

1). 如果需要输出日志到控制台。添加如下配置:

1
2
3
4
5
6
7
8
<!-- 控制台输出 -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<!--格式化输出:%d 表示日期,%thread 表示线程名,%-5level表示级别从左显示5个字符宽度,%msg表示日志消息,%n表示换行符 。 .SSS 表示毫秒-->

<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50}-%msg%n</pattern>
</encoder>
</appender>

2). 如果需要输出日志到文件。添加如下配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<!-- 按照每天生成日志文件 -->
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!-- 日志文件输出的文件名, %i表示序号 -->
<FileNamePattern>D:/tlias-%d{yyyy-MM-dd}-%i.log</FileNamePattern>
<!-- 最多保留的历史日志文件数量 -->
<MaxHistory>30</MaxHistory>
<!-- 最大文件大小,超过这个大小会触发滚动到新文件,默认为 10MB -->
<maxFileSize>10MB</maxFileSize>
</rollingPolicy>

<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<!--格式化输出:%d 表示日期,%thread 表示线程名,%-5level表示级别从左显示5个字符宽度,%msg表示日志消息,%n表示换行符 -->
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50}-%msg%n</pattern>
</encoder>
</appender>

3). 日志开关配置 (开启日志(ALL),取消日志(OFF))

1
2
3
4
5
6
7
<!-- 日志输出级别 -->
<root level="ALL">
<!--输出到控 制台-->
<appender-ref ref="STDOUT" />
<!--输出到文件-->
<appender-ref ref="FILE" />
</root>
  1. Logback日志级别

日志级别指的是日志信息的类型,日志都会分级别,常见的日志级别如下(优先级由低到高):

日志级别 说明 记录方式
trace 追踪,记录程序运行轨迹 【使用很少】 log.trace(“…”)
debug 调试,记录程序调试过程中的信息,实际应用中一般将其视为最低级别 【使用较多】 log.debug(“…”)
info 记录一般信息,描述程序运行的关键事件,如:网络连接、io操作 【使用较多】 log.info(“…”)
warn 警告信息,记录潜在有害的情况 【使用较多】 log.warn(“…”)
error 错误信息 【使用较多】 log.error(“…”)

可以在配置文件logback.xml中,灵活的控制输出那些类型的日志。(大于等于配置的日志级别的日志才会输出

1
2
3
4
5
6
7
<!-- 日志输出级别 -->
<root level="info">
<!--输出到控制台-->
<appender-ref ref="STDOUT" />
<!--输出到文件-->
<appender-ref ref="FILE" />
</root>

lombok中提供的@Slf4j注解,可以简化定义日志记录器这步操作。添加了该注解,就相当于在类中定义了日志记录器,就下面这句代码:

1
private static Logger log = LoggerFactory. getLogger(Xxx. class);

image-20260606134614133

2.员工管理

‍‌‍‍⁠⁠‍‬‌‍‬⁠‌‍‌‬‌飞书云文档

image-20260606175524631

image-20260606180600488

image-20260606180758633

image-20260606180922483

image-20260606181051312

image-20260606181923523

image-20260606182146505

image-20260606182311688

image-20260606182612449

‍‌‌‌‍‌‍‍‬‍‍‬‍‌‬‍‬⁠‌09-后端Web实战(员工管理) - 飞书云文档

image-20260606183150393

image-20260606183608314

image-20260606183820910

image-20260606183959864

image-20260606184030059

image-20260606184116115

image-20260606184242740

image-20260606184834110

image-20260606184921843

image-20260606185133958

image-20260606185223009

image-20260607113835592

image-20260607115420132

image-20260607115900964

image-20260607115956784

image-20260607140612052

image-20260607144509372

全局异常处理器(@RestControllerAdvice + @ExceptionHandler)本质上就是基于 AOP 实现的,而不是拦截器(HandlerInterceptor)。

下面我来帮你理清两者的关系。

1. 拦截器 vs AOP

特性 拦截器(HandlerInterceptor Spring AOP
作用范围 专门用于 Spring MVC 的 Controller 层(请求前后) 可作用于任意 Spring 管理的 Bean(Service、Repository、Controller 等)
实现原理 基于 Servlet 的 HandlerExecutionChain,逐个调用拦截器链 基于动态代理(JDK 动态代理或 CGLib)
典型用途 登录检查、日志记录、权限控制、请求参数预处理 事务管理、性能监控、缓存、异常处理

2. @RestControllerAdvice 底层用的是 AOP

  • @RestControllerAdvice = @ControllerAdvice + @ResponseBody
  • @ControllerAdvice 本身带有 @Component,并被 Spring 识别为切面
  • Spring 内部通过 ExceptionHandlerExceptionResolver 这个组件来处理 @ExceptionHandler 注解。
  • 这个解析器会为每个 @ExceptionHandler 方法生成一个 HandlerMethod,并在请求处理过程中(Controller 方法执行后)调用它。
  • 这种“当目标方法(Controller 方法)抛出异常时,自动调用另一个方法(异常处理方法)”的行为,正是 AOP 的环绕通知(@Around 的一种体现。

👉 结论:它使用了 AOP 的思想,但不是传统的拦截器。

3. 为什么说“不是拦截器”?

  • 拦截器preHandle → Controller → postHandleafterCompletion,可以在请求被处理的前后插入逻辑,但它本身不负责异常处理(异常会抛给容器)。
  • 全局异常处理器:不参与请求链,它是通过 异常解析器 在 Controller 方法抛出异常后,匹配对应的 @ExceptionHandler 方法进行统一处理。

两者处理阶段不同,所以不能说是“拦截器的思想”。

image-20260607145637084

image-20260607150852003

image-20260607151311378

3.班级管理

4.学员管理

5.报表统计

6.登录认证

⁠‬‬‍‬⁠‌‍⁠⁠⁠‬‬⁠‬⁠⁠‌12-后端Web实战(登录认证) - 飞书云文档

image-20260607153305360

image-20260607154440292

image-20260607154547445

负载均衡轮询情况下会出现掉登录的情况,

nginx中 对客户端 IP 地址进行哈希计算,根据哈希值将请求固定分配给某一台后端服务器,可以解决这一问题

image-20260607155425463

image-20260607155504258

image-20260607155605155

image-20260607155655716

json web token

image-20260607155927489

生成jwt令牌

image-20260607160426487

解析jwt令牌

image-20260607160535877

image-20260607162630650

jwt生成的令牌保存在本地存储中

image-20260607174054263

image-20260607191350568

image-20260607191602469

image-20260607191710504

image-20260607191832460

dofilter中的第三个参数就是过滤器链,有下一个继续放行到下一个过滤器中

image-20260607193220628

拦截器

image-20260607193432635

image-20260607193531866

image-20260607194430706

image-20260607194749678

Part4: 前端Web实战 (4天)

  • Vue工程化
  • ElementPlus
  • Tlias案例

Part5: 后端Web进阶 (2天)

  • AOP
  • SpringBoot原理
  • 自定义Starter
  • Maven高级

Part6: 部署 (2天)

  • Linux
  • Docker