反应式项目中自定义Jackson配置未生效问题求助
解决方案
1. 调整Jackson配置顺序,确保自定义模块覆盖默认实现
Quarkus默认会通过ObjectMapperCustomizer注册JavaTimeModule,提供LocalDateTime的默认序列化逻辑。如果你的自定义模块先于默认模块注册,会被默认模块覆盖。修改JacksonConfig,先应用Quarkus的自定义器,再注册自己的模块:
public class JacksonConfig { @Singleton @Produces ObjectMapper objectMapper(@All List<ObjectMapperCustomizer> customizers) { ObjectMapper mapper = new ObjectMapper(); // 先应用Quarkus自带的自定义配置(包括JavaTimeModule) for (ObjectMapperCustomizer customizer : customizers) { customizer.customize(mapper); } // 注册自定义模块,覆盖默认的LocalDateTime序列化/反序列化规则 SimpleModule simpleModule = new SimpleModule("customLocalDateTimeModule"); simpleModule.addDeserializer(LocalDateTime.class, new DateTimeDeserializer()); simpleModule.addSerializer(LocalDateTime.class, new DateTimeSerializer()); mapper.registerModule(simpleModule); return mapper; } }
同时删除JsonUtil中的静态ObjectMapper初始化逻辑,避免静态实例和CDI管理的实例冲突,后续所有序列化操作都通过CDI注入ObjectMapper完成。
2. 使用Quarkus反应式专属的Jackson自定义器
如果你的项目基于RESTEasy Reactive,推荐实现ReactiveJacksonCustomizer来配置,更贴合反应式生态:
@Singleton public class CustomLocalDateTimeJacksonCustomizer implements ReactiveJacksonCustomizer { @Override public void customize(ObjectMapper mapper) { SimpleModule customModule = new SimpleModule("customLocalDateTimeModule"); customModule.addSerializer(LocalDateTime.class, new DateTimeSerializer()); customModule.addDeserializer(LocalDateTime.class, new DateTimeDeserializer()); mapper.registerModule(customModule); } }
这种方式无需手动生产ObjectMapper,Quarkus会自动将自定义配置应用到反应式环境使用的ObjectMapper实例中。
3. 检查自定义序列化器/反序列化器的实现
确保你的DateTimeSerializer和DateTimeDeserializer逻辑正确,比如处理空值、格式匹配:
示例序列化器:
public class DateTimeSerializer extends JsonSerializer<LocalDateTime> { private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); @Override public void serialize(LocalDateTime value, JsonGenerator gen, SerializerProvider serializers) throws IOException { gen.writeString(value != null ? value.format(FORMATTER) : null); } }
示例反序列化器:
public class DateTimeDeserializer extends JsonDeserializer<LocalDateTime> { private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); @Override public LocalDateTime deserialize(JsonParser p, DeserializationContext ctxt) throws IOException { String dateStr = p.getText(); return dateStr == null || dateStr.isBlank() ? null : LocalDateTime.parse(dateStr, FORMATTER); } }
4. 确保CDI注入的ObjectMapper被正确使用
检查接口层和业务逻辑中,是否都是通过CDI注入ObjectMapper,而非直接调用JsonUtil.getObjectMapper()。如果存在直接使用静态实例的情况,会导致全局配置不生效。
比如,在服务类中注入:
@Inject ObjectMapper objectMapper;
而非:
ObjectMapper mapper = JsonUtil.getObjectMapper();
内容的提问来源于stack exchange,提问作者baozi
相关产品推荐
相关产品推荐

