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
相关产品推荐
相关产品推荐

