2019.12更新
最新的Gson已经完全完全支持kotlin了,此篇文章已经变得索然无味了=。=
测试代码
data class Res<T>(
val error_code: Int,
val reason: String,
val result: T
)
data class Result(
val h5url: String,
val h5weixin: String
)
fun main() {
println("start")
val str = """
{
"reason": "请求成功",
"result": {
"h5url": "http://v.juhe.cn/wepiao/go?key=xxxxxxxxxxxxx",
"h5weixin": "http://v.juhe.cn/wepiao/go?key=xxxxxxxxxx&s=weixin"
},
"error_code": 0
}
""".trimIndent()
val resultType = object : TypeToken<Res<Result>>() {}.type
val gson = Gson()
val fromJson = gson.fromJson<Res<Result>>(str, resultType)
print(fromJson.result)
print(fromJson)
}
二次更新
1.因为学了bennyhuo老师的新课程所以照着抄了个扩展方法,让Gson用起来更简单。
2.最近使用发现使用.java也可以解析了,不会为空了。不知道为什么,还需要研究。。。
Gson扩展方法
inline fun <reified T> Gson.fromJson(json: String) = fromJson(json, T::class.java)
Gson扩展方法使用
ResultBean为解析实体类,data为解析字符串
val bean = Gson().fromJson<ResultBean>(data)
更新
Kotlin List和 MutableList 差异:可读写性
在使用JSON To Kotlin Class 插件,版本号v1.7.3时。
解析的集合为Kotlin的List,因为在Kotlin中,List为只读的,要想读写需要使用MutableList。
我在更新Adapter的时候发现的,明明数据有变化,显示却一直不变,原因就在这!!!
正文
同样的写法,在java中使用fastjson,gson到kotlin怎么就不灵了=。=!!!
Gson
序号 | api | 作用 |
---|---|---|
1 | toJson(Object) | 序列化 |
2 | fromJson(String, Class) | 反序列化 |
3 | JsonParser().parse(String) | 解析字段 |
实体类生成工具
像Java中的GsonFormat,Kotlin中也有插件JsonToKotlinClass
代码示例
1. 加入依赖
//json解析
api 'com.google.code.gson:gson:2.8.2'
2.创造数据
val data = """{
"error": false,
"results": [
{
"_id": "5aa5cc6a421aa9103ed33c7c",
"createdAt": "2018-03-12T08:40:10.360Z",
"desc": "3-12",
"publishedAt": "2018-03-12T08:44:50.326Z",
"source": "chrome",
"type": "\u798f\u5229",
"url": "https://ws1.sinaimg.cn/large/610dc034ly1fp9qm6nv50j20u00miacg.jpg",
"used": true,
"who": "daimajia"
},
{
"_id": "5a8e0c41421aa9133298a259",
"createdAt": "2018-02-22T08:18:09.547Z",
"desc": "2-22",
"publishedAt": "2018-02-22T08:24:35.209Z",
"source": "chrome",
"type": "\u798f\u5229",
"url": "https://ws1.sinaimg.cn/large/610dc034ly1foowtrkpvkj20sg0izdkx.jpg",
"used": true,
"who": "\u4ee3\u7801\u5bb6"
},
{
"_id": "5a7b93d2421aa90d2cd3d7f8",
"createdAt": "2018-02-08T08:03:30.905Z",
"desc": "2-8",
"publishedAt": "2018-02-08T08:13:24.479Z",
"source": "chrome",
"type": "\u798f\u5229",
"url": "http://7xi8d6.com1.z0.glb.clouddn.com/20180208080314_FhzuAJ_Screenshot.jpeg",
"used": true,
"who": "daimajia"
},
{
"_id": "5a6e5f88421aa9115696004f",
"createdAt": "2018-01-29T07:40:56.269Z",
"desc": "1-29",
"publishedAt": "2018-01-29T07:53:57.676Z",
"source": "chrome",
"type": "\u798f\u5229",
"url": "http://7xi8d6.com1.z0.glb.clouddn.com/20180129074038_O3ydq4_Screenshot.jpeg",
"used": true,
"who": "daimajia"
},
{
"_id": "5a65381a421aa91156960022",
"createdAt": "2018-01-22T09:02:18.715Z",
"desc": "1-22",
"publishedAt": "2018-01-23T08:46:45.132Z",
"source": "chrome",
"type": "\u798f\u5229",
"url": "http://7xi8d6.com1.z0.glb.clouddn.com/20180122090204_A4hNiG_Screenshot.jpeg",
"used": true,
"who": "daimajia"
},
{
"_id": "5a5bfc29421aa9115489927b",
"createdAt": "2018-01-15T08:56:09.429Z",
"desc": "1-15",
"publishedAt": "2018-01-16T08:40:08.101Z",
"source": "chrome",
"type": "\u798f\u5229",
"url": "http://7xi8d6.com1.z0.glb.clouddn.com/20180115085556_8AeReR_taeyeon_ss_15_1_2018_7_58_51_833.jpeg",
"used": true,
"who": "daimajia"
},
{
"_id": "5a5411fb421aa90fef2035f3",
"createdAt": "2018-01-09T08:51:07.91Z",
"desc": "1-9",
"publishedAt": "2018-01-10T07:57:19.486Z",
"source": "chrome",
"type": "\u798f\u5229",
"url": "http://7xi8d6.com1.z0.glb.clouddn.com/20180109085038_4A7atU_rakukoo_9_1_2018_8_50_25_276.jpeg",
"used": true,
"who": "daimajia"
},
{
"_id": "5a443fcb421aa90fe72536ed",
"createdAt": "2017-12-28T08:50:19.747Z",
"desc": "12-28",
"publishedAt": "2018-01-04T13:45:57.211Z",
"source": "chrome",
"type": "\u798f\u5229",
"url": "http://7xi8d6.com1.z0.glb.clouddn.com/20171228085004_5yEHju_Screenshot.jpeg",
"used": true,
"who": "\u4ee3\u7801\u5bb6"
},
{
"_id": "5a4ad432421aa90fe2f02d1a",
"createdAt": "2018-01-02T08:37:06.235Z",
"desc": "1-2",
"publishedAt": "2018-01-02T08:43:32.216Z",
"source": "chrome",
"type": "\u798f\u5229",
"url": "http://7xi8d6.com1.z0.glb.clouddn.com/20180102083655_3t4ytm_Screenshot.jpeg",
"used": true,
"who": "daimajia"
},
{
"_id": "5a431acd421aa90fe50c02a8",
"createdAt": "2017-12-27T12:00:13.664Z",
"desc": "12-27",
"publishedAt": "2017-12-27T12:13:22.418Z",
"source": "chrome",
"type": "\u798f\u5229",
"url": "http://7xi8d6.com1.z0.glb.clouddn.com/20171227115959_lmlLZ3_Screenshot.jpeg",
"used": true,
"who": "daimajia"
}
]
}"""
3.创建实体类(使用JsonToKotlinClass工具)
data class ResultBean(
val error: Boolean,
val results: List<MeiZiBean>
)
data class MeiZiBean(
val _id: String,
val createdAt: String,
val desc: String,
val publishedAt: String,
val source: String,
val type: String,
val url: String,
val used: Boolean,
val who: String
)
4.解析
//注意必须是javaObjectType,要不会被擦除泛型
val bean = Gson().fromJson(data, ResultBean::class.javaObjectType)
val results = bean.results
//验证是否有数据
val s = results.toString()
Log.e("main",s)
遇到的坑
之前一直写的是ResultBean::class.java,导致被泛型擦除,只能先解析成字符串,然后专门用TypeToken解析List,非常麻烦,网上看了很多文章也没有解决,最后还得自己发现。
源码注释
/**
* This is the main class for using Gson. Gson is typically used by first constructing a
* Gson instance and then invoking {@link #toJson(Object)} or {@link #fromJson(String, Class)}
* methods on it. Gson instances are Thread-safe so you can reuse them freely across multiple
* threads.
*
* <p>You can create a Gson instance by invoking {@code new Gson()} if the default configuration
* is all you need. You can also use {@link GsonBuilder} to build a Gson instance with various
* configuration options such as versioning support, pretty printing, custom
* {@link JsonSerializer}s, {@link JsonDeserializer}s, and {@link InstanceCreator}s.</p>
*
* <p>Here is an example of how Gson is used for a simple Class:
*
* <pre>
* Gson gson = new Gson(); // Or use new GsonBuilder().create();
* MyType target = new MyType();
* String json = gson.toJson(target); // serializes target to Json
* MyType target2 = gson.fromJson(json, MyType.class); // deserializes json into target2
* </pre></p>
*
* <p>If the object that your are serializing/deserializing is a {@code ParameterizedType}
* (i.e. contains at least one type parameter and may be an array) then you must use the
* {@link #toJson(Object, Type)} or {@link #fromJson(String, Type)} method. Here is an
* example for serializing and deserializing a {@code ParameterizedType}:
*
* <pre>
* Type listType = new TypeToken<List<String>>() {}.getType();
* List<String> target = new LinkedList<String>();
* target.add("blah");
*
* Gson gson = new Gson();
* String json = gson.toJson(target, listType);
* List<String> target2 = gson.fromJson(json, listType);
* </pre></p>
*
* <p>See the <a href="https://sites.google.com/site/gson/gson-user-guide">Gson User Guide</a>
* for a more complete set of examples.</p>
*
* @see com.google.gson.reflect.TypeToken
*
* @author Inderjeet Singh
* @author Joel Leitch
* @author Jesse Wilson
*/