做项目的时候,我给前端提供了一个查询列表的接口,但是随着数据的增加运行会变得很慢。通过计时器监控发现是序列化的时候特别费时间(我的实体里有很多关联表)。
解决这个问题可以用JsonSerialize注解,我来总结一下JsonSerialize的用法。
该注解可以自定义序列化,可以写在某一个属性上,也可以写在整个类上(也可以用在getter()方法上与前者相似)。
二者区别:前者对某一个属性序列化时的改写(一般用于统一单位,格式之类),后者需要把整个类需要序列化的字段加工重写。
1. 用在字段上
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
/**
*1. 数据库存的时间不符合前端要求
*2. 数据库存的数据小数点不符合前端要求
**/
public class OrderDTO{
private Integer id;
@JsonSerialize(using = OrderDtoSerializer.class) //1.用这个类格式化时间
private Date createtime;
//在实体里这是多对多关系
private List<GoodsEntity> goodsEntityList;
// @JsonSerialize(using = OrderDtoSerializer.class) //2.小数点保留两位
private Double rate;
}
规范日期为YYYY-MM-DD格式
//可以直接建立静态内部类,也可以做外部类。需要继承JsonSerializer抽象类
class OrderDtoSerializer extends JsonSerializer<OrderDTO> {
// 自定义序列化,规范时间格式。重写serialize方法来实现
@Override
public void serialize(Date createtime, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
//1. 规范时间为yyyy-MM-dd格式
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
//用jsonGenerator把所需要的数据写入json
jsonGenerator.writeString(sdf.format(date));
}
小数点保留两位
class OrderDtoSerializer extends JsonSerializer<OrderDTO> {
// 自定义序列化,小数点保留两位
@Override
public void serialize(Double rate, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
//1. 规范小数点保留两位
DecimalFormat df = new DecimalFormat("#0.00");
//用jsonGenerator把所需要的数据写入json
jsonGenerator.writeString(df.format(value));
}
2. 用在类上
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
/**
*1. 整个实体要简化返回给前端的数据
**/
@JsonSerialize(using = OrderDTO.OrderDtoSerializer.class)
public class OrderDTO{
private Integer id;
private Date createtime;
//在实体里这是多对多关系
private List<GoodsEntity> goodsEntityList;
private Double rate;
//为了方便我用的静态内部类
static class OrderDtoSerializer extends JsonSerializer<OrderDTO> {
// 自定义序列化,防止在接口返回时序列化引起的连环反应,导致过多冗余的对象被再度查询实例化。假如我们不需要createtime属性
@Override
public void serialize(OrderDTO orderDTO, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
jsonGenerator.writeStartObject();//开始写json对象相当于{
jsonGenerator.writeFieldName("id");//属性名字
jsonGenerator.writeNumber(orderDTO.getId());
jsonGenerator.writeFieldName("rate");
jsonGenerator.writeObject(orderDTO.getRate());//用object类型
//对于关联表的属性,可以用这个方法直接赋值
jsonGenerator.writeObjectField("goodsEntityList",orderDTO.getGoodsEntityList());
jsonGenerator.writeEndObject();//写了开始就一定要写结束,相当于}
}
这样写完在前端应该得到这样的json:
{
id:XX,
rate:XX,
goodsEntityList:[]
}
有待补充。。。