一、问题
1.1 真实案例
构造一个java对象,这个class在java内存中就是一个你想处理的对象。当然这个对象也需要存在redis,等待下次定时事件或者其他消费事件处理。另外这个对象也需要在网络上传输。所以你需要一个构造class的成员。
网络(JSON) ~ 内存(class 实例) ~ redis存储(String)
<- 序列化 序列化->
反序列化-> 反序列化<-这个class对象在网络中就是一串json格式串。json格式串处理了网络流中需要知道消息的边界信息。而在redis存储中需要是把任何type的对象转化成string。所以需要进行一系列的序列化和反序列化转换。
1.2 传统做法
构建一个类test 。考虑redis String对象和class对象的序列化/反序列化过程。需要这种类型的构造函数:
- 反序列化:test (String or Map<String, String>){}
- 序列化:Map<String, String>toRedisMap()
和网络json对象的序列化和反序列化过程:
public class test
{
private String m1;
private List<String> m2;
private XXX m3;
// from network JSON
test (){
}
//from redis String
test (String or Map<String, String>) {
}
//copy from other class
test (class or Map<String Key, Value>){
}
//for map type Redis oper api
public Map<String, String> toRedisMap () {
}
//for get this class instance and manipulate
public Map<String, > toClientMap() {
}
//for print
@Override
public String toString() {
}
//for save key
@Override
public int hashCode() {
}
}1.3 扩展问题
序列化和反序列化的过程:还需要实现一些合规检查。检查是否允许非空value,是否可解析(比如说数字是否可解析),大小写,,大小写,有些字段只存在于某一阶段(比如说推送信息的一些控制字段,不会push给客户端),更换key的名字等。这些完整性实现需要引入必要的代码,而且这些跟业务逻辑无关的代码引入也会导致后期维护的困难。
二、解决问题
Jackson用注解的形式解决了以上问题,让代码更简洁,也,只需要安装Jackson的Annotation注解使用方式写法即可。Jackson帮助完成了类的序列化/反序列化以及必要的检查。
2.1 JsonProperty和JsonCreator
JsonCreator和JsonProperites搭配使用
2.1.1 JsonProperty:设置序列化/反序列化的名字映射关系,映射class的成员和JSON的key字段
还是上面那个例子:
public class test {
@JsonProperty("firstName")
public String _first_name
}这里的class成员_first_name就和JSON的firstName的key映射上了。这里需要注意的是,这是比较一般都这样写。在序列化/反序列化都可以对应上。而已经过时的JsonGetter或者JsonSettor只会在序列化或者反序列化的单边转化中有效。
2.1.2 JsonCreator
注解在构造函数或者工厂类的实例化对象函数上。JsonCreator最常用还是和 JsonProperty使用,当然它也可以跟JsonValue搭配或者和JacksonInject搭配。
和JsonProperty搭配的写法如下:
@JsonCreator
public test (@JsonProperty("firstName") String _first_name) {
this._first_name = first_name;
}或者写个空的,然后JsonProperty注解在field上也可以。
public class test {
@JsonProperty("firstName")
public String _first_name;
@JsonCreator
public test () {}
}2.2 JsonGetter和JsonSetter(过时的写法)
JsonSetter和JsonGetter搭配使用
@JsonGetterand@JsonSetterare 是过时的,现在一般用@JsonProperty写法。
三、原理
我们翻开了jaskson-annotations-2.9.9-sources.jar/com/faster. /jackson/annotation目录,查看了每个annotation的实现。
3.1 JsonProperty.java
@Target({ElementType.ANNOTATION_TYPE, ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@JacksonAnnotation
public @interface JsonProperty
{
}这里标识了元注解 JacksonAnnotaion的@Target, @Retention, @JacksonAnnotation的实现。
- Target表面了这个annotation的可应用场合。包括TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE, ANNOTATION_TYPE, PACKAGE, TYPE_PARAMETER, TYPE_USE, MODULE。这里表面可用于成员变量,方法和参数。ElementType.ANNOTATION_TYPE又称元注解 ( -annotation)。元注解可以和其他元注解组成更强大的注解。
- Retention标识了是哪个阶段解析注解。
同时 这里其实还有看到几个可以设置的选项:
- required:是否可忽略没有这个字段
- access:可读写/只读/只写
- defaultValue:默认值
3.2 JsonCreator.java
creator注解了工厂类的构造函数,可以用此方法反序列化后构造出对象。
public abstrat clientMapEntity{
fromClient (Map<String, >, Type t){
EntityFactory.get Mapper().convertValue(this, Map.class);
}
}3.3 其他如JsonIgnoreProperties.java
还有一些注解比如:忽略解析,不想解析输入的某些字段
@JsonIgnoreProperties("extra", "uselessValue")
public class Value {
public int value;
}这时可以解析这个json,不会报无法解析字段的异常,{“value”:42, "extra": "fluffy", "uselessValue": -12}
3.4 其他如JsonIgnore.java
不序列化到网络,不想输出
public class Value {
public int value;
@JsonIgnore
public int internalValue
}. 继续阅读与本文标签相同的文章
-
根本停不下来!苹果发布iOS 13.2新测试版Beta 3
2026-05-15栏目: 教程
-
上海健康保险交易平台上线 首款针对老年患癌群体
2026-05-15栏目: 教程
-
Power BI 10月产品功能更新-视频上线
2026-05-15栏目: 教程
-
小公司如何抓住微信小程序的大红利?
2026-05-15栏目: 教程
-
瓯海新增省级4家工业设计中心
2026-05-15栏目: 教程
