Java17使用Jackson反序列化JSON报InaccessibleObjectException怎么解决
问题根因
- 使用的Jackson版本未适配Java 9+的模块系统,旧版本尝试通过反射修改
java.time包下类的访问权限,被Java模块机制拦截抛出InaccessibleObjectException - 未引入Jackson对Java 8时间类型的专门支持模块
jackson-datatype-jsr310,Jackson默认无法正确反序列化OffsetDateTime/LocalDateTime等java.time包下的时间类型 - 你的
Swupdate类仅提供了getter方法,没有对应setter,Jackson无法给私有属性赋值 - JSON返回的
lastinstall字段值为2021-08-13T13:51:54,不含时区偏移信息,和你定义的OffsetDateTime类型不匹配
修复步骤
步骤1:引入JSR310时间处理模块
Maven依赖示例:
<dependency> <groupId>com.fasterxml.jackson.datatype</groupId> <artifactId>jackson-datatype-jsr310</artifactId> <version>2.15.2</version> <!-- 和你项目其他Jackson组件版本保持一致,建议用2.13以上稳定版 --> </dependency>
Gradle依赖示例:
implementation 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.15.2'
步骤2:修正Swupdate类
建议将lastinstall改为和JSON格式匹配的LocalDateTime类型,同时补全setter方法:
class Swupdate { private String state; private LocalDateTime lastinstall; public String getState() { return state; } public void setState(String state) { this.state = state; } public LocalDateTime getLastinstall() { return lastinstall; } public void setLastinstall(LocalDateTime lastinstall) { this.lastinstall = lastinstall; } }
如果一定要用OffsetDateTime,可以在字段上加序列化注解指定默认时区,或者在ObjectMapper里配置全局默认时区。
步骤3:配置ObjectMapper
注册JSR310模块,关闭时间序列化时间戳的默认配置:
ObjectMapper mapper = new ObjectMapper() // 注册Java8时间类型处理模块 .registerModule(new JavaTimeModule()) // 时间不序列化为时间戳,用字符串格式 .disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); // 执行反序列化 GetConversion conversion = mapper.readValue(responseString, GetConversion.class);
可选:兼容旧版本Jackson的权限报错
如果因为项目限制不能升级Jackson版本,可以在JVM启动参数里添加以下配置,开放java.time包的访问权限:
--add-opens java.base/java.time=ALL-UNNAMED
内容的提问来源于stack exchange,提问作者sdfesgfsef
相关产品推荐
相关产品推荐

