Jackson定制序列化和反序列化

Jackson定制序列化和反序列化,第1张

Jackson定制序列化和反序列化

Unit
注释的想法真的很好。我们只需要添加自定义
com.fasterxml.jackson.databind.ser.BeanSerializerModifier
com.fasterxml.jackson.databind.ser.BeanPropertyWriter
实现。首先创建我们的注释类:

@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.FIELD)@interface Unit {    String value();}

POJO
模型可能如下所示:

class Pojo {    private User user = new User();    private Food food = new Food();    private House house = new House();    // getters, setters, toString}class User {    @Unit("m")    private int height = 10;    // getters, setters, toString}class Food {    @Unit("C")    private int temperature = 50;    // getters, setters, toString}class House {    @Unit("m")    private int width = 10;    // getters, setters, toString}

具有所有这些之后,我们需要自定义属性序列化:

class UnitBeanSerializerModifier extends BeanSerializerModifier {    @Override    public List<BeanPropertyWriter> changeProperties(SerializationConfig config, BeanDescription beanDesc, List<BeanPropertyWriter> beanProperties) {        for (int i = 0; i < beanProperties.size(); ++i) { final BeanPropertyWriter writer = beanProperties.get(i); AnnotatedMember member = writer.getMember(); Unit units = member.getAnnotation(Unit.class); if (units != null) {     beanProperties.set(i, new UnitBeanPropertyWriter(writer, units.value())); }        }        return beanProperties;    }}class UnitBeanPropertyWriter extends BeanPropertyWriter {    private final String unit;    protected UnitBeanPropertyWriter(BeanPropertyWriter base, String unit) {        super(base);        this.unit = unit;    }    @Override    public void serializeAsField(Object bean, JsonGenerator gen, SerializerProvider prov) throws Exception {        gen.writeFieldName(_name);        final Object value = (_accessorMethod == null) ? _field.get(bean) : _accessorMethod.invoke(bean, (Object[]) null);        gen.writeString(value + " " + unit);    }}

使用

SimpleModule
我们可以注册它并与使用
ObjectMapper

import com.fasterxml.jackson.core.JsonGenerator;import com.fasterxml.jackson.databind.BeanDescription;import com.fasterxml.jackson.databind.ObjectMapper;import com.fasterxml.jackson.databind.SerializationConfig;import com.fasterxml.jackson.databind.SerializerProvider;import com.fasterxml.jackson.databind.introspect.AnnotatedMember;import com.fasterxml.jackson.databind.module.SimpleModule;import com.fasterxml.jackson.databind.ser.BeanPropertyWriter;import com.fasterxml.jackson.databind.ser.BeanSerializerModifier;import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;import java.util.List;public class JsonApp {    public static void main(String[] args) throws Exception {        SimpleModule unitModule = new SimpleModule();        unitModule.setSerializerModifier(new UnitBeanSerializerModifier());        ObjectMapper mapper = new ObjectMapper();        mapper.registerModule(unitModule);        Pojo pojo = new Pojo();        System.out.println(mapper.writevalueAsString(pojo));    }}

印刷品:

{  "user" : {    "height" : "10 m"  },  "food" : {    "temperature" : "50 C"  },  "house" : {    "width" : "10 m"  }}

当然,您需要对其进行测试并处理所有极端情况,但以上示例显示了总体思路。以类似的方式,我们可以处理反序列化。我们需要实现custom

BeanDeserializerModifier
和一个custom
UnitDeserialiser

class UnitBeanDeserializerModifier extends BeanDeserializerModifier {    @Override    public JsonDeserializer<?> modifyDeserializer(DeserializationConfig config, BeanDescription beanDesc, JsonDeserializer<?> deserializer) {        JsonDeserializer<?> jsonDeserializer = super.modifyDeserializer(config, beanDesc, deserializer);        if (jsonDeserializer instanceof StdScalarDeserializer) { StdScalarDeserializer scalarDeserializer = (StdScalarDeserializer) jsonDeserializer; Class scalarClass = scalarDeserializer.handledType(); if (int.class == scalarClass) {     return new UnitIntStdScalarDeserializer(scalarDeserializer); }        }        return jsonDeserializer;    }}

反序列化器示例

int

class UnitIntStdScalarDeserializer extends StdScalarDeserializer<Integer> {    private StdScalarDeserializer<Integer> src;    public UnitIntStdScalarDeserializer(StdScalarDeserializer<Integer> src) {        super(src);        this.src = src;    }    @Override    public Integer deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {        String value = p.getValueAsString();        String[] parts = value.split("\s+");        if (parts.length == 2) { return Integer.valueOf(parts[0]);        }        return src.deserialize(p, ctxt);    }}

上面的实现只是一个例子,应该针对其他原始类型进行改进。我们可以使用简单的模块以相同的方式注册它。重复使用与序列化相同:

unitModule.setDeserializerModifier(new UnitBeanDeserializerModifier());


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5089745.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-11-16
下一篇 2022-11-16

发表评论

登录后才能评论

评论列表(0条)

保存