关于fastJson解析Json字符串的问题。JSONException: exepct '[', but {

  1. 描述你的问题
    怎么解析这字符串:

[
    {
        "id": 1,
        "name": "Tony老师聊shell——环境变量配置文件",
        "picSmall": "http://img.mukewang.com/55237dcc0001128c06000338-300-170.jpg",
        "picBig": "http://img.mukewang.com/55237dcc0001128c06000338.jpg",
        "description": "为你带来shell中的环境变量配置文件",
        "learner": 12312
    },
    {
        "id": 2,
        "name": "数学知识在CSS动画中的应用",
        "picSmall": "http://img.mukewang.com/55249cf30001ae8a06000338-300-170.jpg",
        "picBig": "http://img.mukewang.com/55249cf30001ae8a06000338.jpg",
        "description": "数学知识与CSS结合实现酷炫效果",
        "learner": 45625
    },
    {
        "id": 3,
        "name": "Oracle数据库开发必备利器之PL/SQL基础",
        "picSmall": "http://img.mukewang.com/5523711700016d1606000338-300-170.jpg",
        "picBig": "http://img.mukewang.com/5523711700016d1606000338.jpg",
        "description": "Oracle数据库高级开发必备的基础。",
        "learner": 41236
    },
    {
        "id": 4,
        "name": "Android见证消息推送时刻进阶篇",
        "picSmall": "http://img.mukewang.com/551e470500018dd806000338-300-170.jpg",
        "picBig": "http://img.mukewang.com/551e470500018dd806000338.jpg",
        "description": "Android消息推送就在眼前,Come on",
        "learner": 45456
    },
    {
        "id": 5,
        "name": "Avalon探索之旅基础教程——复杂绑定",
        "picSmall": "http://img.mukewang.com/551de0570001134f06000338-300-170.jpg",
        "picBig": "http://img.mukewang.com/551de0570001134f06000338.jpg",
        "description": "前端迷您MVVM框架,Avalon复杂绑定属性篇。",
        "learner": 56556
    },
    {
        "id": 6,
        "name": "Android-Service系列之断点续传下载",
        "picSmall": "http://img.mukewang.com/552640c300018a9606000338-300-170.jpg",
        "picBig": "http://img.mukewang.com/552640c300018a9606000338.jpg",
        "description": "想升职加薪么?本章课程你值得拥有",
        "learner": 48996
    },
    {
        "id": 7,
        "name": "JUnit—Java单元测试必备工具",
        "picSmall": "http://img.mukewang.com/551b92340001c9f206000338-300-170.jpg",
        "picBig": "http://img.mukewang.com/551b92340001c9f206000338.jpg",
        "description": "Java单元测试利器!",
        "learner": 13210
    },
    {
        "id": 8,
        "name": "细说Java多线程之内存可见性",
        "picSmall": "http://img.mukewang.com/5518c3d7000175af06000338-300-170.jpg",
        "picBig": "http://img.mukewang.com/5518c3d7000175af06000338.jpg",
        "description": "用两种方式实现内存可见性",
        "learner": 15051
    },
    {
        "id": 9,
        "name": "CSS动画实用技巧",
        "picSmall": "http://img.mukewang.com/551b98ae0001e57906000338-300-170.jpg",
        "picBig": "http://img.mukewang.com/551b98ae0001e57906000338.jpg",
        "description": "教你使用CSS实现惊艳的动画效果!",
        "learner": 15210
    },
    {
        "id": 10,
        "name": "C++远征之起航篇",
        "picSmall": "http://img.mukewang.com/550b86560001009406000338-300-170.jpg",
        "picBig": "http://img.mukewang.com/550b86560001009406000338.jpg",
        "description": "C++亮点尽在其中",
        "learner": 84545
    },
    {
        "id": 11,
        "name": "Tony老师聊shell——运算符",
        "picSmall": "http://img.mukewang.com/551916790001125706000338-300-170.jpg",
        "picBig": "http://img.mukewang.com/551916790001125706000338.jpg",
        "description": "Tony为你带来shell编程中的运算符!",
        "learner": 18411
    },
    {
        "id": 12,
        "name": "如何使用高德云图在线制作属于你的地图",
        "picSmall": "http://img.mukewang.com/5518ecf20001cb4e06000338-300-170.jpg",
        "picBig": "http://img.mukewang.com/5518ecf20001cb4e06000338.jpg",
        "description": "教你迅速使用云图进行基于LBS的开发。",
        "learner": 56432
    },
    {
        "id": 13,
        "name": "鬼斧神工之正则表达式",
        "picSmall": "http://img.mukewang.com/5518bbe30001c32006000338-300-170.jpg",
        "picBig": "http://img.mukewang.com/5518bbe30001c32006000338.jpg",
        "description": "正则表达式是计算机编程语言界的鬼斧神工。",
        "learner": 25210
    },
    {
        "id": 14,
        "name": "如何使用高德Windows Phone SDK进行基于LBS的开发",
        "picSmall": "http://img.mukewang.com/551380400001da9b06000338-300-170.jpg",
        "picBig": "http://img.mukewang.com/551380400001da9b06000338.jpg",
        "description": "教你迅速使用WP SDK进行基于LBS的开发",
        "learner": 56445
    },
    {
        "id": 15,
        "name": "canvas实现星星闪烁特效",
        "picSmall": "http://img.mukewang.com/550a33b00001738a06000338-300-170.jpg",
        "picBig": "http://img.mukewang.com/550a33b00001738a06000338.jpg",
        "description": "使用HTML5实现轮播图片上的序列帧。",
        "learner": 45658
    },
    {
        "id": 16,
        "name": "如何使用高德JS-API进行基于LBS的开发",
        "picSmall": "http://img.mukewang.com/5513a1b50001752806000338-300-170.jpg",
        "picBig": "http://img.mukewang.com/5513a1b50001752806000338.jpg",
        "description": "教你迅速用高德JS-API进行基于LBS的开发",
        "learner": 15222
    },
    {
        "id": 17,
        "name": "Duang~MySQLi扩展库来袭",
        "picSmall": "http://img.mukewang.com/5513e20600017c1806000338-300-170.jpg",
        "picBig": "http://img.mukewang.com/5513e20600017c1806000338.jpg",
        "description": "Duang~一起开启MySQLi的学习之旅吧!",
        "learner": 46321
    },
    {
        "id": 18,
        "name": "如何使用高德Android SDK进行基于LBS的开发",
        "picSmall": "http://img.mukewang.com/550a78720001f37a06000338-300-170.jpg",
        "picBig": "http://img.mukewang.com/550a78720001f37a06000338.jpg",
        "description": "教你迅速使用Android SDK进行基于LBS的开发",
        "learner": 12130
    },
    {
        "id": 19,
        "name": "高德地图组件快速入门",
        "picSmall": "http://img.mukewang.com/550a836c0001236606000338-300-170.jpg",
        "picBig": "http://img.mukewang.com/550a836c0001236606000338.jpg",
        "description": "教你迅速使用地图组件进行基于LBS的开发",
        "learner": 54540
    },
    {
        "id": 20,
        "name": "如何使用高德定位进行开发",
        "picSmall": "http://img.mukewang.com/550a87da000168db06000338-300-170.jpg",
        "picBig": "http://img.mukewang.com/550a87da000168db06000338.jpg",
        "description": "教你迅速使用定位进行基于LBS的开发",
        "learner": 45665
    },
    {
        "id": 21,
        "name": "Yahoo军规",
        "picSmall": "http://img.mukewang.com/530f0ef700019b5906000338-300-170.jpg",
        "picBig": "http://img.mukewang.com/530f0ef700019b5906000338.jpg",
        "description": "做为WEB前端攻城师,您必须知道的网站性能优化规则。",
        "learner": 12123
    },
    {
        "id": 22,
        "name": "Ajax全接触",
        "picSmall": "http://img.mukewang.com/549bda090001c53e06000338-300-170.jpg",
        "picBig": "http://img.mukewang.com/549bda090001c53e06000338.jpg",
        "description": "由浅入深,循序渐进学习Ajax的相关概念、原理、实现方式和应用方法。",
        "learner": 46456
    },
    {
        "id": 23,
        "name": "jQuery源码解析(DOM与核心模块)",
        "picSmall": "http://img.mukewang.com/547d5a45000156f406000338-300-170.jpg",
        "picBig": "http://img.mukewang.com/547d5a45000156f406000338.jpg",
        "description": "前端架构师的必经之路,揭开框架背后的秘密。",
        "learner": 51456
    },
    {
        "id": 24,
        "name": "用字体在网页中画ICON图标",
        "picSmall": "http://img.mukewang.com/54780ea90001f3b406000338-300-170.jpg",
        "picBig": "http://img.mukewang.com/54780ea90001f3b406000338.jpg",
        "description": "图标恋上字体,就像老鼠爱上大米!",
        "learner": 16456
    },
    {
        "id": 25,
        "name": "CSS3绚丽照片墙",
        "picSmall": "http://img.mukewang.com/547ed1c9000150cc06000338-300-170.jpg",
        "picBig": "http://img.mukewang.com/547ed1c9000150cc06000338.jpg",
        "description": "简单CSS3属性轻松实现绚丽照片墙效果。",
        "learner": 26456
    },
    {
        "id": 26,
        "name": "SEO在网页制作中的应用",
        "picSmall": "http://img.mukewang.com/54214727000160e306000338-300-170.jpg",
        "picBig": "http://img.mukewang.com/54214727000160e306000338.jpg",
        "description": "让您快速迈进SEO的门,不容错过!",
        "learner": 12436
    },
    {
        "id": 27,
        "name": "CSS深入理解之absolute",
        "picSmall": "http://img.mukewang.com/54125edc0001ce6306000338-300-170.jpg",
        "picBig": "http://img.mukewang.com/54125edc0001ce6306000338.jpg",
        "description": "全面深入理解CSS的position:absolute声明。",
        "learner": 45345
    },
    {
        "id": 28,
        "name": "玩转KISSY框架",
        "picSmall": "http://img.mukewang.com/548165820001b4b006000338-300-170.jpg",
        "picBig": "http://img.mukewang.com/548165820001b4b006000338.jpg",
        "description": "全网唯一系统讲解KISSY框架从入门到精通的教程。",
        "learner": 11456
    },
    {
        "id": 29,
        "name": "CSS深入理解之float浮动",
        "picSmall": "http://img.mukewang.com/53d74f960001ae9d06000338-300-170.jpg",
        "picBig": "http://img.mukewang.com/53d74f960001ae9d06000338.jpg",
        "description": "主要介绍了浮动属性的前世与今生,糟粕与精华,误解与滥用等。",
        "learner": 45656
    },
    {
        "id": 30,
        "name": "CSS未来",
        "picSmall": "http://img.mukewang.com/54c87c73000150cf06000338-300-170.jpg",
        "picBig": "http://img.mukewang.com/54c87c73000150cf06000338.jpg",
        "description": "CSS之父Bert Bos带来的分享。",
        "learner": 13436
    }
]
  1. 贴上相关代码
    我的代码如下:

public class MainActivity extends AppCompatActivity {

    private RequestQueue queue;
    private String url = "http://www.imooc.com/api/teacher?type=4&num=30";
    private List<Bean> datas = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
    }

    private void initView() {
        queue = Volley.newRequestQueue(this);
        datas = new ArrayList<Bean>();
        getData();

    }

    private void getData() {

        JsonObjectRequest request = new JsonObjectRequest(url, null, new Response.Listener<JSONObject>() {
            @Override
            public void onResponse(JSONObject jsonObject) {

                datas = JSON.parseArray(jsonObject.toString(), Bean.class);
                Log.i("ddddd", "" + datas.size());

            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError volleyError) {


            }
        });

        queue.add(request);
    }
}

Bean.java

package china.fastjsondemo;


public class Bean {

    public Bean() {
    }

    private String id;
    private String name;
    private String picSmall;
    private String picBig;
    private String description;
    private String learner;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPicSmall() {
        return picSmall;
    }

    public void setPicSmall(String picSmall) {
        this.picSmall = picSmall;
    }

    public String getPicBig() {
        return picBig;
    }

    public void setPicBig(String picBig) {
        this.picBig = picBig;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public String getLearner() {
        return learner;
    }

    public void setLearner(String learner) {
        this.learner = learner;
    }
}
  1. 贴上报错信息

出错:`.fastjson.JSONException: exepct '[', but {

                                                                    at com.alibaba`
  1. 贴上相关截图

  2. 已经尝试过哪些方法仍然没解决(附上相关链接)

我的疑问:是不是fastJson要解析的json数据有一定严密规定死的格式???要不然的话,这段Json数据怎么解析下来.......普通的方法,我会,但写太多了。今天学用fastJson这个东西解析.....

阅读 24k
4 个回答

根据你这个API地址 http://www.imooc.com/api/teacher?type=4&num=30

返回的json数据有两层,而你只解析了一层,当然会数据错误。

应该是建立两层
DataBean

public class DataBean {
    private int id;
    private String name;
    private String picSmall;
    private String picBig;
    private String description;
    private int learner;
    //此处省略 getter & setter
}

RootGroup

public class RootGroup {
    private int status;
    private List<DataBean> data;
    private String msg;
    //此处省略 getter & setter
}

以上由下方工具生成(动手的地方比较多)。,详见附录1
Ps. Android Studio 上还有更方便的插件 GsonFormat (坐上来,自己动) ,详见附录2

然后数据获取处(实际上你写的只有这一段代码就解析好了。。

RootGroup root = JSON.parseObject(jsonStr, RootGroup.class);
        for (int i = 0; i < root.getData().size(); i++) {
            Sys.out(root.getData().get(i).getName());
        }

即可。


附录

附录1: http://www.bejson.com/json2javapojo/
附录2: GsonFormat介绍:http://www.jianshu.com/p/b83ea5e32ee1


好了,问题解决了,说个题外话,很多网络请求框架都自带标准json请求方式的。
私以为,还是自己创建实体类,用着方便。 :-D

fastJson我没用过,不过用 Gson 去解析很快。。。
根据你的JSON数据格式定义如下的Bean:
注意:内部嵌套的类必须是static。

public class Bean{
    public List<Info> info;
    
    public static class Info {
        private String id;
        private String name;
        private String picSmall;
        private String picBig;
        private String description;
        private String learner;
        
        //Get,set方法省略。。。
    }
    
    public List<Info> getInfo() {
        return this.info;
    }
}

使用 Gson 去解析:

                //  1)
                Gson gson = new Gson();
                //  2)
                java.lang.reflect.Type type = new TypeToken<Bean2>() {}.getType();
                //  3)
                Bean temp = gson.fromJson(json2,type);

这样,得出来的 Bean 的对象temp,就是一个 List<Info> ,
用 temp.getInfo().get(i) 就能得到内部类 Info 了。。。。
小白第一次回答问题。。。。求见谅。。。

datas = JSON.parseArray(jsonObject.toString(), Bean.class);

jsonObject.toString()如果是原JSON字符串,应该是可以解析出来的,你看看你这个值拿到的是什么

首先,直接用 JsonArray data=Json.getJsonArray("data"),无法完成........

行得通的做法是(不是很理解Json数据,还得研究研究):把参数返回的jsonObject转换为FastJson的JsonObject,获得的竟然是有三个项目的集合,这怎么理解?然后再从从这个集合中获取“data”数组,并且用FastJson的JsonArray转为集合......

public void onResponse(JSONObject jsonObject) {

                com.alibaba.fastjson.JSONObject list = (com.alibaba.fastjson.JSONObject) JSON.parse(jsonObject.toString());

                JSONArray data = list.getJSONArray("data");
                Log.i("ddd", ""+data.size());


            }

还得研究研究...折腾出真知

=======================

后来发现这个Json数据原来是这样的:本身是一个三个数据的集合,然后如果直接获取data集合就错了...
图片描述

====================================
获取了data的数据后,就可以直接关联JavaBean了,这就比传统的省了一大段繁琐代码.......这里是自动关联了。

com.alibaba.fastjson.JSONObject list = (com.alibaba.fastjson.JSONObject) JSON.parse(jsonObject.toString());

                JSONArray tempArray = list.getJSONArray("data");

                datas = JSON.parseArray(tempArray.toJSONString(), Bean.class);

这是要注意要命的一点是,也在原文中错误的一点,

List<Bean> datas=null; 不需要先new一个ArrayList出来,然后再关联数据,是不行的;就让datas=null, 等到自动关联数据的时候就会自动对应存好数据了.......

=================================
贴出一些笔记,fastJson常用的方法

 1 public static final Object parse(String text); // 把JSON文本parse为JSONObject或者JSONArray  
  2 public static final JSONObject parseObject(String text); // 把JSON文本parse成JSONObject     
  3 public static final  T parseObject(String text, Class clazz); // 把JSON文本parse为JavaBean  
  4 public static final JSONArray parseArray(String text); // 把JSON文本parse成JSONArray 
  5 public static final  List parseArray(String text, Class clazz); //把JSON文本parse成JavaBean集合  
  6 public static final String toJSONString(Object object); // 将JavaBean序列化为JSON文本 
  7 public static final String toJSONString(Object object, boolean prettyFormat); // 将JavaBean序列化为带格式的JSON文本  
  8 public static final Object toJSON(Object javaObject); 将JavaBean转换为JSONObject或者JSONArray。

如果有一段Json字符串数据,要把它parse先,然后再进行fastJson的操作......比如此例子中,volley返回的jsonOject直接用就不行,是不是它仅仅只是字符串?但是经过fastJson解析转化后就能用了......

=============================================

经过最佳答案的那位网友介绍JsonFormat很好用.....有了它这一切问题迎刃而解:

fastJson的解决如下:
提前用JsonFormat生成了Bean这样一个javaBean类,然后就如下两句代码搞定:

private void getJsonData() {
        final StringRequest request = new StringRequest(url, new Response.Listener<String>() {
            @Override
            public void onResponse(String s) {
                
//                Bean bean = (Bean) JSON.parseArray(s, Bean.class);  这里用parseArray会出错
                Bean bean = (Bean) JSON.parseObject(s, Bean.class);
                datas = bean.getData();
                Log.d("ddd", datas.size() + "");
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError volleyError) {
                Log.d("ddd", volleyError.getMessage());
            }
        });
        queue.add(request);
    }

===============================================
再补充楼上提示的用Gson解决,貌似Gson需要三句代码:
JsonFormat的操作一样.....

private void getJsonData() {
        final StringRequest request = new StringRequest(url, new Response.Listener<String>() {
            @Override
            public void onResponse(String s) {
                //// TODO:
                Gson gson = new Gson();
                Type type = new TypeToken<Bean>() {
                }.getType();
                Bean bean = gson.fromJson(s, Bean.class);
                datas = bean.getData();
                //                Log.d("ddd", datas.get(1).getDescription());
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError volleyError) {
                Log.d("ddd", volleyError.getMessage());
            }
        });
        queue.add(request);
    }

综上,所以fastJson是可以两句代码取到数据,Gson三句

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题