Jackson反序列化时如何将含Double值的字符串转为Long类型
Jackson反序列化带小数的字符串到Long类型解决方案
异常的核心原因是Jackson默认规则下,不支持将带小数点的字符串类型值直接反序列化为Long类型字段,可通过以下三种方案解决:
方案1:指定字段级自定义反序列化器(推荐,影响范围可控)
仅针对需要特殊处理的impressions字段生效,不会影响其他字段的反序列化逻辑:
- 首先自定义String转Long的反序列化器,可自行定义取整规则:
import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.databind.DeserializationContext; import com.fasterxml.jackson.databind.JsonDeserializer; import java.io.IOException; import java.math.BigDecimal; public class StringToLongDeserializer extends JsonDeserializer<Long> { @Override public Long deserialize(JsonParser parser, DeserializationContext context) throws IOException { String value = parser.getText().trim(); // 示例为四舍五入取整,可根据业务需要替换为向下取整BigDecimal.ROUND_DOWN等规则 return new BigDecimal(value).setScale(0, BigDecimal.ROUND_HALF_UP).longValue(); } }
- 在POJO对应字段上添加
@JsonDeserialize注解指定反序列化器:
import com.fasterxml.jackson.databind.annotation.JsonDeserialize; public class Sample { // 建议类名首字母大写符合Java编码规范 @JsonDeserialize(using = StringToLongDeserializer.class) private Long impressions; private Long discount; private Double rate; }
方案2:全局配置ObjectMapper(适合大量同类型字段场景)
如果项目中有大量字段需要实现相同的转换规则,可以全局注册自定义反序列化器,配置后所有Long类型字段都会生效:
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.module.SimpleModule; ObjectMapper objectMapper = new ObjectMapper(); // 注册全局自定义反序列化器 SimpleModule longConvertModule = new SimpleModule(); longConvertModule.addDeserializer(Long.class, new StringToLongDeserializer()); objectMapper.registerModule(longConvertModule); // 可配合开启以下常用配置 // 允许浮点数值直接转整数(会截断小数部分) // objectMapper.enable(DeserializationFeature.ACCEPT_FLOAT_AS_INT); // 允许空字符串转null // objectMapper.enable(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL);
方案3:调整字段类型后手动转换(无框架侵入)
无需修改Jackson的任何配置,调整POJO字段类型接收原始值后手动转换,适合临时快速适配场景:
public class Sample { // 用String类型接收原始JSON值 private String impressions; private Long discount; private Double rate; // 手动实现转换方法供业务调用 public Long getImpressionsLongValue() { if (impressions == null || impressions.isBlank()) { return null; } return new BigDecimal(impressions).setScale(0, BigDecimal.ROUND_HALF_UP).longValue(); } }
注意:所有转换方案都需要根据业务需求确认小数部分的处理规则,避免精度损失引发业务问题。
内容的提问来源于stack exchange,提问作者jagannathan rajagopalan
相关产品推荐
相关产品推荐

