jackson序列化和反序列化技巧

1、序列化(别名方式)
采用@JsonProperty 注解标识别名

如果属性是非String类型的,可以设置相关的序列化过滤原则,比如Long型的,定义为0时过滤,在相关字段上加@JsonSerialize指定相关规则:

public class TraceInfo implements Serializable {

/**
 * 轨迹唯一标识
 */
@JsonProperty("ti")
private String trid;
/**
 * 轨迹里程
 */
@JsonProperty("ds")
@JsonSerialize(using = NotEmptyDoubleSerializer.class)
private double distance = 2;
/**
 * 轨迹持续时间,单位毫秒
 */
@JsonProperty("dr")
@JsonSerialize(using = NotEmptyDoubleSerializer.class)
private double duration = 3;
/**
 * 该段轨迹的开始时间戳,unix时间戳,毫秒
 */
@JsonProperty("s")
@JsonSerialize(using = NotEmptyLongSerializer.class)
private long startTime;
/**
 * 该段轨迹的结束时间戳,unix时间戳,毫秒
 */
@JsonProperty("e")
@JsonSerialize(using = NotEmptyLongSerializer.class)
private long endTime;
/**
 * 1-接乘客 2-送乘客
 */
@JsonProperty("t")
@JsonSerialize(using = NotEmptyIntSerializer.class)
private int type;
/**
 * 轨迹点数组
 */
@JsonProperty("p")
private List<PointInfo> points;

public String getTrid() {
    return trid == null ? "" : trid;
}

public void setTrid(String trid) {
    this.trid = trid;
}

public double getDistance() {
    return distance;
}

public void setDistance(double distance) {
    this.distance = distance;
}

public double getDuration() {
    return duration;
}

public void setDuration(double duration) {
    this.duration = duration;
}

public long getStartTime() {
    return startTime;
}

public void setStartTime(long startTime) {
    this.startTime = startTime;
}

public long getEndTime() {
    return endTime;
}

public void setEndTime(long endTime) {
    this.endTime = endTime;
}

public int getType() {
    return type;
}

public void setType(int type) {
    this.type = type;
}

public List<PointInfo> getPointInfos() {
    return points;
}

public void setPointInfos(List<PointInfo> points) {
    this.points = points;
}

}

查看NotEmptyLongSerializer.java:

public class NotEmptyLongSerializer extends StdScalarSerializer {

public NotEmptyLongSerializer() {
    super(Long.class);
}

@Override
public void serialize(Long value, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
    jsonGenerator.writeNumber(value);
}

public boolean isEmpty(SerializerProvider provider, Long value) {
    return value == null || value == 0;
}

}

序列化方法:

protected String toJson(T t) {
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY);
try {
return objectMapper.writeValueAsString(t);
} catch (JsonProcessingException e) {
logger.error(“toJson writeValueAsString error:{}”, e);
}
return null;
}

当这个long型的值不传或者传0就会在序列化过程中被过滤,序列化结果(不传startTime):

{“pointInfos”:[{“l”:“31.202212,121.576482”,“t”:156870881800}],“ti”:“D716cb509acaf4e118b239453e5ac6aas”,“ds”:354.502633,“e”:156870881802,“t”:1,“p”:[{“l”:“31.202212,121.576482”,“t”:156870881800}]}]}
结果发现json串存储的对象字段全是别名,而startTime对应的s并没有,这正是我们需要的。

3、反序列化(别名方式)

1、单个对象反序列化

当对象用别名存储方式存储后,现在想读取存储的对象,需要对其进行反序列化,采用的办法是:

private T toJavaBean(String jsonString, Class z) {
ObjectMapper objectMapper = new ObjectMapper();
try {
return (T) objectMapper.readValue(jsonString, z);
} catch (JsonProcessingException e) {
logger.error(“toJavaBean readValue error:{}”, e);
}
return null;
}
对于简单对象(不是List的对象)按这个方式反序列化,要求是对应的别名和存储的字段一一对应,否则报错。

2、List<对象>反序列化

先采用这样的方法试下:

private T toJavaBeanList(String jsonString) {
ObjectMapper objectMapper = new ObjectMapper();
try {
return (T) objectMapper.readValue(jsonString, List.class);
} catch (JsonProcessingException e) {
logger.error(“toJavaBeanList readValue error:{}”, e);
}
return null;
}

序列化结果报错:
在这里插入图片描述
Caused by: java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast to com.saicmobility.trip.trajectoryservice.model.PointInfo

为什么呢?

打断点调试:

在这里插入图片描述
原来这个方法反序列化出的对象是LinkedHashMap型的,不是我们所需的对象。

正确的方法是采用下面的方法:

private T toJavaBeanList(String jsonString, Class z) {
ObjectMapper objectMapper = new ObjectMapper();
JavaType javaType = getCollectionType(ArrayList.class, z);
try {
return (T) objectMapper.readValue(jsonString, javaType);
} catch (JsonProcessingException e) {
logger.error(“toJavaBeanList readValue error:{}”, e);
}
return null;
}

private JavaType getCollectionType(Class<?> collectionClass, Class<?>… elementClasses) {
ObjectMapper mapper = new ObjectMapper();
return mapper.getTypeFactory().constructParametricType(collectionClass, elementClasses);
}
反序列化前需要通过getCollectionType定义结合属性的对象,然后带入反序列化方法中。

在这里插入图片描述
成功获取集合对象:
在这里插入图片描述
在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值