阿里巴巴的FastJson数据解析介绍

本文简单介绍一下阿里巴巴的FastJson的json数据解析的简单用法。

FastJson据说是目前Json数据解析最快捷的工具,虽然传闻会有一些bug,但是基本功能还是比较完善的,没有bug。

本文介绍FastJson的基本使用方法,和几个简单的示例,还有一个非常复杂的内部类的解析示例。

如果我们使用Android原生的Json解析字符串,获取一个没有的属性就会报错,
使用FastJson来解析json字符串,把字符串标签的数据赋值给Bean对象,
即使json字符串没有Bean的某个属性,数据也不会报错,只是为”null”或0。

常识:

在json中,数据序列化,就是把数据(Bean对象)转化为json的字符串数据
如果说反序列化,就是把json数据转换成Bean对象或Json对象。

一.FastJson的基本介绍

关于FastJson的详细介绍:https://www.w3cschool.cn/fastjson/fastjson-quickstart.html
FastJson使用起来比Android原生的JsonObject方便很多,FastJson都是调用的静态方法。

1.FastJson反序列化

把json数据转换成Bean对象或Json对象
反序列化使用的方法是:

T t=JSON.parseObject(X,Y,...);

比如:

//转换为Json对象
JSONObject jsonObj = JSON.parseObject(jsonStr);

//转换为Bean对象
Model model = JSON.parseObject(jsonStr, Model.class);

2.FastJson序列化

就是根据对象,获取json字符串或者json的字节数据
使用的方法是:JSON.toJSONString(name.Class);
比如:

//根据类Model获取到对应的json字符串
Model model = ...; 
String jsonStr = JSON.toJSONString(model);

//获取json字符串的字节数据
byte[] jsonBytes = JSON.toJSONBytes(model);

3.把Bean对象的数据放到输出流中

Model model = ...; 
OutputStream os;
JSON.writeJSONString(os, model);

//另一种输出流
Writer writer = ...;
JSON.writeJSONString(writer, model);

当然还有很多其他的静态调用方法,可以直接进入类里面看,或者看文档的API

二.下面是FastJson的简单实用示例代码:

我是用Studio创建的Android项目,但是fastjson这个jar包在java工程中也是通用的。

注意json字符串转变为Bean对象,FastJson解析过程是支持内部类的,Gson支不支持我已经不记得了。

1.Uer类

class User{
    private int id;
    private String name;
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}

2.Group类

class Group{
    private int id;
    private String name;
    private List<User> list = new ArrayList<User>();
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public List<User> getList() {
        return list;
    }
    public void setList(List<User> list) {
        this.list = list;
    }
}

3.weibo类

class Weibo {
    private String id;
    private String city;

    public Weibo(String id, String city) {
        this.id = id;
        this.city = city;
    }

    public Weibo() {
    }

    public String getId() {
        return id;
    }

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

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }
}

4.FastJsonTest类

package com.liwenzhi.json.jsondemo;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;


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

/**
 * 几个调用FastJson的方法使用
 */

public class FastJsonTest {

    public static void doMain() {
        json2JsonObjectM1();//将Json文本数据信息转换为JsonObject对象,然后利用键值对的方式获取信息
        json2BeanM2();      //将Json文本数据转换为JavaBean数据!
        json2JSONArrayM3(); //将json数据转化为JSONArray:
        json2JavaBeanM4();  //将JSON文本转换为JavaBean的集合;转换为单纯的1个Object:parseObject(String text, Class<T> clazz);
        bean2JsonM5();      //将JavaBean转换为Json格式的数据/Json文本 用户数据的传递:例如上传服务器
        bean2JSONObjectM6();//将JavaBean转换为JSON对象
        complexExampleM7(); //一个相对复杂的例子:
        complex2JsonM8();   //一个复杂的Object到Json的Demo
        complexMap2JsonM9();//将Map数据转换为JsonString的Demo;这个对RedBoy服务端不就直接破了嘛!
    }

    /**
     * 将Json文本数据信息转换为JsonObject对象,然后利用键值对的方式获取信息
     */
    private static void json2JsonObjectM1() {
        //一个JsonObject文本数据
        String s = "{\"name\":\"liuzhao\"}";//引号是需要转义的
        //将JsonObject数据转换为Json
        JSONObject object = JSON.parseObject(s);
        //利用键值对的方式获取到值
        System.out.println(object.get("name"));
        /**
         * 打印:
         * liuzhao
         */
    }

    /**
     * 将Json文本数据转换为JavaBean数据!
     * 需要注意的是:这时候的Json文本信息中的键的名称必须和JavaBean中的字段名称一样!键中没有的在这个JavaBean中就显示为null!
     */
    private static void json2BeanM2() {
        String s = "{\"id\":\"0375\",\"city\":\"平顶山\"}";
        //一个简单方便 的方法将Json文本信息转换为JsonObject对象的同时转换为JavaBean对象!
        Weibo weibo = JSON.parseObject(s, Weibo.class);//Weibo类在下边定义
        System.out.println(weibo.getId());
        System.out.println(weibo.getCity());
        //打印的结果     0375
        //             平顶山
    }


    /**
     * 将Map类型的数据转换为JsonString
     */
    private static void complexMap2JsonM9() {
        Group group = new Group();
        group.setId(1);
        group.setName("group");

        User user1 = new User();
        user1.setId(2);
        user1.setName("user1");

        User user2 = new User();
        user2.setId(3);
        user2.setName("user2");
        group.getList().add(user1);
        group.getList().add(user2);

        Map<Integer, Object> map = new HashMap<Integer, Object>();
        map.put(1, "No.1");
        map.put(2, "No.2");
        map.put(3, group.getList());

        String jsonString = JSON.toJSONString(map);
        System.out.println(jsonString);
        /**
         *  输出:{1:"No.1",2:"No.2",3:[{"id":2,"name":"user1"},{"id":3,"name":"user2"}]}
         */
    }

    /**
     * 由一个复杂的Object到Json的Demo
     */
    private static void complex2JsonM8() {
        Group group = new Group();
        group.setId(1);
        group.setName("group");

        User user1 = new User();
        user1.setId(2);
        user1.setName("user1");

        User user2 = new User();
        user2.setId(3);
        user2.setName("user2");
        group.getList().add(user1);
        group.getList().add(user2);
        String jsonString = JSON.toJSONString(group);
        System.out.println(jsonString);
        /**
         *  输出:{"id":1,"list":[{"id":2,"name":"user1"},{"id":3,"name":"user2"}],"name":"group"}
         */
    }

    /**
     * 一个相对复杂的例子:
     * JSON文本数据:
     * 首先是JSONObject,转换为JSONArray;
     * 然后将JSONArray转换为JavaBean
     */
    private static void complexExampleM7() {
        String s = "{js:[{id:\"110000\",\"city\":\"北#001京市\"},{id:\"110000\",\"city\":\"北#002京市\"}"
                + ",{id:\"110000\",\"city\":\"北#002京市\"},{id:\"110000\",\"city\":\"北#002京市\"},"
                + "{id:\"110000\",\"city\":\"#006北#005京市\"},"
                + "{id:\"110000\",\"city\":\"北#002京市\"},"
                + "{id:\"110000\",\"city\":\"北#002京市\"},{id:\"120000\",\"city\":\"天#009津市\"}]}";

        JSONObject object = JSON.parseObject(s);
        Object jsonArray = object.get("js");
        System.out.println(jsonArray);
        List<Weibo> list = JSON.parseArray(jsonArray + "", Weibo.class);
        for (Weibo weibo : list) {
            System.out.println(weibo.getCity());
        }
        /**
         * 打印:
         * 北#001京市
         * 北#002京市
         * 北#002京市
         * 北#002京市
         * #006北#005京市
         * 北#002京市
         * 北#002京市
         * 天#009津市
         */

    }

    /**
     * 将JavaBean转换为JSON对象
     */
    private static void bean2JSONObjectM6() {
        Weibo weibo = new Weibo("0373", "洛阳");
        JSONObject json = (JSONObject) JSON.toJSON(weibo);
        System.out.println(json.get("id"));
        /**
         * 打印:
         * 0373
         */
    }

    /**
     * 将JSON文本转换为JavaBean的集合;
     * 内部实现肯定是:首先转换为JSONArray,然后再转换为List集合
     */
    private static void json2JavaBeanM4() {
        String s = "[{\"id\":\"0375\",\"city\":\"平顶山\"},{\"id\":\"0377\",\"city\":\"南阳\"}]";
        List<Weibo> list = JSON.parseArray(s, Weibo.class);
        for (Weibo weibo : list) {
            System.out.println(weibo.getCity());
        }
        /**
         * 打印:
         * 平顶山
         * 南阳
         */
    }

    /**
     * 将json数据转化为JSONArray:
     * 注意:获取到JSONArray之后(我们这里只是获取到JSONArray而不是JavaBean的List集合)
     * 获取JSONArray中的数据转换为String类型需要在外边加"";
     */
    private static void json2JSONArrayM3() {
        String s = "[{\"id\":\"0375\",\"city\":\"平顶山\"},{\"id\":\"0377\",\"city\":\"南阳\"}]";
        //将JSON文本转换为JSONArray
        JSONArray array = JSON.parseArray(s);
        //这行必须写:必须加上+"";不然会报出类型强转异常!
        String str = array.get(1) + "";
        System.out.println(array.get(0));
        JSONObject object = JSON.parseObject(str);
        System.out.println(object.get("id"));
        /**
         * {"city":"平顶山","id":"0375"}
         0377
         */
    }


    /**
     * 将JavaBean转换为Json格式的数据/Json文本
     * 用户数据的传递:例如上传服务器
     */
    private static void bean2JsonM5() {
        Weibo weibo = new Weibo("123456", "上海");
        String string = JSON.toJSONString(weibo);
        System.out.println(string);
        /**
         * 打印:
         * {"city":"上海","id":"123456"}
         */
    }

}

5.Cmd类

package com.liwenzhi.json.fastjsondemo;

import java.util.List;

/**
 * 有内部类的Bean对象
 */

public class Cmd {
    private String status;
    private String originalText;
    private String responseText;
    private NlpResult nlpResult;
    private String sessionState;

    public String getOriginalText() {
        return originalText;
    }

    public void setOriginalText(String originalText) {
        this.originalText = originalText;
    }

    public NlpResult getNlpResult() {
        return nlpResult;
    }

    public void setNlpResult(NlpResult nlpResult) {
        this.nlpResult = nlpResult;
    }

    public String getStatus() {
        return status;
    }

    public void setStatus(String status) {
        this.status = status;
    }

    public String getSessionState() {
        return sessionState;
    }

    public void setSessionState(String sessionState) {
        this.sessionState = sessionState;
    }

    public String getResponseText() {
        return responseText;
    }

    public void setResponseText(String responseText) {
        this.responseText = responseText;
    }

    @Override
    public String toString() {
        return "Cmd{" +
                "status='" + status + '\'' +
                ", originalText='" + originalText + '\'' +
                ", responseText='" + responseText + '\'' +
                ", nlpResult=" + nlpResult +
                ", sessionState='" + sessionState + '\'' +
                '}';
    }

    class NlpResult {
        private String domain;
        private String state;
        private Integer prefix;
        private Integer suffix;
        private Object object;

        public String getDomain() {
            return domain;
        }

        public void setDomain(String domain) {
            this.domain = domain;
        }

        public String getState() {
            return state;
        }

        public void setState(String state) {
            this.state = state;
        }

        public Integer getPrefix() {
            return prefix;
        }

        public void setPrefix(Integer prefix) {
            this.prefix = prefix;
        }

        public Integer getSuffix() {
            return suffix;
        }

        public void setSuffix(Integer suffix) {
            this.suffix = suffix;
        }

        public Object getObject() {
            return object;
        }

        public void setObject(Object object) {
            this.object = object;
        }

        @Override
        public String toString() {
            return "NlpResult{" +
                    "domain='" + domain + '\'' +
                    ", state='" + state + '\'' +
                    ", prefix=" + prefix +
                    ", suffix=" + suffix +
                    ", object=" + object +
                    '}';
        }

        //涉及到内部类的集合
        class Object {
            private List<Stage> stage;

            public List<Stage> getStage() {
                return stage;
            }

            public void setStage(List<Stage> stage) {
                this.stage = stage;
            }

            @Override
            public String toString() {
                return "Object{" +
                        "stage=" + stage +
                        '}';
            }

            class Stage {
                private String message;
                private String url;
                private String image;

                public String getMessage() {
                    return message;
                }

                public void setMessage(String message) {
                    this.message = message;
                }

                public String getUrl() {
                    return url;
                }

                public void setUrl(String url) {
                    this.url = url;
                }

                public String getImage() {
                    return image;
                }

                public void setImage(String image) {
                    this.image = image;
                }

                @Override
                public String toString() {
                    return "Stage{" +
                            "message='" + message + '\'' +
                            ", url='" + url + '\'' +
                            ", image='" + image + '\'' +
                            '}';
                }
            }

        }
    }

}

6.MainActivity类

package com.liwenzhi.json.fastjsondemo;

import android.content.Intent;
import android.net.Uri;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.TextView;

import com.alibaba.fastjson.JSONObject;

import java.util.List;

public class MainActivity extends AppCompatActivity {

    String TAG = "Json MainActivity";

    //双引号,需要转义
    String text1 = "{\"status\":\"0\",\"originalText\":\"背首诗。\",
无家问死生,寄书长不避,况乃未休兵,\",\"sessionState\":\"01\",\"nlpResult\":{\"domain\":\"play_poem\",\"state\":\"0\",\"prefix\":0,\"suffix\":0,
\"object\":{\"stage\":[{\"message\":\"巴尼就念首《月夜忆舍弟》的古诗吧。\"},
{\"message\":\"戍鼓断人行,秋边一雁声,露从今夜白,月是故乡明,有弟皆分散,无家问死生,寄书长不避,况乃未休兵,\"},
{\"url\":\"http:\\/\\/resource.doudoubot.cn\\/download\\/audio\\/play\\/03-yueyeyishedi.mp3\",
\"image\":\"http:\\/\\/resource.doudoubot.cn\\/download\\/image\\/play\\/play_poem.jpg\"}]}}}";

    String text2 = "{\"status\":\"0\",\"originalText\":\"今天天气怎么样?\",
最低气温26摄氏度,风向南风,最大风速4到5级。\",\"sessionState\":\"01\",
\"nlpResult\":{\"domain\":\"Weather-certain\",\"state\":\"0\",\"prefix\":0,\"suffix\":0,
\"object\":{\"stage\":[{\"message\":\"罗湖,2018年7月26日星期四,天气雷阵雨,当前气温28摄氏度,
最高气温32摄氏度,最低气温26摄氏度,风向南风,最大风速4到5级。\"}]}}}";


    TextView tv_info;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        tv_info = findViewById(R.id.tv_info);

        fastjson1();//非常复杂的json数据转换为Bean对象示例

    }

    private void fastjson1() {
        StringBuffer buffer = new StringBuffer();
        //把json字符串转变为Bean对象
        Cmd cmd = JSONObject.parseObject(text1, Cmd.class);
        buffer.append("originalText:" + cmd.getOriginalText() + "\n");
        buffer.append("responseText:" + cmd.getResponseText() + "\n");
        Cmd.NlpResult nlpResult = cmd.getNlpResult();
        buffer.append("domain:" + nlpResult.getDomain() + "\n");
        Cmd.NlpResult.Object object = nlpResult.getObject();
        List<Cmd.NlpResult.Object.Stage> stages = object.getStage();
        for (int i = 0; i < stages.size(); i++) {
            Cmd.NlpResult.Object.Stage stage = stages.get(i);
            String message = stage.getMessage();
            String url = stage.getUrl();
            String image = stage.getImage();
            if (message != null && !message.equals("null")) {
                buffer.append(i + " message:" + stage.getMessage() + "\n");
            }
            if (url != null && !url.equals("null")) {
                buffer.append(i + " url:" + stage.getUrl() + "\n");
            }
            if (image != null && !image.equals("null")) {
                buffer.append(i + " image:" + stage.getImage() + "\n");
            }
        }

        tv_info.setText("cmd:\n" + buffer.toString());
        Log.i("TAG","cmd:\n"+ buffer.toString());

    }


}

上面如果对text1进行解析打印的数据信息是:

cmd:
    originalText:背首诗。
    responseText:戍鼓断人行,秋边一雁声,露从今夜白,月是故乡明,有弟皆分散,无家问死生,寄书长不避,况乃未休兵,
    domain:play_poem
    0 message:巴尼就念首《月夜忆舍弟》的古诗吧。
    1 message:戍鼓断人行,秋边一雁声,露从今夜白,月是故乡明,有弟皆分散,无家问死生,寄书长不避,况乃未休兵,
    2 url:http://resource.doudoubot.cn/download/audio/play/03-yueyeyishedi.mp3
    2 image:http://resource.doudoubot.cn/download/image/play/play_poem.jpg

对text2进行解析打印的数据信息是:

cmd:
    originalText:今天天气怎么样?
    responseText:罗湖,2018年7月26日星期四,天气雷阵雨,当前气温28摄氏度,最高气温32摄氏度,最低气温26摄氏度,风向南风,最大风速4到5级。
    domain:Weather-certain
    0 message:罗湖,2018年7月26日星期四,天气雷阵雨,当前气温28摄氏度,最高气温32摄氏度,最低气温26摄氏度,风向南风,最大风速4到5级。

从这两个负责的json数据可以看出,FastJson是支持多个内部类的数据转换的。

有时候我们得到一个json字符串,但是如果比较复杂,会不知道怎么写成Bean,
这时可以使用一些软件工具,或者使用在线的转换网址:
http://www.bejson.com/json2javapojo/new/
对于复制的json字符串网址也不能做成内部类,它会帮你生成很多个类,需要自己把外部的类复制到内部就可以了。

FastJson就介绍到这里。