# big-event-backend **Repository Path**: JabinL/big-event-backend ## Basic Information - **Project Name**: big-event-backend - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-01-20 - **Last Updated**: 2026-02-12 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Big Event Backend 一个基于 Spring Boot 4.0 的事件管理后端系统,提供用户管理、文章发布、分类管理等功能。 ## 文档 - [Spring Security 在本项目中的作用与接入说明](docs/spring-security.md) - [Redis 在真实业务项目中的常见用法(案例手册)](docs/redis-in-practice.md) ## 快速开始(10 分钟跑起来) > 目标:本节按步骤做完后,你可以在本机通过 Swagger 完成「注册/登录 → Authorize → 调用业务接口」。 ### 0) 前置条件 - JDK 21+ - Maven 3.6+ - Docker Desktop(推荐,用于一键启动 MySQL/Redis) ### 1) 启动依赖(MySQL + Redis) 仓库已提供 Compose 模板: - `docs/mysql/docker-compose.yaml` - `docs/redis/docker-compose.yaml` > 注意:这两个 compose 文件里包含 Linux 绝对路径的 volume 挂载(`/home/...`)。在 Windows 上建议直接注释/删除 `volumes:` > 段,或者改成你本机存在的目录。 在 PowerShell 中: ```powershell # MySQL cd D:\OpenSourceProjects\big-event-backend\docs\mysql # 首次启动前:建议先把 docker-compose.yaml 里的 volumes 改为可用路径或注释掉 docker compose -f .\docker-compose.yaml up -d # Redis cd ..\redis # 首次启动前:同样检查 volumes 是否适配当前 OS docker compose -f .\docker-compose.yaml up -d ``` ### 2) 初始化数据库(导入 SQL) 初始化脚本在:`docs/02_后台资料/01_sql/big_event.sql`(会创建数据库 `big_event` 并建表)。 推荐做法(不依赖容器内挂载): 1. 确保 MySQL 已启动(端口 `3306` 暴露到本机)。 2. 用你习惯的客户端(DataGrip / Navicat / MySQL Workbench)连接后执行该 SQL。 > compose 文件里 `MYSQL_DATABASE` 当前是 `test`,但项目默认连接 `big_event`。建议你把 `MYSQL_DATABASE` 改为 `big_event` > ,或至少保证最终存在名为 `big_event` 的库(与 `application.yml` 默认一致)。 ### 3) 配置应用 项目默认用 `src/main/resources/application.yml`,敏感信息通过环境变量覆盖。 #### 方式 A:使用环境变量 / .env(更贴近部署,推荐) 仓库提供了模板文件:`.env.example` - 复制为 `.env` 并按本机环境填写(不要提交到仓库) PowerShell 加载 `.env` 的一个简单方式(当前 shell 会话有效): ```powershell cd D:\OpenSourceProjects\big-event-backend Get-Content .env | ForEach-Object { if ($_ -match '^\s*#' -or [string]::IsNullOrWhiteSpace($_)) { return } $k, $v = $_ -split '=', 2 [System.Environment]::SetEnvironmentVariable($k.Trim(), $v.Trim(), 'Process') } ``` > 说明:IDEA / Run Configuration 里也可以直接配置同名环境变量(更方便)。 #### 方式 B:使用本地 profile 文件(开发方便) 1. 复制示例:`src/main/resources/application-dev.example.yml` → `src/main/resources/application-dev.yml` 2. 在 `application-dev.yml` 填入本地 DB/Redis/JWT 配置 3. 启动时启用 profile:`spring.profiles.active=dev` ### 4) 启动后端 PowerShell: ```powershell cd D:\OpenSourceProjects\big-event-backend mvn -q -DskipTests=false test mvn spring-boot:run ``` 或者在 IDEA 里直接运行 `com.itheima.BigEventApplication`。 ### 5) 验证(Swagger 走一遍闭环) - Swagger UI:`http://localhost:8080/swagger-ui/index.html` - 先调 `POST /user/register` / `POST /user/login` 拿到 token - 右上角 **Authorize** → 选择 `bearerAuth` → 输入:`Bearer ` --- ## Swagger / OpenAPI 项目集成了 OpenAPI 文档与 Swagger UI(基于 springdoc-openapi)。 服务启动后可通过以下地址访问接口文档(假设端口为 `8080`): - Swagger UI:`http://localhost:8080/swagger-ui/index.html` - Swagger UI(兼容入口):`http://localhost:8080/swagger-ui.html` - OpenAPI JSON:`http://localhost:8080/v3/api-docs` - OpenAPI YAML:`http://localhost:8080/v3/api-docs.yaml` > 如果你修改了 `server.port` 或配置了应用的 `context-path`,请把端口/前缀替换成你自己的实际值。 ### 在 Swagger UI 里调用需要登录的接口(JWT) 1. 先在 Swagger 中调用登录接口(或用 Postman 调用 `POST /user/login`)获取 token。 2. 在 Swagger UI 右上角点击 **Authorize**。 3. 在弹框里选择 `bearerAuth`,输入: - `Bearer <你的token>`(推荐) 4. 点击 Authorize 后,再调用其他需要登录的接口即可(Swagger 会自动携带 `Authorization` 头)。 > 说明:鉴权头解析以 `LoginInterceptor` 为准;当前已支持 `Authorization: Bearer `。 > 如果你仍然看不到 Authorize:请确认你访问的是 `http://localhost:8080/swagger-ui/index.html`,并且后端已重启加载最新配置。 ### 访问权限说明(拦截器放行) 本项目使用 `LoginInterceptor` 拦截大部分接口,但已在 `WebConfig` 中放行登录/注册以及文档相关路径,因此 Swagger UI 通常无需登录即可打开: - `/user/login` - `/user/register` - `/v3/api-docs/**` - `/swagger-ui/**` - `/swagger-ui.html` - `/webjars/**` ## 技术栈 - **Java**: 21 - **Spring Boot**: 4.0.0 - **MyBatis**: 4.0.0 - **MySQL**: 数据持久化 - **Redis**: 令牌缓存 - **JWT**: 身份认证 - **阿里云 OSS**: 文件存储 - **Lombok**: 简化代码 - **PageHelper**: 分页查询 - **Jakarta Validation**: 参数校验 ## 项目结构 ``` big-event-backend/ ├── .env.example # 环境变量模板(复制为 .env 使用,勿提交) ├── pom.xml ├── README.md ├── docs/ │ ├── mysql/docker-compose.yaml │ ├── redis/docker-compose.yaml │ ├── 02_后台资料/01_sql/big_event.sql │ └── spring-security.md # Spring Security 文档 └── src/ ├── main/ │ ├── java/com/itheima/ │ │ ├── BigEventApplication.java │ │ ├── anno/ # 自定义注解 │ │ │ └── State.java # 文章状态校验注解 │ │ ├── config/ # 配置类 │ │ │ ├── JwtProperties.java # JWT 配置映射 │ │ │ ├── OpenApiConfig.java # OpenAPI/Swagger 配置 │ │ │ └── WebConfig.java # Web MVC 配置(拦截器注册等) │ │ ├── context/ # 登录用户上下文 │ │ │ ├── UserContext.java │ │ │ └── UserContextHolder.java │ │ ├── controller/ │ │ │ ├── UserController.java │ │ │ ├── CategoryController.java │ │ │ ├── ArticleController.java │ │ │ └── FileUploadController.java │ │ ├── enums/ │ │ │ └── ArticleState.java │ │ ├── exception/ │ │ │ ├── AuthException.java │ │ │ └── GlobalExceptionHandler.java │ │ ├── interceptors/ │ │ │ └── LoginInterceptor.java │ │ ├── mapper/ │ │ │ ├── UserMapper.java │ │ │ ├── CategoryMapper.java │ │ │ └── ArticleMapper.java │ │ ├── pojo/ │ │ │ ├── User.java │ │ │ ├── Category.java │ │ │ ├── Article.java │ │ │ ├── PageBean.java │ │ │ ├── Result.java │ │ │ ├── ApiErrorItem.java │ │ │ └── ValidationErrorData.java │ │ ├── service/ │ │ │ ├── AuthService.java │ │ │ ├── UserService.java │ │ │ ├── CategoryService.java │ │ │ ├── ArticleService.java │ │ │ └── impl/ │ │ ├── utils/ │ │ │ ├── JwtUtil.java │ │ │ ├── Md5Util.java │ │ │ ├── ThreadLocalUtil.java │ │ │ └── AliOssUtil.java │ │ └── validation/ │ │ └── StateValidation.java │ └── resources/ │ ├── application.yml │ ├── application-dev.example.yml │ └── com/itheima/mapper/ArticleMapper.xml └── test/ └── java/com/itheima/... ``` ## 核心功能 ### 1. 用户管理 - **用户注册**: 用户名5-16位非空字符,密码5-16位非空字符 - **用户登录**: 返回JWT令牌,令牌存储在Redis中,有效期1小时 - **获取用户信息**: 根据令牌获取当前登录用户信息 - **更新用户信息**: 昵称、邮箱等 - **更新头像**: 上传头像到阿里云OSS - **修改密码**: 需验证原密码,修改后清除Redis中的令牌 ### 2. 文章管理 - **发布文章**: 支持标题、内容、封面图、分类、状态(已发布/草稿) - **文章列表**: 支持分页查询,可按分类和状态筛选 - **文章校验**: 使用自定义@State注解校验文章状态 ### 3. 分类管理 - **添加分类**: 分类名称、别名必填 - **查询分类列表**: 获取所有分类 - **查询分类详情**: 根据ID查询 - **更新分类**: 支持分组校验 - **删除分类**: 根据ID删除 ### 4. 文件上传 - **图片上传**: 上传到阿里云OSS - **文件命名**: 使用UUID生成唯一文件名,防止覆盖 ## 认证机制 ### JWT + Redis 双重认证 1. 用户登录成功后生成JWT令牌 2. 令牌存储在Redis中,有效期1小时 3. 每次请求携带Authorization头 4. 拦截器验证令牌: - 解析JWT令牌 - 检查Redis中是否存在该令牌 - 将用户信息存入ThreadLocal 5. 请求完成后清理ThreadLocal ### 拦截器配置 - 拦截所有请求 - 排除登录和注册接口:`/user/login`, `/user/register` ## 数据校验 ### 参数校验 - **用户注册/登录**: 用户名和密码使用`@Pattern`正则校验(5-16位非空字符) - **用户信息**: 昵称(1-10位非空字符)、邮箱格式校验 - **文章**: 标题(1-10位非空字符)、封面图URL格式、自定义状态校验 - **分类**: 分组校验(Add/Update) ### 自定义注解 - `@State`: 校验文章状态只能是"已发布"或"草稿" ## 配置说明 ### 方式 A:使用环境变量(推荐) 本项目 `application.yml` 中的敏感配置已改为环境变量占位符,你可以通过环境变量提供: - `BIGEVENT_DB_URL` - `BIGEVENT_DB_USERNAME` - `BIGEVENT_DB_PASSWORD` - `BIGEVENT_REDIS_HOST` - `BIGEVENT_REDIS_PORT` - `BIGEVENT_REDIS_PASSWORD` 阿里云 OSS(上传功能)通过环境变量读取: - `OSS_ACCESS_KEY_ID` - `OSS_ACCESS_KEY_SECRET` ### 方式 B:使用本地 profile 文件(便于开发) 1. 复制示例文件:`src/main/resources/application-dev.example.yml` → `src/main/resources/application-dev.yml` 2. 在 `application-dev.yml` 中按你的开发环境填写真实的 DB/Redis 配置(可以包含开发环境密码) 3. 启动时启用 profile:`spring.profiles.active=dev` > 注意:`application-dev.yml` 已加入 `.gitignore`,不会提交到远程仓库;仓库中只保留 `application-dev.example.yml` 作为模板。 ### application.yml(不含真实密码的示例) ```yaml spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: ${BIGEVENT_DB_URL:jdbc:mysql://localhost:3306/big_event} username: ${BIGEVENT_DB_USERNAME:big_event} password: ${BIGEVENT_DB_PASSWORD:} data: redis: host: ${BIGEVENT_REDIS_HOST:localhost} port: ${BIGEVENT_REDIS_PORT:6379} password: ${BIGEVENT_REDIS_PASSWORD:} server: port: 8080 ``` ## API接口 > 说明:以下为当前后端已实现的主要接口(以 Controller 为准)。更完整/可交互的接口文档请以 Swagger 为准: `/swagger-ui/index.html`。 ### 用户模块(/user) - `POST /user/register` - 用户注册(form/query 参数:`username`, `password`) - `POST /user/login` - 用户登录,返回 JWT token(form/query 参数:`username`, `password`) - `GET /user/userInfo` - 获取当前登录用户信息 - `PUT /user/update` - 更新用户信息(JSON body:`User`) - `PATCH /user/updateAvatar` - 更新头像(query 参数:`avatarUrl`) - `PATCH /user/updatePwd` - 修改密码(JSON body:`old_pwd`, `new_pwd`, `re_pwd`;Header:`Authorization`) ### 分类模块(/category) - `POST /category` - 新增分类(JSON body:`Category`) - `GET /category` - 分类列表 - `GET /category/detail?id=...` - 分类详情 - `PUT /category` - 更新分类(JSON body:`Category`) - `DELETE /category?id=...` - 删除分类 ### 文章模块(/article) - `POST /article` - 发布文章(JSON body:`Article`) - `GET /article` - 文章列表(分页,query 参数:`pageNum`, `pageSize`, 可选 `categoryId`, `state`) - `GET /article/detail?id=...` - 文章详情 - `PUT /article` - 更新文章(JSON body:`Article`,必须包含 `id`) - `DELETE /article?id=...` - 删除文章 ### 文件上传 - `POST /upload` - 上传文件(multipart form:`file`) ## 运行项目 ### 前置条件 - JDK 21+ - MySQL 8.0+ - Redis 6.0+ - Maven 3.6+ ### 启动步骤 1. 克隆项目到本地 2. 配置数据库/Redis/OSS(建议使用环境变量或 application-dev.yml) 3. 执行SQL脚本创建数据库表 4. 运行主类:`BigEventApplication` 5. 访问:`http://localhost:8080` ## 数据库表结构 ### 用户表 (t_user) - id: 主键 - username: 用户名 - password: 密码(MD5加密) - nickname: 昵称 - email: 邮箱 - user_pic: 头像地址 - create_time: 创建时间 - update_time: 更新时间 ### 文章表 (t_article) - id: 主键 - title: 标题 - content: 内容 - cover_img: 封面图 - state: 状态(已发布/草稿) - category_id: 分类ID - create_user: 创建人ID - create_time: 创建时间 - update_time: 更新时间 ### 分类表 (t_category) - id: 主键 - category_name: 分类名称 - category_alias: 分类别名 - create_user: 创建人ID - create_time: 创建时间 - update_time: 更新时间 ## 安全特性 - 密码使用MD5加密存储 - JWT令牌认证 - Redis令牌管理,支持令牌失效 - 登录拦截器保护所有接口 - 参数校验防止非法输入 - 密码字段使用@JsonIgnore忽略JSON序列化 ## 开发规范 - 使用Lombok简化实体类代码 - 统一使用Result对象返回响应 - 使用ThreadLocal存储当前用户信息 - Service层处理业务逻辑 - Mapper层处理数据访问 - 全局异常处理统一错误响应 ## 版本信息 - Spring Boot: 4.0.0 - Java: 21 - MyBatis: 4.0.0 - Lombok: 1.18.32 - JWT: 4.4.0 ## 许可证 本项目仅供学习交流使用。 ## Logging This project logs **to console only** (Logback). Each request gets a `traceId` (MDC) and the service echoes it back in the response header. ### TraceId - Request header: `X-Trace-Id` (optional) - Response header: `X-Trace-Id` (always) - Log field: `traceId=...` ### Log levels (configurable) You can control log level without changing code: - `LOG_LEVEL_ROOT` (default: `INFO`) - `LOG_LEVEL_APP` for package `com.itheima` (default: `INFO`) Example (PowerShell): ```powershell $env:LOG_LEVEL_ROOT = "INFO" $env:LOG_LEVEL_APP = "DEBUG" mvn -q test ``` To reduce framework noise (Spring/MyBatis), the default config sets them to `WARN`. ## Actuator (observability) The project includes Spring Boot Actuator. - Base path: `/actuator` - Exposed endpoints: `health`, `info`, `metrics`, `prometheus` In `dev`, health details are enabled (for local debugging). In the default config, health details are not shown unless authorized. ## Production (2 vCPU / 8GB baseline) This project uses embedded Tomcat (Spring Boot). A good starting point for a **2C / 8G** machine is provided in `src/main/resources/application-prod.yml`. ### Enable prod profile - Set `SPRING_PROFILES_ACTIVE=prod` - Provide DB/Redis credentials via environment variables: - `BIGEVENT_DB_URL`, `BIGEVENT_DB_USERNAME`, `BIGEVENT_DB_PASSWORD` - `BIGEVENT_REDIS_HOST`, `BIGEVENT_REDIS_PORT`, `BIGEVENT_REDIS_PASSWORD` ### Suggested JVM options (Java 21) Tune these based on whether you run on bare metal or inside a container. For 8GB RAM, a common safe baseline is a 2–4GB heap. ```text -Xms2g -Xmx2g -XX:+UseG1GC -XX:MaxGCPauseMillis=200 -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=./logs -Dfile.encoding=UTF-8 -Duser.timezone=Asia/Shanghai ``` ### Tomcat/Hikari sizing notes - Tomcat request threads are capped (default in prod file: `server.tomcat.threads.max=100`) to avoid swamping MySQL. - Hikari pool is set to `maximum-pool-size=10` by default. - If your MySQL can handle more connections and queries are short, try increasing to **15–20**. - Always adjust together with Tomcat threads after measuring p95 latency and DB CPU.