当前位置:首页 > 开发 > 编程语言 > 编程 > 正文

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

发表于: 2014-08-12   作者:bit1129   来源:转载   浏览:
摘要:   如何把如下简单的JSON字符串反序列化为Java的POJO对象? {"data":{"IM":["MSN","QQ","Gtalk"]}}   下面的POJO类Model无法完成正确的解析:   import com.google.gson.Gson;

 

如何把如下简单的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));
        }
    }
}

 

 

 

 

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

  • 0

    开心

    开心

  • 0

    板砖

    板砖

  • 0

    感动

    感动

  • 0

    有用

    有用

  • 0

    疑问

    疑问

  • 0

    难过

    难过

  • 0

    无聊

    无聊

  • 0

    震惊

    震惊

编辑推荐
gson是google的产物,用于解决json数据解析比较繁琐的问题。以前解析json需要层层解析,gson出现后
通过前几篇的关于Gson的博客我们知道Gson的解析原理: 1)如果是通过GsonBuilder创建的Gson对象,那
研究GSON花费了我一天的时间,期间出现了各种问题,第一次可以理解嘛,不过还好在安卓开发交流22群
背景 json是一种数据格式,便于数据传输、存储、交换。 gson是一种组件库,可以把java对象数据转换
一、 谷歌GSON这个Java类库可以把Java对象转换成JSON,也可以把JSON字符串转换成一个相等的Java对象
1.可以利用Android API中的JsonReader解析Json数据 2.可以引入Gson的jar包,结合JavaBean解析Json数
声明: 1、本帖只提供代码,不深入讲解原理。如果读者想要深入了解,那就不要在这个帖子上浪费时间
在 几篇关于Gson的文章中我们知道Gson解析成Java对象的实现原理是: 1)注册自定义的或者Gson自己定
JSON是JavaScript Object Notation的缩写,可见JSON来源于JavaScript。JSON数据是一系列键值对的集
使用gson解析json,就得 json有一定的格式,要么是一个[],要么是一个{} 若是{},{},{} 外面又没有套[
版权所有 IT知识库 CopyRight © 2009-2015 IT知识库 IT610.com , All Rights Reserved. 京ICP备09083238号