关于spring:Jackson精解第4篇JacksonInject与JsonAlias注解

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

  • 《序列化与反序列化外围用法-JSON框架Jackson精解第1篇》
  • 《非凡数据格式解决-JSON框架Jackson精解第2篇》
  • 《属性序列化自定义排序与字母表排序-JSON框架Jackson精解第3篇》

本节持续为大家介绍在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\":[\"高尔夫球\",\"棒球\"]}";

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

本文转载注明出处(必须带连贯,不能只转文字):字母哥博客 – zimug.com

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理