`
bit1129
  • 浏览: 1068072 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

【Gson三】Gson解析{"data":{"IM":["MSN","QQ","Gtalk"]}}

 
阅读更多

 

如何把如下简单的JSON字符串反序列化为Java的POJO对象?

{"data":{"IM":["MSN","QQ","Gtalk"]}}

 

下面的POJO类Model无法完成正确的解析:

 

import com.google.gson.Gson;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

class Model {
    private Map<String, Map<String, List<String>>> data;

    public Map<String, Map<String, List<String>>> getData() {
        return data;
    }

    public void setData(Map<String, Map<String, List<String>>> data) {
        this.data = data;
    }
}

public class ModelTest {
    public static void main(String[] args) {
        List<String> ims = new ArrayList<String>();
        ims.add("MSN");
        ims.add("QQ");
        ims.add("Gtalk");
        Map<String, List<String>> map = new HashMap<String, List<String>>();
        map.put("IM", ims);

        Map<String, Map<String, List<String>>> dataMap = new HashMap<String, Map<String, List<String>>>();
        dataMap.put("data", map);
        String str = new Gson().toJson(dataMap);
        System.out.println(str);/*{"data":{"IM":["MSN","QQ","Gtalk"]}}*/
        Model m = new Gson().fromJson(str, Model.class);
    }
}

 

异常信息:

Exception in thread "main" com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_ARRAY but was STRING at line 1 column 17
	at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:176)
	at com.google.gson.Gson.fromJson(Gson.java:803)
	at com.google.gson.Gson.fromJson(Gson.java:768)
	at com.google.gson.Gson.fromJson(Gson.java:717)
	at com.google.gson.Gson.fromJson(Gson.java:689)
	at gson.test4.ModelTest.main(ModelTest.java:35)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:606)
	at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)
Caused by: java.lang.IllegalStateException: Expected BEGIN_ARRAY but was STRING at line 1 column 17
	at com.google.gson.stream.JsonReader.beginArray(JsonReader.java:338)
	at com.google.gson.internal.bind.MapTypeAdapterFactory$Adapter.read(MapTypeAdapterFactory.java:172)
	at com.google.gson.internal.bind.MapTypeAdapterFactory$Adapter.read(MapTypeAdapterFactory.java:145)
	at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.read(TypeAdapterRuntimeTypeWrapper.java:40)
	at com.google.gson.internal.bind.MapTypeAdapterFactory$Adapter.read(MapTypeAdapterFactory.java:187)
	at com.google.gson.internal.bind.MapTypeAdapterFactory$Adapter.read(MapTypeAdapterFactory.java:145)
	at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.read(ReflectiveTypeAdapterFactory.java:93)
	at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:172)
	... 10 more

 

如何解决这个问题?

 

仔细看了代码,出错是正常的事情。在代码中,str是从dataMap序列化而来,把这个由dataMap转换而来的JSON串str反序列为Model类型,出错是必然的

String str = new Gson().toJson(dataMap);
Model m = new Gson().fromJson(str, Model.class)

那么Model对象序列化为JSON串的数据是什么样的呢?

{"data":{"data":{"IM":["MSN","QQ","Gtalk"]}}}

 

此时,解决的办法有两个:

 

1. 对于下面的JSON串,对应的数据结构是Map<String,Map<String,List<String>>>,直接把这个这个JSON串转成Map<String,Map<String,List<String>>>是可行的,比如如下的代码

{"data":{"IM":["MSN","QQ","Gtalk"]}}

将它转换为Map<String,Map<String,List<String>>>

 

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;

import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

class Model {
    private Map<String, Map<String, List<String>>> data;

    public Map<String, Map<String, List<String>>> getData() {
        return data;
    }

    public void setData(Map<String, Map<String, List<String>>> data) {
        this.data = data;
    }
}

public class ModelTest {
    public static void main(String[] args) {
        List<String> ims = new ArrayList<String>();
        ims.add("MSN");
        ims.add("QQ");
        ims.add("Gtalk");
        Map<String, List<String>> map = new HashMap<String, List<String>>();
        map.put("IM", ims);

        Map<String, Map<String, List<String>>> dataMap = new HashMap<String, Map<String, List<String>>>();
        dataMap.put("data", map);
        String str = new Gson().toJson(dataMap);
        System.out.println(str);/*{"data":{"IM":["MSN","QQ","Gtalk"]}}*/

        Type type = new TypeToken<Map<String, Map<String, List<String>>>>(){}.getType();

        dataMap = new Gson().fromJson(str, type);
        ims= dataMap.get("data").get("IM");
        for(int i = 0;  i< ims.size(); i++) {
            System.out.println(ims.get(i));
        }
    }
}
 
2.重新定义Model的数据结构,它包含的数据类型应该是private Map<String, List<String>> data;代码如下,此时可以正确解析了

 

 

 

import com.google.gson.Gson;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

class Model {
    private Map<String, List<String>> data;

    public Map<String, List<String>> getData() {
        return data;
    }

    public void setData(Map<String, List<String>> data) {
        this.data = data;
    }
}

public class ModelTest {
    public static void main(String[] args) {
        List<String> ims = new ArrayList<String>();
        ims.add("MSN");
        ims.add("QQ");
        ims.add("Gtalk");
        Map<String, List<String>> map = new HashMap<String, List<String>>();
        map.put("IM", ims);

        Map<String, Map<String, List<String>>> dataMap = new HashMap<String, Map<String, List<String>>>();
        dataMap.put("data", map);
        String str = new Gson().toJson(dataMap);
        System.out.println(str);/*{"data":{"IM":["MSN","QQ","Gtalk"]}}*/

        Model m = new Gson().fromJson(str, Model.class);
        System.out.println(m!=null);
    }
}
 

 3.第三种方式,不使用Type,直接使用Map.class,这时没有使用范型,但是仍然可以得到正确的输出,这是为什么??

 

import com.google.gson.Gson;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

class Model {
    private Map<String, Map<String, List<String>>> data;

    public Map<String, Map<String, List<String>>> getData() {
        return data;
    }

    public void setData(Map<String, Map<String, List<String>>> data) {
        this.data = data;
    }
}

public class ModelTest {
    public static void main(String[] args) {
        List<String> ims = new ArrayList<String>();
        ims.add("MSN");
        ims.add("QQ");
        ims.add("Gtalk");
        Map<String, List<String>> map = new HashMap<String, List<String>>();
        map.put("IM", ims);

        Map<String, Map<String, List<String>>> dataMap = new HashMap<String, Map<String, List<String>>>();
        dataMap.put("data", map);
        String str = new Gson().toJson(dataMap);
        System.out.println(str);/*{"data":{"IM":["MSN","QQ","Gtalk"]}}*/

        //Type type = new TypeToken<Map<String, Map<String, List<String>>>>(){}.getType();
        //Map<String, Map<String, List<String>>> t = null;
        dataMap = new Gson().fromJson(str, Map.class); //不使用Type包装范型,为什么仍然正确?
        ims= dataMap.get("data").get("IM");
        for(int i = 0;  i< ims.size(); i++) {
            System.out.println(ims.get(i));
        }
    }
}

 

 

 

 

0
1
分享到:
评论

相关推荐

    gson-2.8.7-API文档-中文版.zip

    Maven坐标:com.google.code.gson:gson:2.8.7; 标签:google、gson、中文文档、jar包、java; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性化翻译,文档中的代码和...

    GSON-2.85.rar

    1. **JSON到Java对象的映射**:Gson可以将JSON字符串解析为等效的Java对象,如将JSON字符串转换为JsonObject、JsonArray、JsonElement等。 2. **Java对象到JSON的转换**:同样,Gson也能将Java对象序列化为JSON格式...

    Gson解析复杂Json实例,超简单

    implementation 'com.google.code.gson:gson:2.8.6' } ``` 记得同步项目以加载新的依赖项。 ### 创建Java对象 在解析JSON之前,我们需要根据JSON的结构创建对应的Java类。假设我们有以下JSON数据: ```json { ...

    Gson解析json数据

    在本文中,我们将深入探讨如何使用Gson解析JSON数据,包括处理简单JSON和复杂的JSON结构。 首先,我们要了解JSON的基本概念。JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,易于人阅读和编写,...

    Gson TypeAdapter使用技巧几例:数据免判空、解析后校验、预处理.zip

    在这个`Gson TypeAdapter`使用技巧的例子中,我们将深入探讨如何利用TypeAdapter来优化数据处理,包括数据免判空、解析后校验以及预处理等关键环节。这些技巧对于处理机器学习中的数据预处理尤其重要。 首先,让...

    GsonFactory:Gson解析容错框架,愿从此再无Json解析报错

    implementation ' com.google.code.gson:gson:2.8.5 ' } 使用文档 请使用框架返回的Gson对象来代替项目中的Gson对象 // 获取单例的 Gson 对象(已处理容错) Gson gson = GsonFactory . getSingletonGson(); 因为...

    com.google.gson.Gson 2.8.0 jar包

    截止至2016-12-23,github上com.google.gson.Gson ...强大的json字符串解析功能及将字符串转换为json格式。才发现需要这么多分,大家也可以去网盘下载: https://pan.baidu.com/s/1d0JW_9G7iJPIJtjUbU91Jw 提取码: qtvm

    gson-2.8.0.jar

    gson-2.8.0.jar ...Gson 是google解析Json的一个开源框架。网上都说这个比fastJson,JackJso都要好,建议使用Gson。 解压后MD5:a42f1f5bfa4e6f123ddcab3de7e0ff81 大小:226 KB gson API 文档下载地址: ...

    gson-2.6.2.jar包(com.google.code.gson:gson:2.6.2)

    Gson库通过提供`Gson`类,使得Java对象可以方便地转换为JSON字符串,反之也可以将JSON文本解析成对应的Java对象。这对于网络数据交换和存储数据到本地文件或数据库非常有用。 在Android Studio中,通常会将外部依赖...

    通过Gson解析Json文件

    本篇文章将详细阐述如何使用Gson库解析JSON文件,帮助开发者理解并掌握这一技能。 首先,我们需要了解什么是JSON。JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,易于人阅读和编写,同时也易于...

    gson-2.8.9-API文档-中文版.zip

    Maven坐标:com.google.code.gson:gson:2.8.9; 标签:google、gson、jar包、java、中文文档; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性化翻译,文档中的代码和...

    gson-2.8.7.jar

    gson-2.8.7.jar

    android中使用gson来创建和解析json数据

    implementation 'com.google.code.gson:gson:2.8.6' // 使用最新版本 } ``` 然后同步项目,Gson库就会被引入到你的项目中。 **创建JSON数据** 在Android中,你可能有一些Java对象需要转换成JSON格式。例如,假设有...

    gson-2.8.0-API文档-中文版.zip

    Maven坐标:com.google.code.gson:gson:2.8.0; 标签:google、gson、中文文档、jar包、java; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性化翻译,文档中的代码和...

    gson包重复冲突,项目不能正常编译1

    这段代码的作用是告诉Gradle在解析所有依赖(包括transitive dependencies,即间接依赖)时,排除掉group为'com.google.code.gson'的Gson库。这样,即使`ivms_8700_sdk_library.aar`包含Gson,Gradle也不会再引入...

    gson-2.8.6-API文档-中文版.zip

    Maven坐标:com.google.code.gson:gson:2.8.6; 标签:google、gson、中文文档、jar包、java; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性化翻译,文档中的代码和...

    JSON、GSON解析json

    GSON的强大之处在于它可以自动映射JSON数据到Java对象,大大简化了JSON解析和序列化的过程。 以下是关于JSON和GSON在Android开发中的具体知识点: 1. JSON基本结构:JSON包含两种主要数据结构,对象(Object)和数...

    gson-2.8.0,解析json

    在标题“gson-2.8.0,解析json”中,提到的是Gson的版本2.8.0,这是一个专门用于处理JSON解析和序列化的工具。 描述中提到,通过下载并解压提供的zip文件,我们可以得到`gson-2.8.0.jar`。这个JAR文件包含了Gson库...

    Android Gson解析案例

    implementation 'com.google.code.gson:gson:2.8.6' } ``` 2. **创建Java对象**:定义一个与JSON数据匹配的Java类,包含相应的属性和getter/setter方法。 ```java public class User { private String name; ...

    Json解析Gson解析

    三、Gson的高级用法 1. 自定义序列化和反序列化:可以通过实现`JsonSerializer&lt;T&gt;`和`JsonDeserializer&lt;T&gt;`接口来自定义对象的序列化和反序列化规则。 2. `@Expose`注解:通过在字段上添加`@Expose`注解,可以控制...

Global site tag (gtag.js) - Google Analytics