几种json解析方式javaBean与json的相互序列化

一、json简介

What?
json是一种数据格式,格式灵感来源于JavaScript,作为开发中重要的数据交换格式,它有着几大特点:

  • 轻量级的文本数据交换格式。
  • 具有自我描述性,易理解。
  • 易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率。
  • JSON可通过网络进行传输。

语法格式:
JSON结构: 对象{},数组[]
对象表示:{key:value, key: value, ...}

示例:

   	{
   		"name": "Eliza白",
   		"hight": 1.8,
   		"really": false
   	}

很好理解,键值和另一个键值间要有逗号隔开。上面这个例子就是一个对象。
这个对象中包含三个属性name、hight和really, 其值分别是"Eliza白"字符串和1.8这个number和false这个boolean
数组表示:{value, value, ...}
示例:

	["Elizabeth", "Elizabai", "Eliza白"]

同我们的编程语言一样,json对象和包含数组,数组可包含对象。
示例:

	{
		"Array": [{
			"Elizabeth": 1.8
		}, {
			"Elizabai": 1.9
		}, {
			"Eliza白": 2.0
		}]
	}

二、java中的json解析
因为json使用了JavaScript语法,虽然JavaScript能很简单的处理json,但java就不一样了,就需要解析成java对象才能使用。我就记一下几种解析方式吧:

  1. JSONObject
  2. GSON
  3. FastJSON
  4. JackJSON
    以这个json数据为例:
{
	"name": "Eliza白",
	"height": 1.8,
	"carList": [{
		"id": 1,
		"brand": "爱玛",
		"name": "爱玛电动车"
	}, {
		"id": 2,
		"brand": "东风",
		"name": "东风汽车"
	}]
}

JSONObject:

生成json

直接构建:

fun jsonObject(view: View) {
        val car1 = JSONObject()
        car1.put("id", 1)
        car1.put("brand", "爱玛")
        car1.put("name", "艾玛电动车")
        val car2 = JSONObject()
        car2.put("id", 1)
        car2.put("brand", "东风")
        car2.put("name", "东风汽车")
        val carList = JSONArray()
        carList.put(car1)
        carList.put(car2)
        val people = JSONObject()
        people.put("name", "Elizabeth")
        people.put("height", 1.8f)
        people.put("carList", carList)
        Log.i("print", people.toString())
    }
print: {"name":"Elizabeth","height":1.8,"carList":[{"id":1,"brand":"爱玛","name":"艾玛电动车"},{"id":1,"brand":"东风","name":"东风汽车"}]}

用Map构建:

fun jsonObject(view: View) {
        val hashMap = HashMap<String, Any>()
        val car1 = JSONObject()
        car1.put("id", 1)
        car1.put("brand", "爱玛")
        car1.put("name", "艾玛电动车")
        val car2 = JSONObject()
        car2.put("id", 1)
        car2.put("brand", "东风")
        car2.put("name", "东风汽车")
        val carList = ArrayList<JSONObject>()
        carList.add(car1)
        carList.add(car2)
        hashMap.put("name", "Elizabeth")
        hashMap.put("height", 1.8f)
        hashMap.put("carList", carList)
        val people = JSONObject(hashMap.toString())
        Log.i("print", people.toString())
    }
解析:
fun jsonObject(view: View) {
        val file = File(""+cacheDir+"/myjson.json")
        val fileInputStream = FileInputStream(file)
        val bufferedReader = BufferedReader(InputStreamReader(fileInputStream))
        val stringBuilder = StringBuilder()
        try {
            while (true){
                var line = bufferedReader.readLine()
                if (line == null) break
                stringBuilder.append(line)
            }
        }finally {
            bufferedReader.close()
        }
        val json = stringBuilder.toString()
        val people = JSONObject(json)
        val carList = people.getJSONArray("carList")
        Log.i("print", "peopleName: "+people.getString("name"))
        Log.i("print", "peopleHeight: "+people.getDouble("height"))
        for (i in 0 until carList.length()){
            val car = carList.get(i) as JSONObject
            Log.i("print", "carName: "+ car.getInt("id"))
            Log.i("print", "carName: "+ car.getString("brand"))
            Log.i("print", "carName: "+ car.getString("name"))
        }

    }
04-11 22:39:20.006 8246-8246/com.example.actiondispatch I/print: peopleName: Eliza白
04-11 22:39:20.006 8246-8246/com.example.actiondispatch I/print: peopleHeight: 1.8
04-11 22:39:20.006 8246-8246/com.example.actiondispatch I/print: carName: 1
04-11 22:39:20.006 8246-8246/com.example.actiondispatch I/print: carName: 爱玛
04-11 22:39:20.006 8246-8246/com.example.actiondispatch I/print: carName: 爱玛电动车
04-11 22:39:20.006 8246-8246/com.example.actiondispatch I/print: carName: 2
04-11 22:39:20.006 8246-8246/com.example.actiondispatch I/print: carName: 东风
04-11 22:39:20.006 8246-8246/com.example.actiondispatch I/print: carName: 东风汽车

javabean方式,由于android自带的不能用,我想搞,添加依赖弄了半天,也没积分下载别人的,以后补吧。

下面只讲java对象与json转换,字符串转换就不写了。

GSON

添加依赖

implementation 'com.google.code.gson:gson:2.8.6'

几个注意地方:

  • 推荐把成员变量都声明成private
  • 被@Transient注解的字段不会被序列化和反序列化
  • 如果字段值为null,不参与序列化
  • 反序列化时如果某个字段找不到对应值,会赋值为null
  • 内部类不会被序列化和反序列化

常用注解:

  • @SerializedName(“ID”)
    示例:
    @SerializedName("User_Name")
    var name
    {“User_Name”, “Elizabeth”}就可以解析到这个字段,序列化时也会转换成User_Name。
    同时还可以指定更多的名字:
    @SerializedName(value = "User_Name", alternate = {"Username", "UserName"})
  • @Expose(serialize = false, deserialize = false)
    表示指定字段能够序列化和反序列化
    同时需要通过builder开启生效:
    开启后也需要在需要序列化或反序列化的字段上使用该注解标明。
  val builder = GsonBuilder()
  builder.excludeFieldsWithoutExposeAnnotation()
  val json:String = builder.create().toJson(people)
  • @Since(1.0) 高于1.0版本可用
  • @Until(1.0) 低于1.0版本可用
    同时需要用builder开启
builder.setVersion(2.0)
  • @JsonAdapter(MyTypeAdapter.class)
    注解到javabean上,参数是继承了TypeAdapter的类.class,这样就不用GsonBuilder.registerTypeAdapter(MyTypeAdapter.class)
    JavaBean:
data class People(var name: String, var height: Float, var carList: ArrayList<Car>)

data class Car(var id: Int, var brand: String, var name: String)

java对象生成json:

fun jsonObject(view: View) {
        val carList = ArrayList<Car>()
        carList.add(Car(1, "爱玛", "爱玛电动车"))
        carList.add(Car(2, "东方", "东风汽车"))
        val people = People("Elizabeth", 1.8f, carList)
        val json = Gson().toJson(people)
        Log.i("print", json)
    }
print: {"carList":[{"brand":"爱玛","id":1,"name":"爱玛电动车"},{"brand":"东方","id":2,"name":"东风汽车"}],"height":1.8,"name":"Elizabeth"}

解析:

fun jsonObject(view: View) {
        val file = File(""+cacheDir+"/myjson.json")
        val fileInputStream = FileInputStream(file)
        val bufferedReader = BufferedReader(InputStreamReader(fileInputStream))
        val stringBuilder = StringBuilder()
        try {
            while (true){
                var line = bufferedReader.readLine()
                if (line == null) break
                stringBuilder.append(line)
            }
        }finally {
            bufferedReader.close()
        }
        val json = stringBuilder.toString()
        val fromJson = Gson().fromJson(json, People::class.java)
        Log.i("print", fromJson.toString())
    }

当然根据需要我们还可用GsonBuilder进行以上序列化和反序列化

TypeAdapter的使用
TypeAdapter用来处理格式问题
修改下json:

{"name": "Eliza白","height": 1.8,"carList": [{"id": null,"brand": "爱玛","name": "爱玛电动车"}, {"id": 2,"brand": "东风","name": "东风汽车"}]}

我们把其中一个id值改为了null
直接用gson解析出来:

People(name=Eliza白, height=1.8, carList=[Car(id=0, brand=爱玛, name=爱玛电动车), Car(id=2, brand=东风, name=东风汽车)])

id变成了0
我们可以利用自定义TypeAdapter转换:

class MyTypeAdapter : TypeAdapter<Int>() {
    override fun write(out: JsonWriter?, value: Int?) {
        if (value == null){
            out?.value(-1)
        }else{
            out?.value(value)
        }
    }
    override fun read(input: JsonReader?): Int {
        if (input?.peek() == com.google.gson.stream.JsonToken.NULL){
            input?.nextNull()
            return -1;
        }else {
            return input?.nextInt()!!
        }
    }
}

继承TypeAdapter并实现两个方法,一个用来序列化,一个用来反序列化
使用:

 val json = stringBuilder.toString()
val gson = GsonBuilder().registerTypeAdapter(Int::class.java, MyTypeAdapter())
val people = gson.create().fromJson<People>(json, People::class.java)

结果:

People(name=Eliza白, height=1.8, carList=[Car(id=-1, brand=爱玛, name=爱玛电动车), Car(id=2, brand=东风, name=东风汽车)])

JsonSerializer 和JsonDeserializer
TypeAdapter精简版
只接管序列化的过程就用 JsonSerializer ,只接管反序列化的过程就用 JsonDeserializer.
TypeToken的使用
解决泛型问题
我们改下我们的JavaBean:

data class People<T>(var name: String, var height: Float, var carList: ArrayList<Car<T>>?)

data class Car<T>(var id: T, var brand: String, var name: String)

Gson解析时无法知道T要转成上面类型,这时候就需要TypeToken了

fun jsonObject(view: View) {
        val file = File(""+cacheDir+"/myjson.json")
        val fileInputStream = FileInputStream(file)
        val bufferedReader = BufferedReader(InputStreamReader(fileInputStream))
        val stringBuilder = StringBuilder()
        try {
            while (true){
                var line = bufferedReader.readLine()
                if (line == null) break
                stringBuilder.append(line)
            }
        }finally {
            bufferedReader.close()
        }
        val json = stringBuilder.toString()
        val type: Type? = object : TypeToken<People<String>>() {}.type
        val gson =
            GsonBuilder()
                //.registerTypeAdapter(Int::class.java, MyTypeAdapter())
        val people = gson.create().fromJson<People<String>>(json, type)

        Log.i("print", people.toString())
        Log.i("print", people.carList?.get(0)?.id)
    }

满足大家好奇心
json看一下:

{"name": "Eliza白","height": 1.8,"carList": [{"id": 1,"brand": "爱玛","name": "爱玛电动车"}, {"id": 2,"brand": "东风","name": "东风汽车"}]}

输出看一下:

04-12 16:58:52.173 13612-13612/com.example.actiondispatch I/print: People(name=Eliza白, height=1.8, carList=[Car(id=1, brand=爱玛, name=爱玛电动车), Car(id=2, brand=东风, name=东风汽车)])
04-12 16:58:52.174 13612-13612/com.example.actiondispatch I/print: 1

FastJSON:

依赖

implementation 'com.alibaba:fastjson:1.2.68'

序列化:

fun jsonObject(view: View) {
        val carList:ArrayList<Car> = ArrayList<Car>()
        carList.add(Car(1, "爱玛", "爱玛电动车"))
        carList.add(Car(2, "东方", "东风汽车"))
        val people = People("Elizabeth", 1.8f, carList)
        val json = JSON.toJSONString(people)
        Log.i("print",json)
    }

反序列化
由于FastJson需要个默认无参构造参数所以我们改下javabean:

class People{
    var name: String = ""
    var height: Float = -1f
    var carList: ArrayList<Car>? = null
    constructor()
    override fun toString(): String {
        return "People(name='$name', height=$height, carList=$carList)"
    }
}
class Car {
    var id: Int = 0
    var brand: String = ""
    var name: String = ""

    constructor ()

    override fun toString(): String {
        return "Car(id=$id, brand='$brand', name='$name')"
    }
}
fun jsonObject(view: View) {
        val file = File(""+cacheDir+"/myjson.json")
        val fileInputStream = FileInputStream(file)
        val bufferedReader = BufferedReader(InputStreamReader(fileInputStream))
        val stringBuilder = StringBuilder()
        try {
            while (true){
                var line = bufferedReader.readLine()
                if (line == null) break
                stringBuilder.append(line)
            }
        }finally {
            bufferedReader.close()
        }
        val json = stringBuilder.toString()
        val fastJson = JSON.parseObject(json, People::class.java)
        Log.i("print",fastJson.toString())
    }

泛型:

package com.example.actiondispatch

class People<T>{
    var name: String = ""
    var height: Float = -1f
    var carList: ArrayList<Car<T>>? = null
    constructor()
    override fun toString(): String {
        return "People(name='$name', height=$height, carList=$carList)"
    }
}
class Car<T> {
    var id: T? = null
    var brand: String = ""
    var name: String = ""

    constructor ()

    override fun toString(): String {
        return "Car(id=$id, brand='$brand', name='$name')"
    }
}

只需修改:

val fastJson = JSON.parseObject(json, object: TypeReference<People<String>>(){})

JackJSON:

依赖

implementation 'com.fasterxml.jackson.core:jackson-databind:2.11.0.rc1'
implementation 'com.fasterxml.jackson.core:jackson-core:2.11.0.rc1'
implementation 'com.fasterxml.jackson.core:jackson-annotations:2.11.0.rc1'

常见注解
@JsonIgnore 注解的字段将不会进行序列化
@JsonFormat(pattern = " ")格式化
序列化:

fun jsonObject(view: View) {
        val objectMapper = ObjectMapper()
        val carList:ArrayList<Car> = ArrayList<Car>()
        carList.add(Car(1, "爱玛", "爱玛电动车"))
        carList.add(Car(2, "东方", "东风汽车"))
        val people = People("Elizabeth", 1.8f, carList)
        val json = objectMapper.writeValueAsString(people);
        Log.i("print",json)
    }

反序列化:
(同样javabean也要无参构造)

fun jsonObject(view: View) {
        val file = File(""+cacheDir+"/myjson.json")
        val fileInputStream = FileInputStream(file)
        val bufferedReader = BufferedReader(InputStreamReader(fileInputStream))
        val stringBuilder = StringBuilder()
        try {
            while (true){
                var line = bufferedReader.readLine()
                if (line == null) break
                stringBuilder.append(line)
            }
        }finally {
            bufferedReader.close()
        }
        val json = stringBuilder.toString()
        val objectMapper = ObjectMapper()
        val readValue = objectMapper.readValue(json, object: com.fasterxml.jackson.core.type.TypeReference<People<String>>(){})
        Log.i("print",readValue.toString())
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值