json反序列化时如何创建对象

JavaScript027

json反序列化时如何创建对象,第1张

当json在反序列化时,默认选择类的无参构造函数创建类对象,当没有无参构造函数时会报错,@JsonCreator作用就是指定反序列化时用的参构造函数。构造方法的参数前面需要加上@JsonProperty,否则会报错。Json是一种轻量级的数据交换格式(也叫数据序列化方式)。Json采用完全独立于编程语言的文本格式来存储和表示数据。简洁和清晰的层次结构使得 Json 成为理想的数据交换语言。 易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率。数据序列化格式还有:xml、protobuf,其中protobuf存储数据更为高效,在企业级项目中更常见。——RPC项目用的就是protobuf 序列化是将数据结构或是对象转换为二进制串(字节序列)的过程,也就是将具有一定结构的对象转换为可以存储或传输的形式。在序列化期间,对象将其当前状态写入到临时或持久性存储区(如硬盘)。这样我们就可以通过从存储区中读取或反序列化对象的状态,重新创建该对象。

反序列化就是上述的逆过程。

比如我们把json格式的对象转换成字符串,再转换成char*,这样就能在网络上传输,或者写进硬盘——由结构化的数据转成地址值反过来我们把从网络上接收到的字符串对象转成json对象,就是重新构建出json对象结构,这就是反序列化可以看到msg对应的值是一个json,两个json赋值给msg后变成了一个json,而且,js["msg"]["liu shuo"]的意义就是先访问js的键msg,再访问msg中的键liu shuo,还有就是,liu和zhang的顺序也被改了,因为两者在msg这个json里面就是键,是有顺序的在Asp.Net网站开发的过程中,很多时候会遇到对象的序列化和反序列化操作,Newtonsoft.Json组件是专门用来序列化和反序列化操作的一个功能组件,引入这个DLL组件后,就可使用JsonConvert.DeserializeObject方法来反序列化字符串为对象,JsonConvert.DeserializeObject方法有2个重载方法签名,都是可用于C#中字符串的反序列化操作。

在具体需要字符串反序列化的地方调用JsonConvert.DeserializeObject方法。具体例子如下:有个前台传入的序列化字符串jsonStr,需要将之反序列化为TestModel对象,可使用下列语句进行实现。序列化(Serialization),有的人也称之为反解析。指的是将对象的状态信息转换为可以存储或传输的形式的过程。

而反序列化,有的人成为解析。指的就是序列化的逆过程。

图1. 序列化与反序列化

例如,定义如下结构体 book,我们可以创建一个实体对象,bookObj,此时 bookObj 是一个在程序中的实体对象。若我要存储这个对象,或者将其通过 HTTP 进行传输,我就需要将其进行序列化为可以进行存储或者传输的文件形式,例如 json。

package main

import (

"fmt"

"time"

)

type Book struct {

Name string

Author string

PublishTime time.Time

}

func main() {

bookObj := &Book{

Name:"Go 语言基础入门",

Author: "fxtack",

PublishTime: time.Now(),

}

fmt.Println(bookObj)

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

若进行序列化,序列化后的 bookObj 对象的 JSON 格式为(注意,结构体字段名与 JSON 中的字段名并不是完全相等的):

{

"name": "Go 语言基础入门",

"author": "fxtack",

"publishTime": "2021-07-03T18:23:57.7451495+08:00"

}

1

2

3

4

5

1

2

3

4

5

这样我就可以通过存储和传输 json 来实现对 bookObj 对象的存储和传输了。

相应的,如果需要这个对象而读取 json 文件,或者传输的接收者收到这个对象的 json 并打算使用这个对象时,就需要通过反序列化,将其从 json 的格式重新转化为程序中的对象。

//序列化JSON.stringify(json)

var jsonArray = []

jsonArray.push({a:1,b:2})

jsonArray.push({a:2,b:3})

console.log('jsonArray:'+jsonArray)

console.log('jsonArray1:'+JSON.stringify(jsonArray))

//反序列化JSON.parse(json)

var a = JSON.stringify(jsonArray)

var b = JSON.parse(a)

b..push({a:3,b:4})

console.log('b:'+b)

console.log('b1:'+JSON.stringify(b))

上面的代码执行后的输出结果:

[2016-05-21 11:59:52.764] [INFO] console - jsonArray:[object Object],[object Object]

[2016-05-21 11:59:52.765] [INFO] console - jsonArray1:[{"a":1,"b":2},{"a":2,"b":3}]

[2016-05-21 11:59:52.765] [INFO] console - b:[object Object],[object Object],[object Object]

[2016-05-21 11:59:52.766] [INFO] console - b1:[{"a":1,"b":2},{"a":2,"b":3},{"a":3,"b":4}]

或者

即 sample_data 的 value 可能是 List<String> 类型的,也可能是 List<FactoryDataBean> 类型的,ct 的 value 对象对应的 javaBean 为 CtBean<CTGL_TYPE>,为了保证 sample_data 既能兼容 String 又能兼容 FactoryDataBean ,所以要添加泛型类型 CTGL_TYPE

自定义 JsonSerializer 来告诉 Gson 如何将指定的 json 字符串 反序列化为指定的类型/序列化为 Json 字符串。

直接反序列化为一种类型,如果类型转换失败则再转换为另一种类型,适用于没有 type 的情况,如果多次转换会消耗性能。

通过 type 来判断究竟反序列化为哪种类型

解决方案:先把 linkedTreeMap 对象转成 json 字符串,然后再转成 JavaBean

实际应用如下: