4.1 KiB
Bug #741 诸葛亮分析报告
文档类型: Bug分析 分析时间: 2026-06-12 11:46:17 分析模型: mimo-v2.5 (LLM深度分析)
基本信息
- Bug #: 741
- 标题: 【住院医生工作站】打开门诊医生工作站会有代码列表报错
- 模块: 住院医生工作站
- 提出人: 王栩坤
一、Bug 理解
用户登录 doctor1 账号进入住院医生工作站页面时,页面加载过程中某个 API 请求返回了 500 错误,错误信息为 class java.util.ArrayList cannot be cast to class com.fasterxml.jackson.databind.JsonNode。这个 Java ClassCastException 被前端 request.js 拦截器捕获并弹出错误提示,导致页面功能异常。期望是页面能正常加载,患者列表和各 Tab 页正常工作。
二、根因分析
直接原因:后端某个 API 接口在处理请求或序列化响应时,抛出了 ClassCastException: ArrayList cannot be cast to JsonNode。异常被 GlobalExceptionHandler 捕获后返回 {code:500, msg:"class java.util.ArrayList cannot be cast to class com.fasterxml.jackson.databind.JsonNode"}。
根因定位:commit 68cfa4882 修改了 ApplicationConfig,将 Jackson2ObjectMapperBuilderCustomizer 替换为直接创建 new ObjectMapper() 的 @Bean。
// 旧代码 — 定制 Spring Boot 自动配置的 ObjectMapper
@Bean
public Jackson2ObjectMapperBuilderCustomizer jacksonObjectMapperCustomization() {
return builder -> { ... };
}
// 新代码 — 直接覆盖 Spring Boot 自动配置的 ObjectMapper
@Bean
public ObjectMapper objectMapper() {
ObjectMapper mapper = new ObjectMapper();
...
}
问题机制:
- 定义
@Bean ObjectMapper会替换 Spring Boot 自动配置的ObjectMapper,丢失大量自动配置(模块注册、类型解析器、序列化注解处理等) - Spring Boot 4.x 的
MappingJackson2HttpMessageConverter使用此 Bean 做响应序列化 - 当
DictAspect(拦截所有@GetMapping/@PostMapping)处理R<IPage<RegPatientMainInfoDto>>响应时,IPage的泛型信息在新ObjectMapper下无法正确解析 - Jackson 内部在序列化过程中尝试将
ArrayList(IPage内部的 records 列表)强转为JsonNode,导致ClassCastException
涉及文件:
core-framework/.../ApplicationConfig.java— 根因所在,ObjectMapper Bean 配置不当healthlink-his-common/.../DictAspect.java— 拦截所有 Controller 方法,触发序列化链路regdoctorstation/.../AdviceManageController.java—/reg-patient-zk端点regdoctorstation/.../AdviceManageAppServiceImpl.java—getRegPatientMainInfo()返回IPageutils/request.js— 前端拦截器,line 186 抛出 Promise reject
三、修复方案
修改文件:core-framework/src/main/java/com/core/framework/config/ApplicationConfig.java
修复方式:将 @Bean ObjectMapper 回退为 Jackson2ObjectMapperBuilderCustomizer,这样 Spring Boot 自动配置的 ObjectMapper 保持不变,只在其基础上追加自定义配置:
@Bean
public Jackson2ObjectMapperBuilderCustomizer jacksonObjectMapperCustomization() {
return builder -> {
builder.timeZone(TimeZone.getDefault());
builder.simpleDateFormat("yyyy-MM-dd HH:mm:ss");
JavaTimeModule javaTimeModule = new JavaTimeModule();
javaTimeModule.addDeserializer(LocalDateTime.class, LOCAL_DATE_TIME_DESERIALIZER);
javaTimeModule.addSerializer(LocalDateTime.class,
new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
builder.modules(javaTimeModule);
};
}
验证步骤:
mvn clean compile -DskipTests— 编译通过- 启动应用 → 以 doctor1 登录 → 进入住院医生工作站 → 确认无报错
- 验证患者列表正常加载、诊断/医嘱 Tab 页正常切换
四、路由决策
- 修复 Agent: guanyu(后端开发)
- 原因: 修复点在
ApplicationConfig.java的 ObjectMapper Bean 配置,属于后端 Spring 配置问题,需要回退 Jackson 序列化配置并验证编译通过。