Android Json的常用解析方法及自定义JsonRequest

来源:互联网 发布:php class 传值 编辑:程序博客网 时间:2024/05/04 11:47

Android Json的常用解析方法及自定义JsonRequest

上一篇介绍了Xml的常用解析方法,那么很显然,接下来就是Json了。
JSON 是一种轻量级的数据交换格式,具有如下特点:

  • 易于人阅读和编写
  • 易于机器解析和生成
  • 采用完全独立于语言的文本格式
  • 类似于C语言家族的习惯

由于这些特性使得它是理想的数据交换语言,同时个人也比较喜欢它。那么废话不多说,下面就一起来看下它的常用解析方法吧。

原生解析

下面只用到常见的几种Json格式,涉及的工具有JSONObject、JSONArray,大括号是对象,中括号是数组。
1.只有一个对象的Json字符串

{"name":"xiaoming","age":8,"student":true}
public void parseJsonObject(String json) {          try {              JSONObject jsonObject = new JSONObject(json);              String name = jsonObject.getString("name");              int age = jsonObject.getInt("age");              boolean student = jsonObject.getBoolean("student");          } catch (JSONException e) {              // TODO Auto-generated catch block              e.printStackTrace();          }      } 

2.含有数组的Json字符串

[{"name":"xiaoming","age":8,"student":true},{"name":"xiaohong","age":9,"student":true}]
public void parseJSONArray(String json) {          try {              JSONArray jsonArray = new JSONArray(json);              for (int i = 0; i < jsonArray.length(); i++) {                  jsonObject = jsonArray.getJSONObject(i);                  String name = jsonObject.getString("name");                  int age = jsonObject.getInt("age");                  boolean student = jsonObject.getBoolean("student");              }          } catch (JSONException e) {              // TODO Auto-generated catch block              e.printStackTrace();          }      } 

3.对象嵌套对象的Json字符串

{"name":"xiaoming", "age":8, "student":true, "address":{"country":"中国","province":"湖北","city":"武汉"}}
public void parseJsonPerson(String json) {          try {              JSONObject jsonObject = new JSONObject(json);              String name = jsonObject.getString("name");              int age = jsonObject.getInt("age");              boolean student= jsonObject.getBoolean("student");              JSONObject addressJSON = jsonObject.getJSONObject("address");              String country= addressJSON.getString("country");              String province= addressJSON.getString("province");              String city= addressJSON.getString("city");              Address address = new Address(country, province, city);              Person person = new Person(name, age, student, address);          } catch (JSONException e) {              // TODO Auto-generated catch block              e.printStackTrace();          }      }

4.数组中嵌套对象的Json字符串

[{"name":"xiaoming", "age":8, "student":true, "address":{"country":"中国","province":"湖北","city":"武汉"}},{"name":"xiaohong", "age":9, "student":true, "address":{"country":"中国","province":"台湾","city":"台北"}}]
public void parseJsonArrayPerson(String json) {          List<Person> persons = new ArrayList<Person>();          try {              jsonArray = new JSONArray(json);              for (int i = 0; i < jsonArray.length(); i++) {                  jsonObject = jsonArray.getJSONObject(i);                  String name = jsonObject.getString("name");                  int age = jsonObject.getInt("age");                  boolean student = jsonObject.getBoolean("student");                  JSONObject addressJSON = jsonObject.getJSONObject("address");                  String country = addressJSON.getString("country");                  String province = addressJSON.getString("province");                  String city = addressJSON.getString("city");                  Address address = new Address(country, province, city);                  Person person = new Person(name, age, student, address);                  persons.add(person);              }          } catch (JSONException e) {              // TODO Auto-generated catch block              e.printStackTrace();          }      }  

Gson解析

Gson是Google提供的用来在Java对象和Json数据之间进行映射的Java类库。使用Gson,可以很容易的将一串Json数据转换为一个Java对象,或是将一个Java对象转换为相应的Json数据。只需要建立一个对应json的javaBean类,就可以通过简单的操作解析出数据,而且速度比较快,还可以按需去取数据。
首先,我们一起看一下要解析的Json字符串长什么样的。url是 http://www.weather.com.cn/data/sk/101190408.html。

{"weatherinfo":{"city":"太仓","cityid":"101190408","temp":"17","WD":"南风","WS":"2级","SD":"47%","WSE":"2","time":"17:05","isRadar":"0","Radar":"","njd":"暂无实况","qy":"1017","rain":"0"}}

可以看到它是对象中嵌套对象的。如果自己写JavaBean文件还需要点时间,这里介绍一个超简单的方法,就是利用AS的插件GsonFormat来生成。

public class Weathers {    /**     * weatherinfo : {"city":"太仓","cityid":"101190408","temp":"17","WD":"南风","WS":"2级","SD":"47%","WSE":"2","time":"17:05","isRadar":"0","Radar":"","njd":"暂无实况","qy":"1017","rain":"0"}     */    private WeatherinfoEntity weatherinfo;    public void setWeatherinfo(WeatherinfoEntity weatherinfo) {        this.weatherinfo = weatherinfo;    }    public WeatherinfoEntity getWeatherinfo() {        return weatherinfo;    }    public static class WeatherinfoEntity {        /**         * city : 太仓         * cityid : 101190408         * temp : 17         * WD : 南风         * WS : 2级         * SD : 47%         * WSE : 2         * time : 17:05         * isRadar : 0         * Radar :         * njd : 暂无实况         * qy : 1017         * rain : 0         */        private String city;        private String cityid;        private String temp;        private String WD;        private String WS;        private String SD;        private String time;        public void setCity(String city) {            this.city = city;        }        public void setCityid(String cityid) {            this.cityid = cityid;        }        public void setTemp(String temp) {            this.temp = temp;        }        public void setWD(String WD) {            this.WD = WD;        }        public void setWS(String WS) {            this.WS = WS;        }        public void setSD(String SD) {            this.SD = SD;        }        public void setTime(String time) {            this.time = time;        }        public String getCity() {            return city;        }        public String getCityid() {            return cityid;        }        public String getTemp() {            return temp;        }        public String getWD() {            return WD;        }        public String getWS() {            return WS;        }        public String getSD() {            return SD;        }        public String getTime() {            return time;        }        public String toString() {            return city + cityid + temp + WD + WS + SD + time;        }    }}

安装完插件后,新建一个Java文件,右键点击Generate,然后点击GsonFormat,最后复制要解析的Json字符串,就生成了,是不是很简单呢。这里说一下,JavaBean中的字段名称必须和Json字符串中的字段一致,但是不需要全部,按需就行。下面看一下如何来解析。

    private void gsonParser() {        stringRequest = new MyStringRequests(url, new Response.Listener<String>() {            @Override            public void onResponse(String response) {                Gson gson = new Gson();                Weathers weathers = gson.fromJson(response, Weathers.class);                Weathers.WeatherinfoEntity weatherInfo = weathers.getWeatherinfo();                tv.setText(weatherInfo.toString());//                String gsonString = gson.toJson(weathers);//                Log.i(TAG, gsonString);            }        }, new Response.ErrorListener() {            @Override            public void onErrorResponse(VolleyError error) {                tv.setText(error.getMessage());            }        });    }

相比Xml的解析是不是要简单很多呢。先是建立Gson对象,然后调用fromJson()方法,第一个参数是Json字符串,第二个是Class.class,最后获得里层对象。来看一下结果。
这里写图片描述

Fastjson解析

Fastjson 是一个性能很好的 Java 语言实现的 JSON 解析器和生成器,来自阿里巴巴的工程师。在解析方法上与Gson并无太大区别,依旧需要一个javaBean。下面来看下解析方法。

    private void fastjsonParser() {        stringRequest = new MyStringRequests(url, new Response.Listener<String>() {            @Override            public void onResponse(String response) {                Weathers myWeathers = JSON.parseObject(response, Weathers.class);                Weathers.WeatherinfoEntity myWeatherInfo = myWeathers.getWeatherinfo();                tv.setText(myWeatherInfo.toString());//                String fastjsonStr = JSON.toJSONString(myWeatherInfo);//                Log.i(TAG, fastjsonStr);            }        }, new Response.ErrorListener() {            @Override            public void onErrorResponse(VolleyError error) {                tv.setText(error.getMessage());            }        });    }

可以看到这里仅仅是用到JSON.parseObject(),其他与Gson一模一样。下面是结果。
这里写图片描述

自定义GsonRequest

同样以下是学习郭霖大神博客所得。看过上一篇XmlRequest后,相信大家很快能写出GsonRequest。

    class GsonRequest<T> extends Request<T>{        private Gson mGson;        private Response.Listener<T> mListener;        private Class<T> mClass;        public GsonRequest(int method, String url, Class<T> clazz, Response.Listener<T> listener, Response.ErrorListener errorListener) {            super(method, url, errorListener);            mGson = new Gson();            mListener = listener;            mClass = clazz;        }        public GsonRequest(String url, Class<T> clazz, Response.Listener<T> listener, Response.ErrorListener errorListener) {            this(Method.GET, url, clazz,listener, errorListener);        }        @Override        protected Response<T> parseNetworkResponse(NetworkResponse response) {            try {                String jsonString = new String(response.data, "utf-8");                return Response.success(mGson.fromJson(jsonString, mClass), HttpHeaderParser.parseCacheHeaders(response));            } catch (UnsupportedEncodingException e) {                return Response.error(new ParseError(e));            }        }        @Override        protected void deliverResponse(T response) {            mListener.onResponse(response);        }    }

可以看到,GsonRequest的不同在于里面存在class对象和泛型T。在实例化GsonRequest时,多传了个参数就是class对象,因为调用fromJson()方法时需要用到。而为什么泛型是T,是因为我们的Json字符串是不定的,建立的JavaBean也是不同的,所以需要指定任意类型。
使用到的接口是:http://mobile.weather.com.cn/data/sk/101010100.html?_=1381891661455。下面解析方法与上面的一样,就不多说了,直接看代码。

public class Weathers {    /**     * sk_info : {"date":"20131012","cityName":"北京","areaID":"101010100","temp":"21℃","tempF":"69.8℉","wd":"东风","ws":"3级","sd":"39%","time":"15:10","sm":"暂无实况"}     */    private SkInfoEntity sk_info;    public void setSk_info(SkInfoEntity sk_info) {        this.sk_info = sk_info;    }    public SkInfoEntity getSk_info() {        return sk_info;    }    public static class SkInfoEntity {        /**         * date : 20131012         * cityName : 北京         * areaID : 101010100         * temp : 21℃         * tempF : 69.8℉         * wd : 东风         * ws : 3级         * sd : 39%         * time : 15:10         * sm : 暂无实况         */        private String date;        private String cityName;        private String areaID;        private String temp;        private String wd;        private String time;        public void setDate(String date) {            this.date = date;        }        public void setCityName(String cityName) {            this.cityName = cityName;        }        public void setAreaID(String areaID) {            this.areaID = areaID;        }        public void setTemp(String temp) {            this.temp = temp;        }        public void setWd(String wd) {            this.wd = wd;        }        public void setTime(String time) {            this.time = time;        }        public String getDate() {            return date;        }        public String getCityName() {            return cityName;        }        public String getAreaID() {            return areaID;        }        public String getTemp() {            return temp;        }        public String getWd() {            return wd;        }        public String getTime() {            return time;        }        public String toString() {            return date + cityName + areaID + temp + wd + time;        }    }}
RequestQueue mQueue = Volley.newRequestQueue(this);GsonRequest<Weathers> mGsonRequest = new GsonRequest<Weathers>("http://mobile.weather.com.cn/data/sk/101010100.html?_=1381891661455",        Weathers.class, new Response.Listener<Weathers>() {    @Override    public void onResponse(Weathers response) {        Weathers.SkInfoEntity weatherInfo = response.getSk_info();        Log.d("Tag", weatherInfo.toString());        text.setText(weatherInfo.toString());    }}, new Response.ErrorListener() {    @Override    public void onErrorResponse(VolleyError error) {        Log.e("Tag", error.getMessage(), error);        text.setText(error.getMessage());    }});mQueue.add(mGsonRequest);

只需要几个字段的信息,下面是打印结果。
这里写图片描述

由于本人水平实在有限,如有错误之处,还望不吝赐教!

0 0