Lombok@Builder类的序列化和反序列化

3,269 阅读3分钟

学习用Jackson库对Lombok @Builder注释的类进行序列化和反序列化。

出于演示的目的,我们使用Article ,该类有几个字段成员。我们在Lombok @Builder教程中已经创建了这个类。

@Builder
@Getter
@ToString
public class Article {

  private Long id;
  private String title;
  private List<String> tags;
}

1.序列化@Builder类

序列化过程非常简单,我们没有做任何额外的事情。它可以开箱即用。

1.1.Gson

使用Gson将*@Builder*类序列化的Java程序。

Article article = Article.builder(1L)
  .title("Test Article")
  .tag("Test Tag")
  .build();

//With Gson
Gson gson = new Gson();
String gsonJson = gson.toJson(article);

//Prints {"id":1,"title":"Test Article","tags":["Test Tag"]}
System.out.println(gsonJson); 

1.2.杰克逊

使用Jackson将*@Builder*类序列化的Java程序。

Article article = Article.builder(1L)
  .title("Test Article")
  .tag("Test Tag")
  .build();

//With Jackson
ObjectMapper mapper = new ObjectMapper();
String json = mapper.writeValueAsString(article);

//Prints {"id":1,"title":"Test Article","tags":["Test Tag"]}
System.out.println(json); 

2.对@Builder类进行反序列化

2.1.Gson

Gson对于反序列化也非常有效,不需要任何额外的配置。我们可以直接使用它。

String json = "{\"id\":1,\"title\":\"Test Title\",\"tags\":[\"Test Tag\"]}";

Gson gson = new Gson();
Article gsonArticle = gson.fromJson(json, Article.class);

//Prints Article(id=1, title=Test Title, tags=[Test Tag])
System.out.println(gsonArticle);

2.2.杰克逊

默认情况下,如果我们试图反序列化Article类,我们会得到运行时异常InvalidDefinitionException。在没有默认的no-args构造函数的情况下,Jackson无法找到构造该对象的方法。

ObjectMapper mapper = new ObjectMapper();
String json = "{\"id\":1,\"title\":\"Test Title\",\"tags\":[\"Test Tag\"]}";
Article article = mapper.readValue(json, Article.class);
System.out.println(article);
Exception in thread "main" com.fasterxml.jackson.databind.exc.InvalidDefinitionException: 
Cannot construct instance of `com.howtodoinjava.demo.lombok.Article` 
(no Creators, like default constructor, exist): cannot deserialize from Object value 
(no delegate- or property-based Creator)
 at [Source: (String)"{"id":1,"title":"Test Title","tags":["Test Tag"]}"; line: 1, column: 2]

2.2.1.Lombok @Jacksonized

如果你使用Jacksonized注解来实现反序列化的目的,使用@Jacksonized注解是最简单的解决方案。只要用*@Jacksonized*注解来注解@Builder类,我们就可以将JSON字符串转换为Java对象了。

@Builder(toBuilder = true)
@Getter
@ToString
@Jacksonized
public class Article {
    ...
}
String json = "{\"id\":1,\"title\":\"Test Title\",\"tags\":[\"Test Tag\"]}";

ObjectMapper mapper = new ObjectMapper();
Article article = mapper.readValue(json, Article.class);

//prints Article(id=1, title=Test Title, tags=[Test Tag])
System.out.println(article);

2.2.2.Jackson @JsonDeserialize 和 @JsonPOJOBuilder

请记住,@Jacksonized 是一个实验性的功能,在未来的版本中可能会被删除。另一种使@Builder与Jackson一起工作的方法是添加Jackson注解,这可以帮助Jackson弄清如何创建Article类的实例。

两个这样的注解是。

@Builder
@Getter
@ToString
@JsonDeserialize(builder = Article.ArticleBuilder.class)
public class Article {
  private Long id;
  private String title;
  private List<String> tags;

  @JsonPOJOBuilder(withPrefix="")
  public static class ArticleBuilder {
  }
}
String json = "{\"id\":1,\"title\":\"Test Title\",\"tags\":[\"Test Tag\"]}";

ObjectMapper mapper = new ObjectMapper();
Article article = mapper.readValue(json, Article.class);

//Prints Article(id=1, title=Test Title, tags=[Test Tag])
System.out.println(article);

3.总结

基于上述对话,Google Gson在用Lombok@Builder 注释的类上进行序列化和反序列化时效果最佳。它应该是首选方法,因为它开箱即用。

如果需要使用Jackson,我们有@Jacksonized 注释,只需很少的代码就能达到最佳效果。在未来,如果@Jacksonized不是Lombok的一部分,那么在库的升级过程中,我们可以使用其他Jackson注解来使反序列化工作。

祝你学习愉快!!

下载源代码