json相关注解和序列化与反序列化
使⽤jackson进⾏序列化时,往往会遇到后台某个实体对象的属性为null,当序列化成json时对应的属性也为null,可以⽤以下的注解⽅式完成当属性为null时不参与序列化:
@JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL)
@JsonIgnoreProperties
类注解,作⽤是json序列化时将bean中的⼀些属性忽略掉,序列化和反序列化都受影响。
@JsonIgnore
作⽤于属性或字段上,当⽣成json时忽略有该annotation的⽅法或字段。
@JsonProperty("rename")
作⽤于属性或字段上,对其重命名。
@JsonFormat
作⽤于属性或字段上,⽅便把Date类型直接转化为我们想要的模式,如@JsonFormat(pattern="yyyy-MM-dd HH-mm-ss")
@JsonSerialize
作⽤于属性或字段上,指定序列化⽅式。
例如:@JsonSerialize(as=BasicType.class)将类型序列化成指定类型;@JsonSerialize(using=CustomDoubleSerialize.class)⽤于在序列化时嵌⼊我们⾃定义的代码,⽐如序列化⼀个double时在其后限制两位⼩数。
@JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL)
//保证序列化json的时候,如果是null的对象,key也会消失
//⽐如在创建失败的时候,只需要将status和msg显⽰出来,但是如果不加上⾯的注解会将data也显⽰出来,其值会显⽰null
@JsonDeserialize
作⽤于属性或字段上,指定反序列化⽅式。
例如:@JsonDeserialize(as=ValueImpl.class)将类型反序列化成指定类型;@JsonDeserialize(using=CustomDateDeserialize.class)⽤于在反序列化时嵌⼊我们⾃定义的代码。
序列化与反序列化
例⼦:
public class ServerResponse<T> implements Serializable{
Serializable是⼀个标识接⼝,它没有定义任何⽅法,实现了这个接⼝,就代表这个类可以进⾏串⾏化了。
串⾏化也叫序列化,就是将实例的状态转化成⽂本(或⼆进制)的形式,以便永久保存(所以也叫持久化)或在⽹间传递。
什么时候实现java.io.Serializable接⼝?
如果⼀个类的实例需要持久化或者需要在⽹间传递的时候,就⽤到串⾏化。
例如:action,dao层的⼀些个类⼀般不需要串⾏化,⽽bean层的⼀些个类⼀般需要串⾏化。因为客户
端⽤到action,dao层的时候都是import过来,然后⾃⼰进⾏实例化的,或者直接调⽤容器中的实例;⽽bean不⼀样,客户端不可以new⼀个出来给⾃⼰,客户端需要从服务器端接收⼀个bean,读取bean中的信息状态,然后做出⼀系列反应,⽽这个传输过程就⽤到了串⾏化。
为什么要实现序列化?
序列化实体对象是为了⽅便⽹络传输。因为⽹络传输数据只能是⼆进制流,序列化能将实体转化为⼆进制流传输,同时还可通过反序列化重新将⼆进制流还原成实体对象。
json转换对象序列化在⽹络协议中的应⽤:
OSI七层协议模型中表现层的主要功能是把应⽤层的对象转换成⼀段连续的⼆进制串,或者反过来,把⼆进制串转换成应⽤层的对象。这两个功能就是序列化和反序列化。⽽TCP/IP协议的应⽤层对应OSI七层模型的应⽤层、表⽰层和会话层,所以序列化协议属于TCP/IP协议应⽤层的⼀部分。
序列化:将数据结构或对象转换成⼆进制串的过程。
反序列化:将在序列化过程中所⽣成的⼆进制串转换成数据结构或对象的过程。
序列化的作⽤:
1)把对象的字节序列持久化永久地保存到硬盘上。
例如:web服务器中的session对象,当有10万⽤户并发访问,就有可能出现10万个session对象,内存可能不够⽤,于是web容器就会把⼀些session先序列化到硬盘中,等要⽤的时候,再把保存在硬盘中的对象还原到内存中。
2)在⽹络上传送对象的字节序列。
例如:当两个进程在进⾏远程通信时,彼此可以发送各种类型的数据,⽆论是何种类型的数据,都会以⼆进制序列的形式在⽹络上传送,发送⽅需要把这个java对象转换为字节序列,才能在⽹络上传送,接收⽅则需要把字节序列再恢复为java对象。
JDK类库中的序列化API例⼦可以详见
serialVersionUID:序列化的版本号,凡是实现Serializable接⼝的类都有⼀个表⽰序列化版本标识符的静态变量,即private static final long serialVersionUID。
如何序列化⽣成serialVersionUID以及是否加这个UID导致的区别和为什么,详见
最好显⽰指定serialVersionUID,为什么?
因为原则上序列化后的数据中的serialVersionUID只有和当前类的serialVersionUID相同时才能被正常的反序列化。如果不显⽰指定,在⼀次执⾏序列化后,如果增加或者删除了某些成员变量,再次执⾏序列化,系统就会重新⽣成hash值然后赋给UID,导致反序列化的时候报error。
注意:
1.如果⼀个类想被序列化,需要实现Serializable接⼝。否则将抛出NotSerializableException异常,这是因为,在序列化操作过程中会对类型进⾏检查,要求被序列化的类必须属于Enum、Array和Serializable类型其中的任何⼀种,这也是为什么Serializable虽然是⼀个空接⼝,但是只要实现了该接⼝就能序列化和反序列化。
2.在类中增加writeObject 和 readObject ⽅法可以实现⾃定义序列化策略,虽然这俩⽅法不是被显⽰调⽤,但是因为在使⽤ObjectOutputStream的writeObject⽅法和ObjectInputStream的readObject⽅法时,会通过反射的⽅式调⽤到它们。
ArrayList源码中有关序列化的使⽤
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论