Jakarta EE Jsonb处理YearMonth反序列化报错求助(弃用Jackson)
解决Jakarta EE JSON-B反序列化java.time.YearMonth的错误
问题原因
Jakarta EE JSON-B(Jsonb)默认未内置java.time.YearMonth类型的序列化/反序列化支持,这是导致你遇到错误的核心原因。下面提供纯Jsonb生态的解决方案,无需依赖Jackson。
解决方案:自定义Jsonb类型适配器
通过实现JsonbAdapter接口,我们可以手动定义YearMonth与JSON字符串之间的转换逻辑,适配你需要的"年月"格式(如yyyy-MM)。
1. 编写YearMonth的Jsonb适配器
创建适配器类,处理YearMonth和字符串的双向转换:
import jakarta.json.bind.adapter.JsonbAdapter; import java.time.YearMonth; import java.time.format.DateTimeFormatter; public class YearMonthJsonbAdapter implements JsonbAdapter<YearMonth, String> { // 定义JSON中使用的年月格式,可根据需求调整 private static final DateTimeFormatter YEAR_MONTH_FORMAT = DateTimeFormatter.ofPattern("yyyy-MM"); @Override public String adaptToJson(YearMonth yearMonth) throws Exception { // 序列化:YearMonth转字符串 return yearMonth != null ? yearMonth.format(YEAR_MONTH_FORMAT) : null; } @Override public YearMonth adaptFromJson(String jsonValue) throws Exception { // 反序列化:字符串转YearMonth return jsonValue != null && !jsonValue.isBlank() ? YearMonth.parse(jsonValue, YEAR_MONTH_FORMAT) : null; } }
2. 应用适配器到代码中
有两种方式可以使用这个适配器,根据你的场景选择:
方式一:字段级单独配置
直接在实体类的publishedOn字段上标注@JsonbTypeAdapter,指定我们的适配器:
public class Book { public String isbn; public String title; @JsonbTypeAdapter(YearMonthJsonbAdapter.class) public YearMonth publishedOn; }
方式二:全局配置(推荐多类使用场景)
如果你的项目中有多个类用到YearMonth类型,可以全局注册适配器,避免重复标注:
public static void main(String[] args) { // 创建Jsonb配置并注册适配器 JsonbConfig config = new JsonbConfig() .withAdapters(new YearMonthJsonbAdapter()); Jsonb jsonb = JsonbBuilder.create(config); // 序列化测试 Book book = new Book(); book.isbn = "123"; book.title = "Advanced JPA and Hibernate"; book.publishedOn = YearMonth.of(2022, 9); String serializedJson = jsonb.toJson(book); // 输出:{"isbn":"123","title":"Advanced JPA and Hibernate","publishedOn":"2022-09"} // 反序列化测试 String testJson = "{\"isbn\":\"123\",\"title\":\"Advanced JPA and Hibernate\",\"publishedOn\":\"2022-09\"}"; Book deserializedBook = jsonb.fromJson(testJson, Book.class); // deserializedBook.publishedOn 将正确解析为 YearMonth.of(2022,9) }
与JPA转换器的兼容性说明
你当前使用的JPAYearMonthDateAttributeConverter负责将YearMonth映射到数据库DATE字段,而我们的Jsonb适配器仅处理JSON与Java对象的转换,二者职责分离,完全可以同时使用,不会产生冲突,完美满足你"仅存储年月信息"的需求。
内容的提问来源于stack exchange,提问作者Abdelmuniem
相关产品推荐
相关产品推荐

