javanull0_jackson实现null转0以及0转null的⽰例代码
需求背景
最近遇到⼀个需求,有个数值类型的字段,⾮必填,默认为空,数据库表针对该字段设计的是⼀个int类型, 由于dba推荐规范,默认该值是not null。这个时候,问题就来了,数据库默认存的是0,前端展⽰时,⼜不能显⽰这个0(需要的是null)
解决⽅案
针对此类处理,通常的⽅案有以下2种:
前端做处理,统⼀对0和null做处理,0即是null,null即是0
后端做处理,针对要处理的字段,在序列化之前或者之后做处理,或者采取硬编码的⽅式,针对要处理的字段,写if else
⽅案分析
针对第⼀种,这⾥⾯有个⽐较尴尬的地⽅,前端所接收的字段中,有些0是有意义的,譬如是否有效,0
可能代表有效,如果统⼀做了处理,那这个改为null了,那就出问题了。假如不统⼀处理,则需要区别对待,由于对前端不熟,不知道是否有类似注解或者带标志的全局⽅法来处理类似问题,听前端说处理⽐较⿇烦,so,只能后端来处理了。
针对第⼆种,后端处理的⽅式更灵活⼀些,想要简单可拓展,使⽤@JasonSerilize和@JsonDeserialize注解,写⾃定义序列化和反序列化类。想要快速完成,⾛硬编码。起初,因为对jackson的序列化反序列化机制不太了解,写的2个serializer和deserializer发布后也问题不断,所以为了保证项⽬的进展,采取了⽐较恶⼼的硬编码的⽅式,写了很多if else来做判断
测试序列化
maven依赖:jackson版本2.9.7
com.
jackson-databind
${jackson.version}
com.
jackson-core
${jackson.version}
com.
jackson-annotations
${jackson.version}
序列化类:
@JacksonStdImpl
public class ZeroToNullSerializer extends JsonSerializer implements ContextualSerializer {
private Class> type;
public ZeroToNullSerializer() {
}
public ZeroToNullSerializer(final JavaType type) {
}
@Override
public void serialize(Object o, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException { if (o instanceof Short) {
if (((Short) o)pareTo((short)0) == 0) {
jsonGenerator.writeNull();
} else {
jsonGenerator.writeNumber(((Short) o).shortValue());
}
}
if (o instanceof Integer) {
bigdecimal转换为integerif (((Integer) o).intValue() == 0) {
jsonGenerator.writeNull();
} else {
jsonGenerator.writeNumber(((Integer) o).intValue());
}
}
if (o instanceof Float) {
if (((Float) o)pareTo(0f) == 0) {
jsonGenerator.writeNull();
} else {
jsonGenerator.writeNumber(((Float) o).floatValue());
}
}
if (o instanceof Double) {
if (((Double) o)pareTo(0D) == 0) {
jsonGenerator.writeNull();
} else {
jsonGenerator.writeNumber(((Double) o).doubleValue());
}
}
if (o instanceof Long) {
if (((Long) o)pareTo(0L) == 0) {
jsonGenerator.writeNull();
} else {
jsonGenerator.writeNumber(((Long) o).longValue());
}
}
if (o instanceof BigDecimal) {
if (((BigDecimal) o)pareTo(BigDecimal.ZERO) == 0) {
jsonGenerator.writeNull();
}else {
jsonGenerator.writeNumber((BigDecimal) o);
}
}
}
@Override
public JsonSerializer> createContextual(SerializerProvider prov, BeanProperty property) throws JsonMappingException { return new Type());
}
}
测试序列化的bean:
@Data
public class TestSerializerBean {
@JsonSerialize(using =ZeroToNullSerializer.class)
private Integer number;
private Integer age;
private BigDecimal money;
}
序列化Test:
@Test
public void testSerializer() throws JsonProcessingException {
TestSerializerBean serializerBean = new TestSerializerBean();
serializerBean.setNumber(0);
serializerBean.setAge(0);
serializerBean.setMoney(new BigDecimal(20));
String string = mapper.writeValueAsString(serializerBean);
System.out.println(string);
}
测试结果:
return handleLong(p, ctxt);
}
if (pe == BigDecimal.class) {
return handleBigDecimal(p, ctxt);
}
if (pe == Double.class) {
return handleDouble(p, ctxt);
}
if (pe == Float.class) {
return handleFloat(p, ctxt);
}
if (pe == Short.class) {
return handleShort(p, ctxt);
}
throw new RuntimeException("反序列化错误,类型" + String() + "+不⽀持数值类型的反序列化"); }
private Object handleBigDecimal(JsonParser p, DeserializationContext ctxt) throws IOException { switch (p.getCurrentTokenId()) {
case JsonTokenId.ID_NUMBER_INT:
case JsonTokenId.ID_NUMBER_FLOAT:
DecimalValue();
case JsonTokenId.ID_STRING:
String text = p.getText().trim();
// note: no need to call `coerce` as this is never primitive
if (text == null || text.length() == 0) {
return getNullValue(ctxt);
}
try {
return new BigDecimal(text);
} catch (IllegalArgumentException iae) {
}
return (BigDecimal) ctxt.handleWeirdStringValue(type, text,
"not a valid representation");
case JsonTokenId.ID_START_ARRAY:

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。