学习用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类的实例。
两个这样的注解是。
- @JsonDeserialize- 用于指定自定义反序列化器来解读JSON。
- @JsonPOJOBuilder- 用来配置生成器类的细节。
@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注解来使反序列化工作。
祝你学习愉快!!