启动项目前应该先配置好环境。
该说明只是大体总结需要配置的地方,详细环境需结合 day01-环境搭建-讲义 进行配置。
基础软件准备
- JDK11(我使用的是JDK17可行,JDK23不可行)
- MySQL8
- Redis >= 3.0
- 在config中配置密码后启动。注意:运行项目的全程不能关闭Redis服务。
- Maven >= 3.3
- Nginx 启动
配置文件:zzyl-web/src/main/resources/application.yml,本仓库中不含该文件,需要自行创建并配置。
- 数据源(MySQL)配置
username和password与自己的数据库账号密码对应。 - Redis的
port和password和自己配置的对应。 - 在阿里云OSS中创建一个自己的bucket并获得
AccessKeyId、AccessKeyValue、bucketName和endpoint,替换掉原来的四项。将权限设置为公共读。
将MySQL数据表创建完毕并插入数据。
在数据库查询控制台中执行以下语句:
# 开发环境暂时打开,生产环境应该关闭它
set global sql_mode=(select replace(@@sql_mode,'ONLY_FULL_GROUP_BY',''));执行完毕之后便可以进行登录操作,否则会报错。
小程序端:
将自己的微信小程序的AppID和AppSecret配置到application.yml中对应的位置,否则小程序端无法登录。
以上内容配置完毕后可以尝试进入项目( http://localhost:9090 )。
注意:以上所有提到的地方都需要认真检查,有步骤没有执行一定会产生BUG。
如果还产生了其它BUG,可以询问AI。
本项目经过实测可以完整运行,包括Web端和小程序端。未发现功能bug(某bug可以通过刷新消除),如果你有发现bug,欢迎提交PR。
Warning
以下内容来自AI生成,仅供参考。
说明:这是一个基于 Spring Boot 的企业级多模块后端项目,模块划分合理,包含基础库(common)、服务层(service)、安全模块(security)和 Web 可执行模块(web)。下面将对项目结构、重要模块与常见流程(如登录鉴权)进行简明易懂的说明,并给出若干代码片段以帮助快速理解实现要点。
- 项目概览
- 技术栈:Java 11, Spring Boot 2.7.x, MyBatis, Spring Security, Redis, Druid, JWT, Lombok, Hutool
- 模块:
zzyl-common:公共实体、VO、工具类、属性类等通用代码。zzyl-service:业务实现(service 层)的模块。zzyl-security:与身份认证、授权、资源管理有关的模块(包含 Controller、Service、Mapper 等)。zzyl-web:Spring Boot 可执行应用,依赖 service 模块并包含配置(application.yml)。
- 典型运行与配置点
-
入口类(
zzyl-web模块)-
关键位置:
com.zzyl.ZzylApplication -
作用:Spring Boot 启动类,负责启动 Spring 容器。
-
相关片段:
public static void main(String[] args) { SpringApplication.run(ZzylApplication.class, args); }
-
-
配置文件:
zzyl-web/src/main/resources/application.yml-
包含服务端口(默认 9995)、数据源(Druid/MySQL)、Redis、JWT/OSS 等配置。
-
重要段落示例(摘录):
server:
port: 9995spring:
datasource:
druid:
url: jdbc:mysql://localhost:3306/sz-zzyl?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai username: root password: heima123zzyl:
framework:
jwt:
base64-encoded-secret-key: $2a$10$PVtHn...
ttl: 3600000
-
- 登录鉴权流程(高层次)
-
概述:前端调用安全模块的登录接口(
/security/login),后端使用 Spring Security 的AuthenticationManager进行认证,成功后生成 JWT 返回,并把用户可访问的 URL 列表存入 Redis 作为授权参考。 -
控制器层(摘录):
@PostMapping("/login") public ResponseResult login(@RequestBody LoginDto loginDto){ UserVo userVo = loginService.login(loginDto); return ResponseResult.success(userVo); }
-
服务实现要点(摘录自
LoginServiceImpl):-
使用
UsernamePasswordAuthenticationToken与authenticationManager.authenticate(...)发起认证。 -
将认证通过后的
UserAuth(实现了UserDetails)转换为UserVo,设置用户 token:// 创建token String token = JwtUtil.createJWT(secretKey, ttl, claims);
-
将用户可访问的 resource paths 与白名单合并后存入 Redis:
redisTemplate.opsForValue().set(CacheConstants.PUBLIC_ACCESS_URLS + userVo.getId(), jsonUrlList, ttl, TimeUnit.SECONDS);
-
- 关键类说明(简要)
-
UserAuth(位于zzyl-common):实现 Spring Security 的UserDetails,携带用户信息与权限(roles),用于框架认证的 principal。关键方法:@Override public Collection<? extends GrantedAuthority> getAuthorities() { return authorities.stream().map(role -> new SimpleGrantedAuthority("ROLE_" + role)).collect(Collectors.toList()); }
-
JwtUtil(位于zzyl-common):负责 JWT 的创建与解析,核心步骤为使用 HS256 签名和设置过期时间,示例(摘录):JwtBuilder builder = Jwts.builder() .setClaims(claims) .signWith(signatureAlgorithm, secretKey.getBytes(StandardCharsets.UTF_8)) .setExpiration(DateUtil.offset(new Date(), DateField.HOUR_OF_DAY, dateOffset));
return builder.compact();
-
SecurityConfigProperties(位于zzyl-common):通过@ConfigurationProperties(prefix = "zzyl.framework.security")绑定安全相关的白名单与默认密码等配置信息。
- 模块间的依赖关系
- 父 POM:项目根
pom.xml定义了依赖管理与版本号(如 Spring Boot、Hutool、JWT、MyBatis、Druid 等),并把常用依赖放在dependencyManagement中统一控制版本。 zzyl-web依赖zzyl-service;zzyl-service、zzyl-security依赖zzyl-common(公共类库)。
- 开发与调试建议
- 本地启动:确保 MySQL、Redis 服务已启动,并且
application.yml中的连接信息(URL、用户名、密码)正确。 - 日志:
logback.xml在 resources 下,用于配置日志输出。 - 若要调试登录流程,可在
LoginServiceImpl.login方法中断点:- 检查
authenticationManager.authenticate(...)的结果。 - 验证
resourceMapper.selectByUserId(...)返回的资源路径列表是否符合权限预期。 - 检查生成的 JWT 是否能被
JwtUtil.parseJWT(...)正确解析。
- 检查
- 常见扩展点(建议)
- 权限粒度:当前基于请求路径的授权,可与注解式权限(方法级)结合加强控制。
- Token 管理:考虑实现 token 黑名单(logout)或短 token + 刷新 token 的方案提高安全性。
- 配置管理:把敏感配置(OSS、JWT 密钥等)迁移到配置中心或环境变量/密钥管理服务(不要把生产密钥写到代码/资源文件)。
- 小结
本项目结构清晰,遵循常见的企业级分层(common/service/security/web)。登录鉴权使用 Spring Security + JWT + Redis 的组合,代码易于理解与扩展。上面的摘录与说明旨在帮助熟悉 Java/Spring 的开发者快速定位关键逻辑、开始调试与二次开发。
如果你愿意,我可以继续:
- 生成更详细的模块级架构图与调用序列示意;
- 编写快速启动脚本(Windows PowerShell)并校验服务能否本地启动;
- 为关键类补充更详细的注释或单元测试样例。
- 快速启动(本地开发)
先决条件:
- Java 11
- Maven 3.6+
- MySQL(本项目用作数据存储)
- Redis(作缓存与存储用户可访问 URL 列表)
在本机构建并运行(示例,Windows PowerShell):
# 从项目根构建(跳过测试,加速)
cd zzyl-web; mvn -DskipTests package
# 或者用 Spring Boot 的插件直接启动(开发时用)
cd zzyl-web; mvn spring-boot:run
# 若已生成 jar,则运行:
java -jar zzyl-web/target/zzyl-web.jar注意:启动前请确保 application.yml 中的 MySQL/Redis 配置信息正确,或通过环境变量/外部配置覆盖。
- 示例请求(登录示例)
- HTTP 示例(curl)
curl -X POST "http://localhost:9995/security/login" \
-H "Content-Type: application/json" \
-d '{"username":"admin","password":"your_password"}'- PowerShell 示例(Invoke-RestMethod)
Invoke-RestMethod -Method Post -Uri http://localhost:9995/security/login -ContentType 'application/json' -Body (@{ username = 'admin'; password = 'your_password' } | ConvertTo-Json)响应示例(简化):
-
成功:返回
UserVo,其中包含userToken(JWT),客户端把它放入 Authorization 头或前端本地存储:{ "data": { "id": "...", "username": "admin", "userToken": "" } }
- 重要文件位置(快速定位)
zzyl-web/src/main/resources/application.yml— 全局配置(端口、数据源、redis、jwt 等)zzyl-web/src/main/java/com/zzyl/ZzylApplication.java— 应用入口zzyl-security/src/main/java/com/zzyl/controller/LoginController.java— 登录接口zzyl-security/src/main/java/com/zzyl/service/impl/LoginServiceImpl.java— 登录逻辑(认证、生成 JWT、写 Redis)zzyl-common/src/main/java/com/zzyl/utils/JwtUtil.java— JWT 生成/解析工具zzyl-common/src/main/java/com/zzyl/vo/UserAuth.java— Spring Security 的UserDetails实现zzyl-common/src/main/java/com/zzyl/properties—JwtTokenManagerProperties,SecurityConfigProperties等配置绑定类
- 排查与调试检查点(常见问题)
- 无法连接 MySQL/Redis:检查
application.yml中的 host/port/credentials,确认服务已启动并允许本地连接。 - 登录失败且抛出异常:在
LoginServiceImpl.login中断点,检查authenticationManager.authenticate(...)返回的Authentication;如果为未通过,排查UserDetailsService的实现加载用户是否成功。 - Token 无法解析:确认
JwtTokenManagerProperties.base64EncodedSecretKey与用于解析的密钥一致,并且JwtUtil使用的编码匹配(UTF-8)。 - 权限问题(访问控制):检查 Redis 中存的
PUBLIC_ACCESS_URLS:{userId}键值是否包含期望的路径,以及SecurityConfigProperties.publicAccessUrls是否配置了必要的白名单。