杰克逊顶部

通过。开始使用Spring 5和Spring Boot 2学习春天课程:

>>查看课程

1.介绍

在本文中,我们将比较g杰克逊用于将JSON数据序列化和反序列化到Java对象的api,反之亦然。

GSON和Jackson是完整的库,为Java提供了JSON数据绑定支持。每个都是积极开发的开源项目,提供了处理复杂的数据类型和支持Java泛型的支持。

在大多数情况下,这两个库都可以在不修改实体类的情况下反序列化为实体,这在开发人员无法访问实体源代码的情况下非常重要。

2.Gson Maven的依赖

<依赖项>  com.google.code.gson   GSON   $ {gson.version}  

您可以获得最新版本的GSON这里

3.Gson序列化

序列化将Java对象转换为JSON输出。考虑以下实体:

public class ActorGson {private String imdbId;私人dateOfBirth日期;私人<字符串>电影列表;// getters和setters, default constructor和field constructor省略}public class Movie {private String imdbId;私人字符串主任;私人列表< ActorGson >演员;//默认构造函数和字段构造函数

3.1。简单的序列化

让我们从Java的一个例子开始,以JSON序列化:

SimpleDateFormat SDF = New SimpleDateFormat(“DD-MM-YYYY”);Actorgson Rudyyoungblood = New Acrorgson(“NM2199632”,SDF.Parse(“21-09-1982”),arrays.aslist(“Apocalypto”,“Beatdown”,“Wind Walkers”));电影电影=新电影(“TT0472043”,“MEL GIBSON”,arrays.aslist(Rudyyoungblood));string serializedmovie = new gson()。Tojson(电影);

这将导致:

{"imdbId": "tt0472043", "导演":"梅尔·吉布森","演员":[{"imdbId": "nm2199632", "出生日期":" 1982年9月21日12:00:00 AM", "电影记录":["启示录","Beatdown", "Wind Walkers"]}]}

默认:

  • 所有属性都是序列化,因为它们没有空值价值
  • 出生日期使用默认的GSON日期模式翻译字段
  • 输出不格式化,json属性名称对应于Java实体

3.2。自定义序列化

使用自定义串行程序允许我们修改标准行为。我们可以使用HTML介绍输出格式化器,手柄空值值,从输出中排除属性,或添加新的输出。

ActorGsonSerializer修改JSON代码的生成Actorgson.元素:

公共类Actorgsonserializer实施JSonserializer  {私有SimpleDateFormat SDF = New SimpleDateFormat(“DD-MM-YYYY”);@override public jsonelement serialize(Actorgson Actor,键入类型,JsonserializationContext JsonserializationContext){JONObject Actorjsonobj = new jsonobject();Actorjsonobj.addproperty(“ imdb代码”,Actor.getImdbid());Actorjsonobj.addProperty(“出生日期”,Actor.getDateOfbirth ...()!= null?sdf.format(Actor.getDateOfbirth ...()):null);Actorjsonobj.addproperty(“ n°电影:”,Actor.getFilmography()!= null?Actor.getFilmography()。size():null);Actorjsonobj.addproperty(“filmography”,Actor.getFilmography()!= null?convertfilmography(Actor.getFilmography()):null);返回Actorjsonobj;私有字符串转换文件(列表 Filmography){return filmopmen.stream().collect(收集器.joining(“ - ”));}}

为了排除导演财产,呢@Expose注释用于我们要考虑的属性:

公共类meviewithnullvalue {@expose私有字符串imdbid;私人字符串主任;@Expepe私人列表演员;}

现在我们可以使用GSON对象创建使用格森布金尔班级:

Gson gson = new gsonbuilder().setprettyprinting().excludefieldswithoutexposeannottation().seriaLizenulls().disablehtmlescaping().disablehtmlescaping().registryypeadapter(Actorgson.class,New ActorgSonserializer()).create();SimpleDateFormat SDF = New SimpleDateFormat(“DD-MM-YYYY”);Actorgson Rudyyoungblood = New Acrorgson(“NM2199632”,SDF.Parse(“21-09-1982”),arrays.aslist(“Apocalypto”,“Beatdown”,“Wind Walkers”));moviewithnullvalue moviewithnullvalue = new moviewithnullvalue(null,“mel gibson”,arrays.aslist(Rudyyoungblood));string serializedmovie = gson.tojson(moviewithnullvalue);

结果如下:

{“imdbid”:null,“Actors”:[{“ imdb代码”:“nm2199632”,“出生日期”:“21-09-1982”,“ n°电影:”:3,“影片摄影”:“apocalypto-beatdown-wand walkers”}“}

请注意:

  • 输出被格式化
  • 有些属性名称已更改并包含HTML
  • 空值值,并且导演字段是省略了
  • 日期现在在dd-mm-yyyy格式
  • 一个新的财产是在场 -米电影
  • 影图是一个格式化的属性,而不是默认的JSON列表

4.Gson反序列化

4.1。简单的反序列化

Deserialization将JSON输入转换为Java对象。为演示输出,我们实现ToString()两个实体类中的方法:

公共类电影{@override public string tostring(){return“影片[imdbid =”+ imdbid +“,Director =”+ Director +“,Actors =”+ Actors +“]”;公共类Actorgson {@override public string tostring(){return“actorgson [imdbid =”+ imdbid +“,dateofbirth =”dateofbirth +“,feclographic =”+ filmography +“]”;} ...}

然后我们利用序列化JSON并通过标准的GSON Deserialization运行它:

字符串jsoninput =“{\”imdbid \“:\”tt0472043 \“,\”Actors \“:”+“[{\”imdbid \“:\”nm2199632 \“,\”dateofbirth \“:\”1982-09-21T12:00:00 + 01:00 \“,”+“\”影视\“:[”apocalypto“,\”beatdown \“,\”Wind Walkers \“]}}”;电影outputmovie = new gson()。fromjson(jsoninput,movie.class);outputmovie.tostring();

输出是我们我们的实体,填充了来自我们JSON输入的数据:

电影[imdbid = tt0472043,导演= null,actors = [actorgson [imdbid = nm2199632,dateofbirth = tue sep 21 04:00:00 pdt 1982,mempovock = [apocalypto,beatdown,风沃克]]]

与简单序列化器的情况一样:

  • JSON输入名称必须与Java实体名称对应,否则它们被设置为空。
  • 出生日期字段用默认的GSON日期模式翻译,忽略了时区。

4.2。自定义反序列化

使用自定义反序列化器允许我们修改标准反序列化器行为。在这种情况下,我们希望日期反映正确的时区出生日期。我们使用自定义Actorgsondeserializer在这一点Actorgson.实体实现这一目标:

公共类ActorgSondeserializer实现JSondEserializer  {Private SimpleDateFormat SDF = New SimpleDateFormat(“Yyyy-MM-DD'HH:MM:SS”);@override public Actorgson Deserialize(jsonelement json,键入类型,jsondeserializationcontext jsondeserializationcontext)抛出jsonparseexception {jsonobject jsonobject = json.getasjsonobject();jsonelement jsonimdbid = jsonobject.get(“imdbid”);jsonelement jsondateofbirth = jsonobject.get(“dateofbirth”);jsonarray jsonfilmography = jsonobject.getasjsonArray(“影片摄影”);arraylist  filmlist = new arraylist ();if(jsonfilmography!= null){for(int i = 0; i 

我们雇了一个SimpleDateFormat.解析器解析输入日期,计入时区。

注意,我们可以决定只为Date编写自定义反序列化器,但是Actorgsondeserializer提供反序列化过程的更详细视图。

另请注意,GSON方法不需要修改Actorgson.实体,这是理想的,因为我们不总是可以访问输入实体。我们在此处使用自定义Deserializer:

字符串jsoninput =“{\”imdbid \“:\”tt0472043 \“,\”Actors \“:”+“[{\”imdbid \“:\”nm2199632 \“,\”dateofbirth \“:\”1982-09-21T12:00:00 + 01:00 \“,+ \”影视\“:[\”apocalypto“,\”beatdown \“,\”Wind Walkers \“]}]}”Gson Gson = new gsonbuilder().registryypeadapter(Actorgson.class,New ActorgSondeserializer()).Create();电影outputmovie = gson.fromjson(jsoninput,movie.class);outputmovie.tostring();

输出类似于简单的Deserializer结果,除了日期使用正确的时区:

电影[imdbId=tt0472043, director=null, actors=[ActorGson

5.杰克逊Maven依赖

<依赖> < groupId > com.fasterxml.jackson。核心< / groupId > < artifactId > jackson-databind < / artifactId > <版本> ${杰克逊。版本}< /版本> < / >的依赖

你可以获得最新版本的杰克逊这里

6.杰克逊序列化

6.1。简单的序列化

在这里,我们将使用Jackson使用以下实体获取与GSON的相同序列化内容。请注意,实体的Getters / Setter必须公开:

public class ActorJackson {private String imdbId;私人dateOfBirth日期;私人<字符串>电影列表;//需要的getter和setter,默认构造函数//和字段构造函数细节省略}私人字符串主任;私人列表< ActorJackson >演员;SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy");ActorJackson rudyYoungblood = new ActorJackson("nm2199632",sdf.parse("21-09-1982"),数组。asList(比如说电影《启示》,“杀威棒”,“风步行者”));Movie Movie = new Movie("tt0472043","Mel Gibson", Arrays.asList(rudyYoungblood));ObjectMapper = new ObjectMapper(); String jsonResult = mapper.writeValueAsString(movie);

输出如下:

{“imdbid”:“tt0472043”,“导演”:“mel gibson”,“演员”:[{“imdbid”:“nm2199632”,“datefbirth”:401439600000,“moppovaly”:[“apocalypto”,“beatdown”,“Wind Walkers”]}]}]}

一些值得注意的事项:

  • ObjectMapper.是我们的杰克逊序列化器/ deserializer
  • 输出JSON未格式化
  • 默认情况下,Java日期已翻译为价值

6.2。自定义序列化

我们可以为Actorjackson.为我们的实体扩展stdserializer来源生成。再次注意到实体的Getters / Setter必须公开:

public class ActorJacksonSerializer extends StdSerializer {private SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy");public ActorJacksonSerializer(Class t) {super(t);} @Override public void serialize(actor jackson actor, JsonGenerator JsonGenerator, SerializerProvider SerializerProvider) throws IOException {JsonGenerator . writestartobject ();jsonGenerator。writeStringField(“imdbId actor.getImdbId ());jsonGenerator。writeObjectField("dateOfBirth", actor.getDateOfBirth() != null ?sdf.format (actor.getDateOfBirth()):零);jsonGenerator。writeNumberField("N°电影:",actor.getFilmography() != null ? actor.getFilmography().size() : null); jsonGenerator.writeStringField("filmography", actor.getFilmography() .stream().collect(Collectors.joining("-"))); jsonGenerator.writeEndObject(); } }

我们创建了电影实体,以允许忽略导演字段:

公共类meviewithnullvalue {私有字符串imdbid;@jsonignore私有弦绳;私人列表< ActorJackson >演员;//所需的getter和setter,默认构造函数//和字段构造函数详细信息删除}

现在我们可以使用自定义ObjectMapper.创建和设置:

SimpleDateFormat SDF = New SimpleDateFormat(“DD-MM-YYYY”);Actorjackson Rudyyoungblood = New Actorjackson(“NM2199632”,SDF.Parse(“21-09-1982”),arrays.aslist(“Apocalypto”,“Beatdown”,“Wind Walkers”));moviewithnullvalue moviewithnullvalue = new moviewithnullvalue(null,“mel gibson”,arrays.aslist(Rudyyoungblood));SimpleModule模块=新SimpleModule();module.addserializer(新的ActorJackSonserializer(Actorjackson.class));ObjectMapper = new ObjectMapper();字符串jsonresult = mapper.registerermodule(模块).writer(new defaultprettyprinter()).writevalueastring(moviewithnullvalue);

输出格式化json处理空值值,格式化日期,不包括导演字段并显示新的输出:

{“actors”:[{“imdbid”:“nm2199632”,“datefbirth”:“21-09-1982”,“n°电影:”:3,“影片摄影”:“apocalypto-beatdown-walkers”}“],“imdbid”:null}

7.杰克逊反序列化

7.1。简单的反序列化

为演示输出,我们实现ToString()杰克逊实体类中的方法:

公共类电影{@override public string tostring(){return“影片[imdbid =”+ imdbid +“,Director =”+ Director +“,Actors =”+ Actors +“]”;公共类ActorJackson {@override public string toString(){return“Actorjackson [Imdbid =”+ imdbid +“,dateofbirth =”dateofbirth +“,feclographic =”+ filmography +“]”;} ...}

然后我们利用序列化JSON并通过杰克逊解串化运行:

字符串jsonInput =“{\”imdbid \“:\”tt0472043 \“,\”Actors \“:[{\”imdbid \“:\”nm2199632 \“,\”dateofbirth \“:\”1982-09-21T12:00:00 + 01:00 \“,”影视\“:[\”apocalypto“,\”beatdown \“,\”Wind Walkers \“]}]}”ObjectMapper = new ObjectMapper();电影电影= mapper.readvalue(jsoninput,movie.class);

输出是我们我们的实体,填充了来自我们JSON输入的数据:

电影[imdbId=tt0472043, director=null, actors=[ActorJackson] [imdbId=nm2199632, dateOfBirth=Tue Sep 21 04:00:00 PDT 1982, filmgraphy =[启示,Beatdown,风行]]]].

与简单序列化器的情况一样:

  • JSON输入名称必须与Java实体名称对应,否则它们被设置为空值,
  • 出生日期字段用默认的杰克逊日期模式翻译,忽略了时区。

7.2。自定义反序列化

使用自定义反序列化器允许我们修改标准反序列化器行为。

在这种情况下,我们希望日期反映正确的时区出生日期,所以我们添加了一个DateFormatter到我们的JacksonObjectMapper.:

字符串jsoninput =“{\”imdbid \“:\”tt0472043“,\”Director \“:\”Mel Gibson \“,\”Actors \“:[{\”imdbid \“:\”NM2199632 \“,“dateofbirth \”:\“1982-09-21T12:00:00 + 01:00 \”,\“影视\”:[“apocalypto”,\“beatdown \”,\“Wind Walkers”]}]}“;ObjectMapper = new ObjectMapper();dateformat df = new simpleDateFormat(“yyyy-mm-dd't'hh:mm:ss”);Mapper.SetDateFormat(DF);电影电影= mapper.readvalue(jsoninput,movie.class);movie.tostring();

该输出反映了具有日期的正确时区:

电影[IMDBID = TT0472043,Director = Mel Gibson,Actors = [Actorjackson [IMDBID = NM2199632,DateObirth = Tue Sep 21 12:00:00 PDT 1982,Feconography = [Apocalypto,Beatdown,Wind Walkers]]]

这种解决方案很干净,简单。

或者,我们本可以为此创建自定义解串器Actorjackson.类,使用我们注册此模块ObjectMapper.,并使用@JsonDeserialize注释的Actorjackson.实体。

该方法的缺点是需要修改实体,当我们无法访问输入实体类时,这可能不是案例的理想选择。

结论

Gson和jackson都是序列化/反序列化JSON数据的好选项,易于使用和良好的记录。

GSON的优势:

  • 简单的toJson/fromJson在简单的情况下
  • 对于反序列化,不需要访问Java实体

杰克逊的优势:

  • 内置于所有JAX-RS(泽西,Apache CXF,RESTEASY,RESTLET)和Spring框架中
  • 广泛的注释支持

你可以找到密码g杰克逊在github上。

杰克逊底部

通过。开始使用Spring 5和Spring Boot 2学习春天课程:

>>查看课程
评论在本文上关闭!