前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >jackson的注解

jackson的注解

原创
作者头像
mariolu
修改2019-10-20 15:49:47
1.8K0
修改2019-10-20 15:49:47
举报

一、问题

1.1 真实案例

构造一个java对象,这个class在java内存中就是一个你想处理的对象。当然这个对象也需要存在redis,等待下次定时事件或者其他消费事件处理。另外这个对象也需要在网络上传输。所以你需要一个构造class的成员。

代码语言:java
复制
网络(JSON)       ~         内存(class 实例)     ~        redis存储(String)
                <- 序列化                       序列化->
                反序列化->                      反序列化<-

这个class对象在网络中就是一串json格式串。json格式串处理了网络流中需要知道消息的边界信息。而在redis存储中需要是把任何type的对象转化成string。所以需要进行一系列的序列化和反序列化转换。

1.2 传统做法

构建一个类testObject。考虑redis String对象和class对象的序列化/反序列化过程。需要这种类型的构造函数:

  • 反序列化:testObject(String or Map<String, String>){}
  • 序列化:Map<String, String>toRedisMap()

和网络json对象的序列化和反序列化过程:

代码语言:javascript
复制
public class  testObject
{
       private String m1;
       private List<String> m2;
       private XXX m3;
       
       // from network JSON
       testObject (){
       }
       
       //from redis String
       testObject(String or Map<String, String>) {
       }
       
       //copy from other class
       testObject(class or Map<String Key, Object Value>){
       }

       //for map type Redis oper api
       public Map<String, String> toRedisMap () {
     
       }
    
       //for get this class instance and manipulate
       public Map<String, Object> 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字段

还是上面那个例子:

代码语言:javascript
复制
public class testObject {
        @JsonProperty("firstName")
         public String _first_name
}

这里的class成员_first_name就和JSON的firstName的key映射上了。这里需要注意的是,这是比较一般都这样写。在序列化/反序列化都可以对应上。而已经过时的JsonGetter或者JsonSettor只会在序列化或者反序列化的单边转化中有效。

2.1.2 JsonCreator

注解在构造函数或者工厂类的实例化对象函数上。JsonCreator最常用还是和 JsonProperty使用,当然它也可以跟JsonValue搭配或者和JacksonInject搭配。

和JsonProperty搭配的写法如下:

代码语言:javascript
复制
@JsonCreator
public testObject(@JsonProperty("firstName") String _first_name) {
    this._first_name = first_name;
}

或者写个空的,然后JsonProperty注解在field上也可以。

代码语言:javascript
复制
public class testObject {
        @JsonProperty("firstName")
         public String _first_name;
         
         @JsonCreator
         public testObject() {}
}

2.2 JsonGetter和JsonSetter(过时的写法)

JsonSetter和JsonGetter搭配使用

@JsonGetterand@JsonSetterare 是过时的,现在一般用@JsonProperty写法。

三、原理

我们翻开了jaskson-annotations-2.9.9-sources.jar/com/faster.xml/jackson/annotation目录,查看了每个annotation的实现。

3.1 JsonProperty.java

代码语言:javascript
复制
@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又称元注解 (meta-annotation)。元注解可以和其他元注解组成更强大的注解。
  • Retention标识了是哪个阶段解析注解。

同时 这里其实还有看到几个可以设置的选项:

图1 JsonProperty的一些成员
图1 JsonProperty的一些成员
  • required:是否可忽略没有这个字段
  • access:可读写/只读/只写
  • defaultValue:默认值

3.2 JsonCreator.java

creator注解了工厂类的构造函数,可以用此方法反序列化后构造出对象。

代码语言:javascript
复制
public abstrat clientMapEntity{
       fromClient (Map<String, Object>, Type t){
               EntityFactory.getObjectMapper().convertValue(this, Map.class);
       }
}

3.3 其他如JsonIgnoreProperties.java

还有一些注解比如:忽略解析,不想解析输入的某些字段

代码语言:javascript
复制
@JsonIgnoreProperties("extra", "uselessValue")
public class Value {
        public int value;
}

这时可以解析这个json,不会报无法解析字段的异常,{“value”:42, "extra": "fluffy", "uselessValue": -12}

3.4 其他如JsonIgnore.java

不序列化到网络,不想输出

代码语言:javascript
复制
public class Value {
      public int value;
      @JsonIgnore
       public int internalValue
}. 

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、问题
    • 1.1 真实案例
      • 1.2 传统做法
        • 1.3 扩展问题
        • 二、解决问题
          • 2.1 JsonProperty和JsonCreator
            • 2.1.1 JsonProperty:设置序列化/反序列化的名字映射关系,映射class的成员和JSON的key字段
            • 2.1.2 JsonCreator
          • 2.2 JsonGetter和JsonSetter(过时的写法)
          • 三、原理
            • 3.1 JsonProperty.java
              • 3.2 JsonCreator.java
                • 3.3 其他如JsonIgnoreProperties.java
                  • 3.4 其他如JsonIgnore.java
                  相关产品与服务
                  文件存储
                  文件存储(Cloud File Storage,CFS)为您提供安全可靠、可扩展的共享文件存储服务。文件存储可与腾讯云服务器、容器服务、批量计算等服务搭配使用,为多个计算节点提供容量和性能可弹性扩展的高性能共享存储。腾讯云文件存储的管理界面简单、易使用,可实现对现有应用的无缝集成;按实际用量付费,为您节约成本,简化 IT 运维工作。
                  领券
                  问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档