You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Quarkus REST API中Jackson为何忽略自定义ObjectMapper?

问题分析与解决方案

为什么自定义ObjectMapper被忽略?

  • 手动创建未配置的ObjectMapper实例:你在hello()方法里直接new ObjectMapper()生成的实例,完全独立于Quarkus容器中通过ObjectMapperCustomizer配置的实例。这个未配置的实例解析JSON时,会把0.000000009解析为Double类型,而你添加的WRITE_BIGDECIMAL_AS_PLAIN配置仅对BigDecimal类型生效,所以序列化时依然输出科学计数法。
  • 返回类型的序列化逻辑差异:返回POJO时,Quarkus使用容器中配置好的ObjectMapper处理,且POJO存储的是BigDecimal,正好触发配置效果;返回ObjectNode时,因为节点内数值是Double,即使使用自定义ObjectMapper,也无法激活该配置。

解决方法

方法1:注入Quarkus配置好的ObjectMapper(推荐)

不要手动创建ObjectMapper,通过依赖注入获取容器中已配置的实例,确保解析和序列化都应用自定义规则:

@Path("/hello")
public class ExampleResource {

    @Inject
    ObjectMapper objectMapper; // 注入容器内已配置的实例

    @GET
    @Consumes(MediaType.APPLICATION_JSON)
    public ObjectNode hello() throws JsonProcessingException {
        String str = "{\"var\": 0.000000009}";
        ObjectNode object = (ObjectNode) objectMapper.readTree(str);
        return object;
    }
}

同时更新自定义配置,开启将浮点解析为BigDecimal的规则:

@Singleton
public class RegisterCustomModuleCustomizer implements ObjectMapperCustomizer {
    public void customize(ObjectMapper mapper) {
        mapper.enable(JsonGenerator.Feature.WRITE_BIGDECIMAL_AS_PLAIN);
        mapper.enable(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS); // 新增解析配置
    }
}

方法2:手动转换ObjectNode中的数值类型

如果需要保留手动创建ObjectMapper的逻辑,可以将节点内的Double值转为BigDecimal,确保序列化时触发配置:

@Path("/hello")
public class ExampleResource {

    @Inject
    ObjectMapper objectMapper;

    @GET
    @Consumes(MediaType.APPLICATION_JSON)
    public ObjectNode hello() throws JsonProcessingException {
        String str = "{\"var\": 0.000000009}";
        ObjectMapper tempMapper = new ObjectMapper();
        ObjectNode object = (ObjectNode) tempMapper.readTree(str);
        // 将Double转为BigDecimal
        double doubleValue = object.get("var").asDouble();
        object.put("var", BigDecimal.valueOf(doubleValue));
        return object;
    }
}

方法3:沿用POJO返回类型

既然POJO方式已经可以正常工作,若无需动态节点结构,直接使用POJO作为返回类型是最简洁的方案:

@Path("/hello")
public class ExampleResource {

    @Inject
    ObjectMapper objectMapper;

    @GET
    @Consumes(MediaType.APPLICATION_JSON)
    public Entity hello() throws JsonProcessingException {
        String str = "{\"var\": 0.000000009}";
        return objectMapper.readValue(str, Entity.class);
    }
}

内容的提问来源于stack exchange,提问作者Andrey Kirson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 03:44:52