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定义结合属性的对象,然后带入反序列化方法中。
成功获取集合对象: