美文网首页
Jackson精解第4篇-@JacksonInject与@Jso

Jackson精解第4篇-@JacksonInject与@Jso

作者: 字母哥课堂 | 来源:发表于2020-09-22 07:32 被阅读0次

    Jackson是Spring Boot(SpringBoot)默认的JSON数据处理框架,但是其并不依赖于任何的Spring 库。有的小伙伴以为Jackson只能在Spring框架内使用,其实不是的,没有这种限制。它提供了很多的JSON数据处理方法、注解,也包括流式API、树模型、数据绑定,以及复杂数据类型转换等功能。它虽然简单易用,但绝对不是小玩具,更多的内容我会写成一个系列,5-10篇文章,请您继续关注我。

    本节继续为大家介绍在JSON反序列化过程中,如何使用@JacksonInject注解和@JsonAlias注解

    一、@JacksonInject注解

    在使用JSON格式进行反序列化的时候,我们经常有这样一些需求。我们从客户端或者其他渠道获取了一个JSON格式的数据对象,该对象包含若干个属性。但是我们在将JSON字符串反序列化的时候,需要给它加上一些默认数据,比如:

    • responseTime数据响应时间,赋值为当前时间即可;
    • 数据反序列化的操作人,赋值为系统当前用户等

    客户端返回给我们的数据本身不会携带这些附加信息,这个时候我们就可以使用JacksonInject注解,在JSON字符串反序列化为对象的时候,加上这些附加信息。下面是JacksonInject使用方法

    @Data
    public class PlayerStar {
    
      private String name;
      private Integer age;
      private String[] hobbies;    //业余爱好,数组
      private List<String> friends;   //  朋友
      private Map<String, BigDecimal> salary; //年收入 Map
    
      @JacksonInject("responseTime")      //注意这里
      private LocalDateTime responseTime;
    }
    

    我们来测试一下反序列化的过程,需要注意的是下文中的jsonInString中并不携带responseTime信息,是我们自己在反序列化的时候注入到java对象中的。

    @Test
    void testJSON2Object() throws IOException {
      //为responseTime赋值为当前值
      InjectableValues.Std iv = new InjectableValues.Std();
      iv.addValue("responseTime", LocalDateTime.now());
    
      ObjectMapper mapper = new ObjectMapper();
      mapper.setInjectableValues(iv);       //将可插入值,在反序列化过程中赋值给对象
      
      //将JSON字符串反序列化为java对象
      String jsonInString = "{\"name\":\"乔丹\",\"age\":45,\"hobbies\":[\"高尔夫球\",\"棒球\"]}";
      PlayerStar jordan = mapper.readValue(jsonInString, PlayerStar.class);
    
      System.out.println(jordan);
    
    }
    

    最终的反序列化结果,java 对象的toString()方法输出结果如下,可以看到多出一个responseTime赋值属性,值为当前时间

    PlayerStar(name=乔丹, age=45, hobbies=[高尔夫球, 棒球], friends=null, salary=null, responseTime=2020-09-22T06:41:09.192)
    

    二、按照数据类型type进行数据注入

    在上文的代码中,JSON字符串反序列化为对象,使用的是属性id的方法进行注入的

      @JacksonInject("responseTime")      //注意这里responseTime为属性id
      private LocalDateTime responseTime;
    
      InjectableValues.Std iv = new InjectableValues.Std();
      iv.addValue("responseTime", LocalDateTime.now());  //注意这里responseTime为属性id,而这要统一
    

    除了可以按照属性id进行数据的注入,还可以使用java type数据类型进行数据注入。这种方法在一个java 类中,多个成员变量数据类型重复的时候,比如定义多个LocalDateTime成员变量,用起来就不太方便了。所以还是建议大家使用属性id的方法进行注入数据注入。

      @JacksonInject
      private LocalDateTime responseTime;
    
      InjectableValues.Std iv = new InjectableValues.Std();
      iv.addValue(LocalDateTime.class, LocalDateTime.now());  //注意这里LocalDateTime.class
    

    三、 @JsonAlias注解

    当我们在开发过程中,可能在v1.0的版本中我们定义的PlayerStar类(上文)包含name属性,但是我们用着用着发现name这个单词太通用了,在很多的地方都是系统关键字;我们希望在v2.0版本中,给这个成员变量换一个名字,叫做starName,或者playerName。但是我们不希望用户废弃v1.0的接口。
    也就是说我们希望做到多版本兼容,客户端传送过来的JSON字符串,可以是name、可以是playerName、可以是starName。我们该怎么做?答案是使用@JsonAlias注解

    @Data
    public class PlayerStar {
    
      @JsonAlias({"starName", "playerName" })
      private String name;
    

    下面三种JSON格式数据都可以被正确的反序列化为PlayerStar对象,并为name成员变量赋值

    String jsonInString = "{\"name\":\"乔丹\",\"age\":45,\"hobbies\":[\"高尔夫球\",\"棒球\"]}";
    String jsonInString = "{\"starName\":\"乔丹\",\"age\":45,\"hobbies\":[\"高尔夫球\",\"棒球\"]}";
    String jsonInString = "{\"playerName\":\"乔丹\",\"age\":45,\"hobbies\":[\"高尔夫球\",\"棒球\"]}";
    

    欢迎关注我的博客,里面有很多精品合集

    • 本文转载注明出处(必须带连接,不能只转文字):字母哥博客

    觉得对您有帮助的话,帮我点赞、分享!您的支持是我不竭的创作动力! 。另外,笔者最近一段时间输出了如下的精品内容,期待您的关注。

    相关文章

      网友评论

          本文标题:Jackson精解第4篇-@JacksonInject与@Jso

          本文链接:https://www.haomeiwen.com/subject/ykpiyktx.html