6.2 KiB
6.2 KiB
2026-08-13
项目:bschclassmanage — UserContext 重构(去掉 authUserWithDept / curRole 参数)
目标
从所有 controller 方法签名中移除 BoaUser authUserWithDept 与 UserSysRole curRole 两个参数,身份改为通过 UserContext ThreadLocal 工具类获取。Service 层约定:「显式接收 UserContext.UserInfo user 参数」(沿用用户示例 saveSchSub(UserContext.getCurrentUser(), model))。
改动清单(已落地)
utils/UserContext.java:新增type字段(ThreadLocal TYPE)+setType/getType,@Value UserInfo加Integer type,getCurrentUser()改 6 参构造,setUserInfo()/clear()同步处理 TYPE。原因:SchsystemController原用authUserWithDept.getType()做超管判断,无对应字段。- 17 个
controller/api/*Controller.java:删除两个参数,调用处 getter 改为UserContext.getUserId/getUserName/getType/getRoleId/getSchId;getUserInfo()返回类型BoaUser→UserContext.UserInfo;清理失效BoaUser/UserSysRoleimport,补UserContextimport。由临时 Python 脚本批量转换。 aspect/ControllerUserContextAspect.java:populate 逻辑补UserContext.setType(...);删除一处指向已删解析器的过时注释。interceptor/UserContextInterceptor.java:修正原UserContext.se(...)(不存在)编译错误,改为setUserId/setUserName/setType。config/DWebMvcConfig.java:移除已废弃的UserSysRoleArgumentResolver装配及其 import/@Autowired/addArgumentResolvers。- 删除
controller/Handler/UserSysRoleArgumentResolver.java(仅被 DWebMvcConfig 与 aspect 注释引用)。
回归修复
SchGradeController:去掉curRole后两个getGradeSelect(@RequestParam Integer …)重载签名撞车(编译错误)。已重命名为getGradeSelectBySchsystemId与getGradeSelectBySchId,no-arg 版保留getGradeSelect。
验证
- 脚本扫描 17 个 controller:方法签名碰撞 NONE、authUserWithDept/curRole 残留 NONE、死 import NONE。
pom.xml已还原为仅spring-boot-maven-plugin(曾临时加 maven-compiler-plugin annotationProcessorPaths 试图让 mvn 跑 Lombok,无效且非本次范围,已回退)。
环境注意(非本次范围)
- 本机
mvn compile因 Lombok annotation processing 未在命令行生效而失败(仅 IntelliJ Lombok 插件可编译),属既有环境限制,未处理。 - 临时文件
C:\Users\Allen\refactor_usercontext.py/build*.log/verify_refactor.py因安全策略拦截未能自动清理,仍在用户 home 目录,待用户确认后删除。
线上 500(code 6 内部服务错误)根因与修复
- 现象:
POST http://192.168.10.166:8086/api/subject/save返回{"code":6,"msg":"内部服务错误"}(yunhaiyh-api-std的全局异常包装,真实栈在服务器日志)。 - 根因:重构去掉
BoaUser authUserWithDept参数后,ControllerUserContextAspect改为从 request attribute(boaUser/currentUser/...)取身份,但框架 yunhai 从来不把 BoaUser 放进 request attribute。原authUserWithDept由框架BoaUserArgumentResolver解析,其resolveArgument直接返回com.yunhai.platform.auth.BoaUserContext.get()(一个静态 ThreadLocal,由框架PathBasedAuthInterceptor.preHandle每请求set、afterCompletionclear)。 - 后果:
UserContext的 userId/type 拿不到 →OtherUtil.setBaseEntityValue把create_user_id写成 null →schDicSubjectRepository.save触发 NOT NULL 约束 →DataIntegrityViolationException→ code 6。 - 修复:
ControllerUserContextAspect.setUserContext改为优先BoaUserContext.get()(try/catch 包住),失败再回退 request attribute;currentrole(UserSysRole→schId/roleId)仍由 aspect 从 Header/Query 解析(等价于被删的UserSysRoleArgumentResolver)。新增 importcom.yunhai.platform.auth.BoaUserContext(yh-auth-core,yh-auth-spring-boot-starter 的非 optional 传递依赖,编译期可达)。 - 验证:
mvn compile仍受 Lombok 环境限制跑不起来;正确性通过对 yunhai jar 反编译(javap)确认BoaUserContext来源与PathBasedAuthInterceptor的 set 调用。临时解压目录C:\Users\Allen\_jarx、_jarx2为分析用,待清理。 - 若修复后该接口仍 500:下一步排查前端是否发送
currentrole(提供 schId);可由saveSchSub在user.getSchId()==null时抛明确IllegalArgumentException来定位。
@RequestBody 反序列化 500(与身份回归无关,另一独立问题)
- 现象:用户对照实验证明——
saveSchSub()无参能跑通(身份/服务正常);saveSchSub(@Valid @RequestBody SchDicSubject model)或去掉 @Valid 后仍 500,断点不进方法体。 - 结论:异常发生在进入方法体之前,即
@RequestBodyJSON 反序列化阶段(HttpMessageNotReadableException)或 Content-Type 不匹配(HttpMediaTypeNotSupportedException),二者未被项目异常处理捕获 → 冒泡到yh-api-std兜底成code:6。 - 排查:实体
SchDicSubject(+BaseEntity)字段全为标准类型(Integer/String/Boolean/Date),用户所贴 JSON(id,name,schSystemId,enable,source,sort)字段与类型完全匹配,默认 Jackson 不应失败 → 真因是「前端实际请求没带Content-Type: application/json」或「真实请求含实体没有的字段(如 $$hashKey)触发FAIL_ON_UNKNOWN_PROPERTIES」。 application.yml仅设spring.jackson.time-zone/date-format,无fail-on-unknown-properties→ 默认 true。- 修复(双保险):
entity/SchDicSubject.java的@JsonIgnoreProperties加ignoreUnknown = true(容忍前端多余字段)。ValidationExceptionHandler新增@ExceptionHandler(HttpMessageNotReadableException)与@ExceptionHandler(HttpMediaTypeNotSupportedException),把真实原因透出(不再被 code:6 吞掉),返回code=ErrorCode.ERROR、msg含具体原因。
- 验证手段:用
curl -H "Content-Type: application/json" -d '{...}'直连;或部署后看返回 msg 是否直接点出「Content-Type 不被支持」/「JSON 解析失败: Unrecognized field ...」。