refactor(pojo): 修正Article类中attributeid字段的列名拼写

feat(controller): 在ArticleController中添加根据属性ID获取文章的方法

style(repository): 在CategoryRepository方法上添加空行提高可读性

chore: 移除MyAfterProjecyApplication中多余的MapperScan注解
This commit is contained in:
qingfeng1121
2025-10-19 11:11:56 +08:00
parent bd6b240f52
commit effcc3838d
8 changed files with 457 additions and 61 deletions

View File

@@ -2,7 +2,7 @@
## 项目概述
MyAfterProject是一个基于Spring Boot的后端博客系统提供文章管理、留言板等功能的API接口。本文档旨在帮助前端开发者理解和使用这些API接口
MyAfterProject是一个基于Spring Boot的后端博客系统提供文章管理、留言板等功能的RESTful API接口。系统集成了Spring Security和JWT认证机制确保API的安全性和权限控制。本文档旨在帮助前端开发者理解和使用这些API接口包括接口规范、请求/响应格式、认证方式及最佳实践
## 技术栈
@@ -10,8 +10,10 @@ MyAfterProject是一个基于Spring Boot的后端博客系统提供文章管
- **ORM框架**: Spring Data JPA
- **数据库**: MySQL
- **缓存**: Redis
- **认证**: Spring Security + JWT
- **API风格**: RESTful
- **认证授权**: Spring Security + JWT Token
- **API风格**: RESTful API
- **错误处理**: 全局异常处理机制
- **权限控制**: 基于角色的访问控制(RBAC)
## 项目结构
@@ -19,29 +21,45 @@ MyAfterProject是一个基于Spring Boot的后端博客系统提供文章管
src/main/java/com/qf/myafterprojecy/
├── controller/ # 控制器层处理HTTP请求
│ ├── ArticleController.java # 文章相关API
── MessageController.java # 留言相关API
── MessageController.java # 留言相关API
│ └── AuthController.java # 认证相关API
├── pojo/ # 实体类和数据传输对象
│ ├── Article.java # 文章实体
│ ├── Message.java # 留言实体
│ ├── User.java # 用户实体
│ ├── Role.java # 角色实体
│ ├── ResponseMessage.java # 统一响应消息格式
│ └── dto/ # 数据传输对象
│ ├── ArticleDto.java # 文章DTO
│ └── MessageDto.java # 留言DTO
├── repository/ # 数据访问层
│ ├── ArticleRepository.java # 文章数据访问
── MessageRepository.java # 留言数据访问
── MessageRepository.java # 留言数据访问
│ ├── UserRepository.java # 用户数据访问
│ └── RoleRepository.java # 角色数据访问
├── service/ # 业务逻辑层
│ ├── ArticleService.java # 文章服务实现
│ ├── IArticleService.java # 文章服务接口
│ ├── MessageService.java # 留言服务实现
│ └── IMessageService.java # 留言服务接口
├── config/ # 配置类
│ ├── SecurityConfig.java # Spring Security配置
│ └── security/ # 安全相关组件
│ ├── JwtTokenProvider.java # JWT令牌生成器
│ ├── JwtAuthenticationFilter.java # JWT认证过滤器
│ └── UserDetailsServiceImpl.java # 用户认证服务
├── GlobalExceptionHandler.java # 全局异常处理器
└── MyAfterProjecyApplication.java # 应用入口
```
## 配置信息
后端服务默认运行在 `http://localhost:8080` 端口前端项目需要将API请求指向该地址。
- **服务地址**: `http://localhost:8080`
- **API基础路径**: `/api`
- **认证头**: `Authorization: Bearer {token}`
- **默认测试账号**:
- 作者账号: `test_author` / `password123` (拥有AUTHOR角色)
- 管理员账号: `test_admin` / `admin123` (拥有ADMIN角色)
## API接口详细说明
@@ -178,7 +196,10 @@ POST /api/articles
**功能**: 创建新文章
**权限**: 需要AUTHOR角色
**权限**: 需要AUTHOR角色 (通过`@PreAuthorize("hasRole('AUTHOR')")`控制)
**请求头**:
- `Authorization: Bearer {token}` (必需)
**请求体**:
```json
@@ -213,7 +234,10 @@ PUT /api/articles/{id}
**功能**: 更新现有文章
**权限**: 需要AUTHOR或ADMIN角色
**权限**: 需要AUTHOR角色 (通过`@PreAuthorize("hasRole('AUTHOR')")`控制)
**请求头**:
- `Authorization: Bearer {token}` (必需)
**请求参数**:
- `id`: 文章ID路径参数
@@ -248,7 +272,10 @@ DELETE /api/articles/{id}
**功能**: 删除指定文章
**权限**: 需要AUTHOR或ADMIN角色
**权限**: 需要AUTHOR或ADMIN角色 (通过`@PreAuthorize("hasRole('AUTHOR') or hasRole('ADMIN')")`控制)
**请求头**:
- `Authorization: Bearer {token}` (必需)
**请求参数**:
- `id`: 文章ID路径参数
@@ -362,6 +389,9 @@ DELETE /api/messages/{id}
**权限**: 需要ADMIN角色
**请求头**:
- `Authorization: Bearer {token}` (必需)
**请求参数**:
- `id`: 留言ID路径参数
@@ -411,6 +441,64 @@ DTO类用于前后端数据传输是对实体类的简化只包含需要
- **ArticleDto**: 包含文章的基本信息,用于创建和更新文章
- **MessageDto**: 包含留言的基本信息,用于创建和更新留言
- **LoginRequest**: 登录请求参数
- **SignupRequest**: 注册请求参数
- **JwtResponse**: JWT认证响应
## 认证与授权
系统使用JWT (JSON Web Token) 进行身份认证。在访问需要授权的API接口时前端需要在请求头中包含有效的JWT令牌。
### 获取JWT令牌
```
POST /api/auth/signin
```
**功能**: 用户登录并获取JWT令牌
**请求体**:
```json
{
"username": "test_author",
"password": "password123"
}
```
**返回数据**:
```json
{
"code": 200,
"message": "登录成功",
"success": true,
"data": {
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"type": "Bearer",
"id": 1,
"username": "test_author",
"email": "author@example.com",
"roles": ["ROLE_AUTHOR"]
}
}
```
### 用户注册
```
POST /api/auth/signup
```
**功能**: 用户注册新账号
**请求体**:
```json
{
"username": "新用户名",
"email": "user@example.com",
"password": "密码123",
"role": "author" // 可选值: user, author, admin
}
```
## 前端调用示例
@@ -438,6 +526,14 @@ const api = axios.create({
}
});
// 认证相关API
export const authAPI = {
// 用户登录
login: (credentials) => api.post('/auth/signin', credentials),
// 用户注册
register: (userData) => api.post('/auth/signup', userData)
};
// 请求拦截器 - 添加认证token
api.interceptors.request.use(
config => {

View File

@@ -968,3 +968,297 @@ Caused by: org.hibernate.QueryException: could not resolve property: typeid of:
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.analyze(QueryTranslatorImpl.java:276)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:192)
... 91 common frames omitted
2025-10-16 16:41:18 [restartedMain] INFO c.q.m.MyAfterProjecyApplication - Starting MyAfterProjecyApplication using Java 1.8.0_461 on DESKTOP-8G5GS0I with PID 31448 (E:\MyWebProject\MyAfterProjecy\target\classes started by 30803 in E:\MyWebProject\MyAfterProjecy)
2025-10-16 16:41:18 [restartedMain] DEBUG c.q.m.MyAfterProjecyApplication - Running with Spring Boot v2.6.13, Spring v5.3.23
2025-10-16 16:41:18 [restartedMain] INFO c.q.m.MyAfterProjecyApplication - No active profile set, falling back to 1 default profile: "default"
2025-10-16 16:41:18 [restartedMain] INFO o.s.b.d.e.DevToolsPropertyDefaultsPostProcessor - Devtools property defaults active! Set 'spring.devtools.add-properties' to 'false' to disable
2025-10-16 16:41:18 [restartedMain] INFO o.s.b.d.e.DevToolsPropertyDefaultsPostProcessor - For additional web related logging consider setting the 'logging.level.web' property to 'DEBUG'
2025-10-16 16:41:18 [restartedMain] INFO o.s.d.r.c.RepositoryConfigurationDelegate - Bootstrapping Spring Data JPA repositories in DEFAULT mode.
2025-10-16 16:41:18 [restartedMain] INFO o.s.d.r.c.RepositoryConfigurationDelegate - Finished Spring Data repository scanning in 48 ms. Found 4 JPA repository interfaces.
2025-10-16 16:41:19 [restartedMain] WARN o.m.s.mapper.ClassPathMapperScanner - No MyBatis mapper was found in '[com.qf.myafterprojecy]' package. Please check your configuration.
2025-10-16 16:41:19 [restartedMain] INFO o.s.b.w.e.tomcat.TomcatWebServer - Tomcat initialized with port(s): 8080 (http)
2025-10-16 16:41:19 [restartedMain] INFO o.a.catalina.core.StandardService - Starting service [Tomcat]
2025-10-16 16:41:19 [restartedMain] INFO o.a.catalina.core.StandardEngine - Starting Servlet engine: [Apache Tomcat/9.0.68]
2025-10-16 16:41:19 [restartedMain] INFO o.a.c.c.C.[Tomcat].[localhost].[/] - Initializing Spring embedded WebApplicationContext
2025-10-16 16:41:19 [restartedMain] INFO o.s.b.w.s.c.ServletWebServerApplicationContext - Root WebApplicationContext: initialization completed in 1360 ms
2025-10-16 16:41:19 [restartedMain] INFO o.h.jpa.internal.util.LogHelper - HHH000204: Processing PersistenceUnitInfo [name: default]
2025-10-16 16:41:19 [restartedMain] INFO org.hibernate.Version - HHH000412: Hibernate ORM core version 5.6.12.Final
2025-10-16 16:41:20 [restartedMain] INFO o.h.annotations.common.Version - HCANN000001: Hibernate Commons Annotations {5.1.2.Final}
2025-10-16 16:41:20 [restartedMain] INFO com.zaxxer.hikari.HikariDataSource - WebProjectHikariCP - Starting...
2025-10-16 16:41:20 [restartedMain] INFO com.zaxxer.hikari.HikariDataSource - WebProjectHikariCP - Start completed.
2025-10-16 16:41:20 [restartedMain] INFO org.hibernate.dialect.Dialect - HHH000400: Using dialect: org.hibernate.dialect.MySQL8Dialect
2025-10-16 16:41:21 [restartedMain] INFO o.h.e.t.j.p.i.JtaPlatformInitiator - HHH000490: Using JtaPlatform implementation: [org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform]
2025-10-16 16:41:21 [restartedMain] INFO o.s.o.j.LocalContainerEntityManagerFactoryBean - Initialized JPA EntityManagerFactory for persistence unit 'default'
2025-10-16 16:41:22 [restartedMain] WARN o.s.b.a.s.s.UserDetailsServiceAutoConfiguration -
Using generated security password: e8814a4c-8fc8-484c-9843-05e3327fe275
This generated password is for development use only. Your security configuration must be updated before running your application in production.
2025-10-16 16:41:22 [restartedMain] INFO o.s.s.web.DefaultSecurityFilterChain - Will secure any request with [org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@4c6343c, org.springframework.security.web.context.SecurityContextPersistenceFilter@205a03b4, org.springframework.security.web.header.HeaderWriterFilter@5d32430e, org.springframework.security.web.authentication.logout.LogoutFilter@d7acc06, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@5c4d0c68, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@5570d9fd, org.springframework.security.web.authentication.AnonymousAuthenticationFilter@7357e1f4, org.springframework.security.web.access.ExceptionTranslationFilter@abf2f25, org.springframework.security.web.access.intercept.FilterSecurityInterceptor@7f6072c9]
2025-10-16 16:41:22 [restartedMain] INFO o.s.b.a.w.s.WelcomePageHandlerMapping - Adding welcome page: class path resource [static/index.html]
2025-10-16 16:41:23 [restartedMain] INFO o.s.b.d.a.OptionalLiveReloadServer - LiveReload server is running on port 35729
2025-10-16 16:41:23 [restartedMain] INFO o.s.b.w.e.tomcat.TomcatWebServer - Tomcat started on port(s): 8080 (http) with context path ''
2025-10-16 16:41:23 [restartedMain] INFO c.q.m.MyAfterProjecyApplication - Started MyAfterProjecyApplication in 5.335 seconds (JVM running for 6.173)
2025-10-16 16:41:23 [restartedMain] INFO c.q.m.init.CategoryDataInit - ===== 分类数据初始化开始 =====
2025-10-16 16:41:23 [restartedMain] INFO c.q.m.init.CategoryDataInit - 当前数据库中分类数量: 4
2025-10-16 16:41:23 [restartedMain] INFO c.q.m.init.CategoryDataInit - 数据库中已存在分类数据,无需初始化
2025-10-16 16:41:23 [restartedMain] INFO c.q.m.init.CategoryDataInit - ===== 分类数据初始化结束 =====
2025-10-16 16:41:23 [restartedMain] INFO c.q.m.init.MessageDataInit - ===== 消息数据初始化开始 =====
2025-10-16 16:41:23 [restartedMain] INFO c.q.m.init.MessageDataInit - 当前数据库中消息数量: 6
2025-10-16 16:41:23 [restartedMain] INFO c.q.m.init.MessageDataInit - 数据库中已存在消息数据,无需初始化
2025-10-16 16:41:23 [restartedMain] INFO c.q.m.init.MessageDataInit - ===== 消息数据初始化结束 =====
2025-10-16 16:41:23 [restartedMain] INFO c.q.m.runner.MessageDataChecker - ===== 消息数据检查器开始运行 =====
2025-10-16 16:41:23 [restartedMain] INFO c.q.m.runner.MessageDataChecker - 当前数据库中消息数量: 6
2025-10-16 16:41:23 [restartedMain] INFO c.q.m.runner.MessageDataChecker - ===== 测试Repository查询方法 =====
2025-10-16 16:41:23 [restartedMain] TRACE o.h.type.descriptor.sql.BasicBinder - binding parameter [1] as [INTEGER] - [1]
2025-10-16 16:41:23 [restartedMain] INFO c.q.m.runner.MessageDataChecker - 文章ID为1的消息数量: 0
2025-10-16 16:41:23 [restartedMain] INFO c.q.m.runner.MessageDataChecker - 根消息数量: 3
2025-10-16 16:41:23 [restartedMain] TRACE o.h.type.descriptor.sql.BasicBinder - binding parameter [1] as [VARCHAR] - [%张%]
2025-10-16 16:41:23 [restartedMain] TRACE o.h.type.descriptor.sql.BasicBinder - binding parameter [2] as [CHAR] - [\]
2025-10-16 16:41:23 [restartedMain] INFO c.q.m.runner.MessageDataChecker - 昵称包含'张'的消息数量: 1
2025-10-16 16:41:23 [restartedMain] TRACE o.h.type.descriptor.sql.BasicBinder - binding parameter [1] as [INTEGER] - [1]
2025-10-16 16:41:23 [restartedMain] INFO c.q.m.runner.MessageDataChecker - 文章ID为1的评论数量: 0
2025-10-16 16:41:23 [restartedMain] TRACE o.h.type.descriptor.sql.BasicBinder - binding parameter [1] as [INTEGER] - [1]
2025-10-16 16:41:23 [restartedMain] INFO c.q.m.runner.MessageDataChecker - 消息ID为1的回复数量: 1
2025-10-16 16:41:23 [restartedMain] INFO c.q.m.runner.MessageDataChecker - ===== 测试Service层方法 =====
2025-10-16 16:41:23 [restartedMain] INFO c.q.m.service.MessageService - 查询所有消息
2025-10-16 16:41:23 [restartedMain] INFO c.q.m.runner.MessageDataChecker - 获取所有消息: 成功=true, 消息数量=6
2025-10-16 16:41:23 [restartedMain] INFO c.q.m.service.MessageService - 根据ID查询消息: 1
2025-10-16 16:41:23 [restartedMain] TRACE o.h.type.descriptor.sql.BasicBinder - binding parameter [1] as [INTEGER] - [1]
2025-10-16 16:41:23 [restartedMain] INFO c.q.m.runner.MessageDataChecker - 根据ID1获取消息: 成功=true, 昵称=张三
2025-10-16 16:41:23 [restartedMain] INFO c.q.m.service.MessageService - 获取文章评论数量: 1
2025-10-16 16:41:23 [restartedMain] TRACE o.h.type.descriptor.sql.BasicBinder - binding parameter [1] as [INTEGER] - [1]
2025-10-16 16:41:23 [restartedMain] INFO c.q.m.runner.MessageDataChecker - 获取文章ID为1的评论数量: 成功=true, 数量=0
2025-10-16 16:41:23 [restartedMain] INFO c.q.m.service.MessageService - 查询所有根消息
2025-10-16 16:41:23 [restartedMain] INFO c.q.m.runner.MessageDataChecker - 获取根消息: 成功=true, 数量=3
2025-10-16 16:41:23 [restartedMain] INFO c.q.m.service.MessageService - 保存消息: 测试用户
2025-10-16 16:41:23 [restartedMain] TRACE o.h.type.descriptor.sql.BasicBinder - binding parameter [1] as [INTEGER] - [1]
2025-10-16 16:41:23 [restartedMain] TRACE o.h.type.descriptor.sql.BasicBinder - binding parameter [2] as [VARCHAR] - [这是一条测试消息]
2025-10-16 16:41:23 [restartedMain] TRACE o.h.type.descriptor.sql.BasicBinder - binding parameter [3] as [TIMESTAMP] - [Thu Oct 16 16:41:23 CST 2025]
2025-10-16 16:41:23 [restartedMain] TRACE o.h.type.descriptor.sql.BasicBinder - binding parameter [4] as [VARCHAR] - [test@example.com]
2025-10-16 16:41:23 [restartedMain] TRACE o.h.type.descriptor.sql.BasicBinder - binding parameter [5] as [VARCHAR] - [测试用户]
2025-10-16 16:41:23 [restartedMain] TRACE o.h.type.descriptor.sql.BasicBinder - binding parameter [6] as [INTEGER] - [null]
2025-10-16 16:41:23 [restartedMain] INFO c.q.m.service.MessageService - 消息保存成功: 53
2025-10-16 16:41:23 [restartedMain] INFO c.q.m.runner.MessageDataChecker - 保存新消息: 成功=true, 消息ID=53
2025-10-16 16:41:23 [restartedMain] INFO c.q.m.service.MessageService - 删除消息: 53
2025-10-16 16:41:23 [restartedMain] TRACE o.h.type.descriptor.sql.BasicBinder - binding parameter [1] as [INTEGER] - [53]
2025-10-16 16:41:23 [restartedMain] TRACE o.h.type.descriptor.sql.BasicBinder - binding parameter [1] as [INTEGER] - [53]
2025-10-16 16:41:23 [restartedMain] TRACE o.h.type.descriptor.sql.BasicBinder - binding parameter [1] as [INTEGER] - [53]
2025-10-16 16:41:23 [restartedMain] TRACE o.h.type.descriptor.sql.BasicBinder - binding parameter [1] as [INTEGER] - [53]
2025-10-16 16:41:23 [restartedMain] INFO c.q.m.service.MessageService - 消息删除成功: 53
2025-10-16 16:41:23 [restartedMain] INFO c.q.m.runner.MessageDataChecker - 删除消息ID53: 成功=true
2025-10-16 16:41:23 [restartedMain] INFO c.q.m.runner.MessageDataChecker - ===== 消息数据检查器运行结束 =====
2025-10-16 16:41:30 [File Watcher] INFO o.s.b.d.a.LocalDevToolsAutoConfiguration$RestartingClassPathChangeChangedEventListener - Restarting due to 33 class path changes (0 additions, 33 deletions, 0 modifications)
2025-10-16 16:41:30 [Thread-16] INFO o.a.catalina.core.StandardService - Stopping service [Tomcat]
2025-10-16 16:41:30 [Thread-16] INFO o.s.o.j.LocalContainerEntityManagerFactoryBean - Closing JPA EntityManagerFactory for persistence unit 'default'
2025-10-16 16:41:30 [Thread-16] INFO com.zaxxer.hikari.HikariDataSource - WebProjectHikariCP - Shutdown initiated...
2025-10-16 16:41:30 [Thread-16] INFO com.zaxxer.hikari.HikariDataSource - WebProjectHikariCP - Shutdown completed.
2025-10-16 16:41:31 [restartedMain] INFO c.q.m.MyAfterProjecyApplication - Starting MyAfterProjecyApplication using Java 1.8.0_461 on DESKTOP-8G5GS0I with PID 31448 (E:\MyWebProject\MyAfterProjecy\target\classes started by 30803 in E:\MyWebProject\MyAfterProjecy)
2025-10-16 16:41:31 [restartedMain] DEBUG c.q.m.MyAfterProjecyApplication - Running with Spring Boot v2.6.13, Spring v5.3.23
2025-10-16 16:41:31 [restartedMain] INFO c.q.m.MyAfterProjecyApplication - No active profile set, falling back to 1 default profile: "default"
2025-10-16 16:41:31 [restartedMain] INFO o.s.d.r.c.RepositoryConfigurationDelegate - Bootstrapping Spring Data JPA repositories in DEFAULT mode.
2025-10-16 16:41:31 [restartedMain] INFO o.s.d.r.c.RepositoryConfigurationDelegate - Finished Spring Data repository scanning in 0 ms. Found 0 JPA repository interfaces.
2025-10-16 16:41:31 [restartedMain] WARN o.m.s.mapper.ClassPathMapperScanner - No MyBatis mapper was found in '[com.qf.myafterprojecy]' package. Please check your configuration.
2025-10-16 16:41:31 [restartedMain] INFO o.s.b.w.e.tomcat.TomcatWebServer - Tomcat initialized with port(s): 8080 (http)
2025-10-16 16:41:31 [restartedMain] INFO o.a.catalina.core.StandardService - Starting service [Tomcat]
2025-10-16 16:41:31 [restartedMain] INFO o.a.catalina.core.StandardEngine - Starting Servlet engine: [Apache Tomcat/9.0.68]
2025-10-16 16:41:31 [restartedMain] INFO o.a.c.c.C.[Tomcat].[localhost].[/] - Initializing Spring embedded WebApplicationContext
2025-10-16 16:41:31 [restartedMain] INFO o.s.b.w.s.c.ServletWebServerApplicationContext - Root WebApplicationContext: initialization completed in 241 ms
2025-10-16 16:41:31 [restartedMain] INFO o.h.jpa.internal.util.LogHelper - HHH000204: Processing PersistenceUnitInfo [name: default]
2025-10-16 16:41:31 [restartedMain] INFO com.zaxxer.hikari.HikariDataSource - WebProjectHikariCP - Starting...
2025-10-16 16:41:31 [restartedMain] INFO com.zaxxer.hikari.HikariDataSource - WebProjectHikariCP - Start completed.
2025-10-16 16:41:31 [restartedMain] INFO org.hibernate.dialect.Dialect - HHH000400: Using dialect: org.hibernate.dialect.MySQL8Dialect
2025-10-16 16:41:31 [restartedMain] INFO o.h.e.t.j.p.i.JtaPlatformInitiator - HHH000490: Using JtaPlatform implementation: [org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform]
2025-10-16 16:41:31 [restartedMain] INFO o.s.o.j.LocalContainerEntityManagerFactoryBean - Initialized JPA EntityManagerFactory for persistence unit 'default'
2025-10-16 16:41:31 [restartedMain] INFO o.s.b.a.w.s.WelcomePageHandlerMapping - Adding welcome page: class path resource [static/index.html]
2025-10-16 16:41:31 [restartedMain] WARN o.s.b.a.s.s.UserDetailsServiceAutoConfiguration -
Using generated security password: fb20fba2-55fa-48c2-932e-95c944238d5a
This generated password is for development use only. Your security configuration must be updated before running your application in production.
2025-10-16 16:41:31 [restartedMain] INFO o.s.s.web.DefaultSecurityFilterChain - Will secure any request with [org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@40f82067, org.springframework.security.web.context.SecurityContextPersistenceFilter@3ba61976, org.springframework.security.web.header.HeaderWriterFilter@b1983a, org.springframework.security.web.csrf.CsrfFilter@3f7f7a19, org.springframework.security.web.authentication.logout.LogoutFilter@2e443beb, org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter@4d7f7722, org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter@7516f6de, org.springframework.security.web.authentication.ui.DefaultLogoutPageGeneratingFilter@3877416a, org.springframework.security.web.authentication.www.BasicAuthenticationFilter@31fbbdb0, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@6e69e0ac, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@6215d513, org.springframework.security.web.authentication.AnonymousAuthenticationFilter@393c1971, org.springframework.security.web.session.SessionManagementFilter@7f4d1b34, org.springframework.security.web.access.ExceptionTranslationFilter@1438245a, org.springframework.security.web.access.intercept.FilterSecurityInterceptor@47b6baf7]
2025-10-16 16:41:31 [restartedMain] INFO o.s.b.d.a.OptionalLiveReloadServer - LiveReload server is running on port 35729
2025-10-16 16:41:31 [restartedMain] INFO o.s.b.w.e.tomcat.TomcatWebServer - Tomcat started on port(s): 8080 (http) with context path ''
2025-10-16 16:41:31 [restartedMain] INFO c.q.m.MyAfterProjecyApplication - Started MyAfterProjecyApplication in 0.437 seconds (JVM running for 14.391)
2025-10-16 16:41:31 [restartedMain] INFO o.s.b.d.a.ConditionEvaluationDeltaLoggingListener - Condition evaluation delta:
==========================
CONDITION EVALUATION DELTA
==========================
Positive matches:
-----------------
SpringBootWebSecurityConfiguration matched:
- found 'session' scope (OnWebApplicationCondition)
- AllNestedConditions 2 matched 0 did not; NestedCondition on DefaultWebSecurityCondition.Beans @ConditionalOnMissingBean (types: org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter,org.springframework.security.web.SecurityFilterChain; SearchStrategy: all) did not find any beans; NestedCondition on DefaultWebSecurityCondition.Classes @ConditionalOnClass found required classes 'org.springframework.security.web.SecurityFilterChain', 'org.springframework.security.config.annotation.web.builders.HttpSecurity' (DefaultWebSecurityCondition)
WebSecurityEnablerConfiguration matched:
- @ConditionalOnClass found required class 'org.springframework.security.config.annotation.web.configuration.EnableWebSecurity' (OnClassCondition)
- found 'session' scope (OnWebApplicationCondition)
- @ConditionalOnMissingBean (names: springSecurityFilterChain; SearchStrategy: all) did not find any beans (OnBeanCondition)
Negative matches:
-----------------
None
Exclusions:
-----------
None
Unconditional classes:
----------------------
None
2025-10-16 16:41:33 [File Watcher] INFO o.s.b.d.a.LocalDevToolsAutoConfiguration$RestartingClassPathChangeChangedEventListener - Restarting due to 33 class path changes (33 additions, 0 deletions, 0 modifications)
2025-10-16 16:41:33 [Thread-22] INFO o.a.catalina.core.StandardService - Stopping service [Tomcat]
2025-10-16 16:41:34 [Thread-22] INFO o.s.o.j.LocalContainerEntityManagerFactoryBean - Closing JPA EntityManagerFactory for persistence unit 'default'
2025-10-16 16:41:34 [Thread-22] INFO com.zaxxer.hikari.HikariDataSource - WebProjectHikariCP - Shutdown initiated...
2025-10-16 16:41:34 [Thread-22] INFO com.zaxxer.hikari.HikariDataSource - WebProjectHikariCP - Shutdown completed.
2025-10-16 16:41:34 [restartedMain] INFO c.q.m.MyAfterProjecyApplication - Starting MyAfterProjecyApplication using Java 1.8.0_461 on DESKTOP-8G5GS0I with PID 31448 (E:\MyWebProject\MyAfterProjecy\target\classes started by 30803 in E:\MyWebProject\MyAfterProjecy)
2025-10-16 16:41:34 [restartedMain] DEBUG c.q.m.MyAfterProjecyApplication - Running with Spring Boot v2.6.13, Spring v5.3.23
2025-10-16 16:41:34 [restartedMain] INFO c.q.m.MyAfterProjecyApplication - No active profile set, falling back to 1 default profile: "default"
2025-10-16 16:41:34 [restartedMain] INFO o.s.d.r.c.RepositoryConfigurationDelegate - Bootstrapping Spring Data JPA repositories in DEFAULT mode.
2025-10-16 16:41:34 [restartedMain] INFO o.s.d.r.c.RepositoryConfigurationDelegate - Finished Spring Data repository scanning in 15 ms. Found 4 JPA repository interfaces.
2025-10-16 16:41:34 [restartedMain] WARN o.m.s.mapper.ClassPathMapperScanner - No MyBatis mapper was found in '[com.qf.myafterprojecy]' package. Please check your configuration.
2025-10-16 16:41:34 [restartedMain] INFO o.s.b.w.e.tomcat.TomcatWebServer - Tomcat initialized with port(s): 8080 (http)
2025-10-16 16:41:34 [restartedMain] INFO o.a.catalina.core.StandardService - Starting service [Tomcat]
2025-10-16 16:41:34 [restartedMain] INFO o.a.catalina.core.StandardEngine - Starting Servlet engine: [Apache Tomcat/9.0.68]
2025-10-16 16:41:34 [restartedMain] INFO o.a.c.c.C.[Tomcat].[localhost].[/] - Initializing Spring embedded WebApplicationContext
2025-10-16 16:41:34 [restartedMain] INFO o.s.b.w.s.c.ServletWebServerApplicationContext - Root WebApplicationContext: initialization completed in 268 ms
2025-10-16 16:41:34 [restartedMain] INFO o.h.jpa.internal.util.LogHelper - HHH000204: Processing PersistenceUnitInfo [name: default]
2025-10-16 16:41:34 [restartedMain] INFO com.zaxxer.hikari.HikariDataSource - WebProjectHikariCP - Starting...
2025-10-16 16:41:34 [restartedMain] INFO com.zaxxer.hikari.HikariDataSource - WebProjectHikariCP - Start completed.
2025-10-16 16:41:34 [restartedMain] INFO org.hibernate.dialect.Dialect - HHH000400: Using dialect: org.hibernate.dialect.MySQL8Dialect
2025-10-16 16:41:34 [restartedMain] INFO o.h.e.t.j.p.i.JtaPlatformInitiator - HHH000490: Using JtaPlatform implementation: [org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform]
2025-10-16 16:41:34 [restartedMain] INFO o.s.o.j.LocalContainerEntityManagerFactoryBean - Initialized JPA EntityManagerFactory for persistence unit 'default'
2025-10-16 16:41:34 [restartedMain] WARN o.s.b.a.s.s.UserDetailsServiceAutoConfiguration -
Using generated security password: e4f76c3b-a578-4993-8c06-099ca64aac88
This generated password is for development use only. Your security configuration must be updated before running your application in production.
2025-10-16 16:41:34 [restartedMain] INFO o.s.s.web.DefaultSecurityFilterChain - Will secure any request with [org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@61e1947f, org.springframework.security.web.context.SecurityContextPersistenceFilter@43665935, org.springframework.security.web.header.HeaderWriterFilter@12df53fc, org.springframework.security.web.authentication.logout.LogoutFilter@da58f5f, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@3c3161c5, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@14532fd1, org.springframework.security.web.authentication.AnonymousAuthenticationFilter@3d9a6a52, org.springframework.security.web.access.ExceptionTranslationFilter@3c129b01, org.springframework.security.web.access.intercept.FilterSecurityInterceptor@34da3c43]
2025-10-16 16:41:34 [restartedMain] INFO o.s.b.a.w.s.WelcomePageHandlerMapping - Adding welcome page: class path resource [static/index.html]
2025-10-16 16:41:34 [restartedMain] INFO o.s.b.d.a.OptionalLiveReloadServer - LiveReload server is running on port 35729
2025-10-16 16:41:34 [restartedMain] INFO o.s.b.w.e.tomcat.TomcatWebServer - Tomcat started on port(s): 8080 (http) with context path ''
2025-10-16 16:41:34 [restartedMain] INFO c.q.m.MyAfterProjecyApplication - Started MyAfterProjecyApplication in 0.706 seconds (JVM running for 17.767)
2025-10-16 16:41:34 [restartedMain] INFO c.q.m.init.CategoryDataInit - ===== 分类数据初始化开始 =====
2025-10-16 16:41:34 [restartedMain] INFO c.q.m.init.CategoryDataInit - 当前数据库中分类数量: 4
2025-10-16 16:41:34 [restartedMain] INFO c.q.m.init.CategoryDataInit - 数据库中已存在分类数据,无需初始化
2025-10-16 16:41:34 [restartedMain] INFO c.q.m.init.CategoryDataInit - ===== 分类数据初始化结束 =====
2025-10-16 16:41:34 [restartedMain] INFO c.q.m.init.MessageDataInit - ===== 消息数据初始化开始 =====
2025-10-16 16:41:34 [restartedMain] INFO c.q.m.init.MessageDataInit - 当前数据库中消息数量: 6
2025-10-16 16:41:34 [restartedMain] INFO c.q.m.init.MessageDataInit - 数据库中已存在消息数据,无需初始化
2025-10-16 16:41:34 [restartedMain] INFO c.q.m.init.MessageDataInit - ===== 消息数据初始化结束 =====
2025-10-16 16:41:34 [restartedMain] INFO c.q.m.runner.MessageDataChecker - ===== 消息数据检查器开始运行 =====
2025-10-16 16:41:34 [restartedMain] INFO c.q.m.runner.MessageDataChecker - 当前数据库中消息数量: 6
2025-10-16 16:41:34 [restartedMain] INFO c.q.m.runner.MessageDataChecker - ===== 测试Repository查询方法 =====
2025-10-16 16:41:34 [restartedMain] TRACE o.h.type.descriptor.sql.BasicBinder - binding parameter [1] as [INTEGER] - [1]
2025-10-16 16:41:34 [restartedMain] INFO c.q.m.runner.MessageDataChecker - 文章ID为1的消息数量: 0
2025-10-16 16:41:34 [restartedMain] INFO c.q.m.runner.MessageDataChecker - 根消息数量: 3
2025-10-16 16:41:34 [restartedMain] TRACE o.h.type.descriptor.sql.BasicBinder - binding parameter [1] as [VARCHAR] - [%张%]
2025-10-16 16:41:34 [restartedMain] TRACE o.h.type.descriptor.sql.BasicBinder - binding parameter [2] as [CHAR] - [\]
2025-10-16 16:41:34 [restartedMain] INFO c.q.m.runner.MessageDataChecker - 昵称包含'张'的消息数量: 1
2025-10-16 16:41:34 [restartedMain] TRACE o.h.type.descriptor.sql.BasicBinder - binding parameter [1] as [INTEGER] - [1]
2025-10-16 16:41:34 [restartedMain] INFO c.q.m.runner.MessageDataChecker - 文章ID为1的评论数量: 0
2025-10-16 16:41:34 [restartedMain] TRACE o.h.type.descriptor.sql.BasicBinder - binding parameter [1] as [INTEGER] - [1]
2025-10-16 16:41:34 [restartedMain] INFO c.q.m.runner.MessageDataChecker - 消息ID为1的回复数量: 1
2025-10-16 16:41:34 [restartedMain] INFO c.q.m.runner.MessageDataChecker - ===== 测试Service层方法 =====
2025-10-16 16:41:34 [restartedMain] INFO c.q.m.service.MessageService - 查询所有消息
2025-10-16 16:41:34 [restartedMain] INFO c.q.m.runner.MessageDataChecker - 获取所有消息: 成功=true, 消息数量=6
2025-10-16 16:41:34 [restartedMain] INFO c.q.m.service.MessageService - 根据ID查询消息: 1
2025-10-16 16:41:34 [restartedMain] TRACE o.h.type.descriptor.sql.BasicBinder - binding parameter [1] as [INTEGER] - [1]
2025-10-16 16:41:34 [restartedMain] INFO c.q.m.runner.MessageDataChecker - 根据ID1获取消息: 成功=true, 昵称=张三
2025-10-16 16:41:34 [restartedMain] INFO c.q.m.service.MessageService - 获取文章评论数量: 1
2025-10-16 16:41:34 [restartedMain] TRACE o.h.type.descriptor.sql.BasicBinder - binding parameter [1] as [INTEGER] - [1]
2025-10-16 16:41:34 [restartedMain] INFO c.q.m.runner.MessageDataChecker - 获取文章ID为1的评论数量: 成功=true, 数量=0
2025-10-16 16:41:34 [restartedMain] INFO c.q.m.service.MessageService - 查询所有根消息
2025-10-16 16:41:34 [restartedMain] INFO c.q.m.runner.MessageDataChecker - 获取根消息: 成功=true, 数量=3
2025-10-16 16:41:34 [restartedMain] INFO c.q.m.service.MessageService - 保存消息: 测试用户
2025-10-16 16:41:34 [restartedMain] TRACE o.h.type.descriptor.sql.BasicBinder - binding parameter [1] as [INTEGER] - [1]
2025-10-16 16:41:34 [restartedMain] TRACE o.h.type.descriptor.sql.BasicBinder - binding parameter [2] as [VARCHAR] - [这是一条测试消息]
2025-10-16 16:41:34 [restartedMain] TRACE o.h.type.descriptor.sql.BasicBinder - binding parameter [3] as [TIMESTAMP] - [Thu Oct 16 16:41:34 CST 2025]
2025-10-16 16:41:34 [restartedMain] TRACE o.h.type.descriptor.sql.BasicBinder - binding parameter [4] as [VARCHAR] - [test@example.com]
2025-10-16 16:41:34 [restartedMain] TRACE o.h.type.descriptor.sql.BasicBinder - binding parameter [5] as [VARCHAR] - [测试用户]
2025-10-16 16:41:34 [restartedMain] TRACE o.h.type.descriptor.sql.BasicBinder - binding parameter [6] as [INTEGER] - [null]
2025-10-16 16:41:34 [restartedMain] INFO c.q.m.service.MessageService - 消息保存成功: 54
2025-10-16 16:41:34 [restartedMain] INFO c.q.m.runner.MessageDataChecker - 保存新消息: 成功=true, 消息ID=54
2025-10-16 16:41:34 [restartedMain] INFO c.q.m.service.MessageService - 删除消息: 54
2025-10-16 16:41:34 [restartedMain] TRACE o.h.type.descriptor.sql.BasicBinder - binding parameter [1] as [INTEGER] - [54]
2025-10-16 16:41:34 [restartedMain] TRACE o.h.type.descriptor.sql.BasicBinder - binding parameter [1] as [INTEGER] - [54]
2025-10-16 16:41:34 [restartedMain] TRACE o.h.type.descriptor.sql.BasicBinder - binding parameter [1] as [INTEGER] - [54]
2025-10-16 16:41:34 [restartedMain] TRACE o.h.type.descriptor.sql.BasicBinder - binding parameter [1] as [INTEGER] - [54]
2025-10-16 16:41:34 [restartedMain] INFO c.q.m.service.MessageService - 消息删除成功: 54
2025-10-16 16:41:34 [restartedMain] INFO c.q.m.runner.MessageDataChecker - 删除消息ID54: 成功=true
2025-10-16 16:41:34 [restartedMain] INFO c.q.m.runner.MessageDataChecker - ===== 消息数据检查器运行结束 =====
2025-10-16 16:41:34 [restartedMain] INFO o.s.b.d.a.ConditionEvaluationDeltaLoggingListener - Condition evaluation delta:
==========================
CONDITION EVALUATION DELTA
==========================
Positive matches:
-----------------
None
Negative matches:
-----------------
SpringBootWebSecurityConfiguration:
Did not match:
- AllNestedConditions 1 matched 1 did not; NestedCondition on DefaultWebSecurityCondition.Beans @ConditionalOnMissingBean (types: org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter,org.springframework.security.web.SecurityFilterChain; SearchStrategy: all) found beans of type 'org.springframework.security.web.SecurityFilterChain' filterChain; NestedCondition on DefaultWebSecurityCondition.Classes @ConditionalOnClass found required classes 'org.springframework.security.web.SecurityFilterChain', 'org.springframework.security.config.annotation.web.builders.HttpSecurity' (DefaultWebSecurityCondition)
Matched:
- found 'session' scope (OnWebApplicationCondition)
WebSecurityEnablerConfiguration:
Did not match:
- @ConditionalOnMissingBean (names: springSecurityFilterChain; SearchStrategy: all) found beans named springSecurityFilterChain (OnBeanCondition)
Matched:
- @ConditionalOnClass found required class 'org.springframework.security.config.annotation.web.configuration.EnableWebSecurity' (OnClassCondition)
- found 'session' scope (OnWebApplicationCondition)
Exclusions:
-----------
None
Unconditional classes:
----------------------
None
2025-10-16 16:41:40 [http-nio-8080-exec-2] INFO o.a.c.c.C.[Tomcat].[localhost].[/] - Initializing Spring DispatcherServlet 'dispatcherServlet'
2025-10-16 16:41:40 [http-nio-8080-exec-2] INFO o.s.web.servlet.DispatcherServlet - Initializing Servlet 'dispatcherServlet'
2025-10-16 16:41:40 [http-nio-8080-exec-2] INFO o.s.web.servlet.DispatcherServlet - Completed initialization in 1 ms
2025-10-16 16:43:14 [http-nio-8080-exec-8] ERROR c.q.m.service.ArticleService - 获取文章失败: For input string: "title"
2025-10-16 16:43:37 [http-nio-8080-exec-9] ERROR c.q.m.service.ArticleService - 获取文章失败: For input string: "title"
2025-10-16 16:43:46 [http-nio-8080-exec-10] TRACE o.h.type.descriptor.sql.BasicBinder - binding parameter [1] as [VARCHAR] - [%1%]
2025-10-16 16:44:00 [http-nio-8080-exec-1] TRACE o.h.type.descriptor.sql.BasicBinder - binding parameter [1] as [VARCHAR] - [%2%]
2025-10-16 16:47:16 [http-nio-8080-exec-3] INFO c.q.m.controller.MessageController - 接收获取所有消息的请求
2025-10-16 16:47:16 [http-nio-8080-exec-3] INFO c.q.m.service.MessageService - 查询所有消息
2025-10-16 16:47:28 [http-nio-8080-exec-4] INFO c.q.m.controller.MessageController - 接收获取所有消息的请求
2025-10-16 16:47:28 [http-nio-8080-exec-4] INFO c.q.m.service.MessageService - 查询所有消息
2025-10-16 17:07:29 [SpringApplicationShutdownHook] INFO o.s.o.j.LocalContainerEntityManagerFactoryBean - Closing JPA EntityManagerFactory for persistence unit 'default'
2025-10-16 17:07:29 [SpringApplicationShutdownHook] INFO com.zaxxer.hikari.HikariDataSource - WebProjectHikariCP - Shutdown initiated...
2025-10-16 17:07:29 [SpringApplicationShutdownHook] INFO com.zaxxer.hikari.HikariDataSource - WebProjectHikariCP - Shutdown completed.

View File

@@ -1,6 +1,5 @@
package com.qf.myafterprojecy;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

View File

@@ -52,6 +52,47 @@ public class ArticleController {
return articleService.getArticlesByTitle(title);
}
/**
* 根据属性ID获取该属性下的所有文章
* @param attributeId 属性ID
* @return 返回包含文章列表的ResponseMessage对象
*/
@GetMapping("/attribute/{attributeId}")
public ResponseMessage<List<Article>> getArticlesByAttribute(@PathVariable Integer attributeId) {
return articleService.getArticlesByAttribute(attributeId);
}
/**
* 根据分类ID获取该分类下的所有文章兼容旧接口
* @param categoryId 分类ID
* @return 返回包含文章列表的ResponseMessage对象
*/
@GetMapping("/category/{categoryId}")
public ResponseMessage<List<Article>> getArticlesByCategory(@PathVariable Integer categoryId) {
return articleService.getArticlesByCategory(categoryId);
}
/**
* 根据属性ID获取最新文章按创建时间降序
* @param attributeId 属性ID
* @return 返回包含最新文章列表的ResponseMessage对象
*/
@GetMapping("/attribute/{attributeId}/latest")
public ResponseMessage<List<Article>> getLatestArticlesByAttribute(@PathVariable Integer attributeId) {
return articleService.getLatestArticlesByAttribute(attributeId);
}
/**
*
* @return ar
*/
/**
* 获取浏览量最高的文章列表
* @return 返回包含热门文章列表的ResponseMessage对象
*/
@GetMapping("/popular")
public ResponseMessage<List<Article>> getMostViewedArticles() {
return articleService.getMostViewedArticles();
}
/**
* 创建新文章
* 仅限AUTHOR角色用户访问
@@ -91,43 +132,4 @@ public class ArticleController {
return articleService.deleteArticle(id);
}
/**
* 根据分类ID获取该分类下的所有文章兼容旧接口
* @param categoryId 分类ID
* @return 返回包含文章列表的ResponseMessage对象
*/
@GetMapping("/category/{categoryId}")
public ResponseMessage<List<Article>> getArticlesByCategory(@PathVariable Integer categoryId) {
return articleService.getArticlesByCategory(categoryId);
}
/**
* 根据属性ID获取该属性下的所有文章
* @param attributeId 属性ID
* @return 返回包含文章列表的ResponseMessage对象
*/
@GetMapping("/attribute/{attributeId}")
public ResponseMessage<List<Article>> getArticlesByAttribute(@PathVariable Integer attributeId) {
return articleService.getArticlesByAttribute(attributeId);
}
/**
* 根据属性ID获取最新文章按创建时间降序
* @param attributeId 属性ID
* @return 返回包含最新文章列表的ResponseMessage对象
*/
@GetMapping("/attribute/{attributeId}/latest")
public ResponseMessage<List<Article>> getLatestArticlesByAttribute(@PathVariable Integer attributeId) {
return articleService.getLatestArticlesByAttribute(attributeId);
}
/**
* 获取浏览量最高的文章列表
* @return 返回包含热门文章列表的ResponseMessage对象
*/
@GetMapping("/popular")
public ResponseMessage<List<Article>> getMostViewedArticles() {
return articleService.getMostViewedArticles();
}
}

View File

@@ -34,6 +34,7 @@ public class CategoryAttributeController {
return categoryAttributeService.getCategoryAttributeById(id);
}
/**
* 根据分类ID获取属性列表
* @param categoryId 分类ID

View File

@@ -22,7 +22,7 @@ public class Article {
private String content;
@NotNull(message = "类别id不能为空")
@Column(name = "attributeid")
@Column(name = "attribute_id")
private Integer attributeid;
@Column(name = "img")

View File

@@ -15,6 +15,9 @@ public class ArticleDto {
@NotBlank(message = "内容不能为空")
private String content;
@NotNull(message = "属性ID不能为空")
private Integer attributeid;
private String img;
private Integer status;

View File

@@ -14,6 +14,7 @@ public interface CategoryRepository extends JpaRepository<Category, Integer> {
* @param typename 分类名称
* @return 返回符合条件的分类列表
*/
List<Category> findByTypenameContaining(String typename);
/**