Json源码解析与使用

96
独角的犀牛
2018.07.13 14:31 字数 2302

目录介绍

0.提问环节

1.基本使用

1.1 Gson对象创建

1.2 生成Json字符串

1.3 fromJson之Json数组转化为字符串数组

1.4 toJson之字符串数组转为Json数组

1.5 fromJson之Json数组转为List

1.6 toJson之List转为Json数组

1.7 toJson之List转为Json数组

1.8 fromJson之Json数组转为List

2.高级使用

2.1 序列化和反序列化

2.2 序列化

2.3 反序列化

2.4 字段过滤

2.5 属性重命名

2.6 个性化设置

2.7 TypeAdapter

2.8 JsonSerializer序列化接口

2.9 JsonDeserializer反序列化接口

3.0 将请求网络日志按照一定格式展示

3.源码分析

3.1 后期添加

4.知识拓展

关于链接

1.技术博客汇总

2.开源项目汇总

3.生活博客汇总

4.喜马拉雅音频汇总

5.程序员聊天笔记汇总

5.其他汇总

1.基本使用

1.1 Gson对象创建

1.1.1 直接通过new来创建对象

//通过构造函数来获取

Gson gson = new Gson();

//通过 GsonBuilder 来获取,可以进行多项特殊配置

Gson gson = new GsonBuilder().create();

1.1.2 通过单利方式创建全局对象

private static Gson gson = null;

static {

    if (gson == null) {

        gson = new GsonBuilder()

                .setLenient()// json宽松

                .enableComplexMapKeySerialization()//支持Map的key为复杂对象的形式

                .serializeNulls() //智能null

                .setPrettyPrinting()// 调教格式

                .disableHtmlEscaping()

                .registerTypeAdapter(int.class, new JsonDeserializer() {//根治服务端int 返回""空字符串

                    @Override

                    public Integer deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {

                        //try catch不影响效率

                        try {

                            return json.getAsInt();

                        } catch (NumberFormatException e) {

                            return 0;

                        }

                    }

                })

                .create();

    }

}

public static Gson getGson() {

    return gson;

}

1.2 生成Json字符串

1.2.1 代码如下所示

private void toJson() {

    JsonObject jsonObject = new JsonObject();

    jsonObject.addProperty("String", "leavesC");

    jsonObject.addProperty("Number_Integer", 23);

    jsonObject.addProperty("Number_Double", 22.9);

    jsonObject.addProperty("Boolean", true);

    jsonObject.addProperty("Char", 'c');

    //Log.e(TAG,jsonObject.getAsString());      //这个会崩溃

    Log.e(TAG,jsonObject.toString());

    Log.e(TAG,jsonObject+"");

    //{"String":"leavesC","Number_Integer":23,"Number_Double":22.9,"Boolean":true,"Char":"c"}

    //{"String":"leavesC","Number_Integer":23,"Number_Double":22.9,"Boolean":true,"Char":"c"}

}

1.2.2 addProperty方法

支持String,boolean,char,Number(包含:int,long,float,double,byte,short)

public void addProperty(String property, String value) {

    add(property, createJsonElement(value));

}

public void addProperty(String property, Number value) {

    add(property, createJsonElement(value));

}

public void addProperty(String property, Boolean value) {

    add(property, createJsonElement(value));

}

public void addProperty(String property, Character value) {

    add(property, createJsonElement(value));

}

1.2.3 通过 JsonObject 自己来构建一个 JsonElement

addProperty 方法底层调用的是 add(String property, JsonElement value) 方法,即将基本数据类型转化为了 JsonElement 对象,JsonElement 是一个抽象类,而 JsonObject 继承了 JsonElement ,因此我们可以通过 JsonObject 自己来构建一个 JsonElement

//注意这个方法返回JsonElement对象

private JsonElement createJsonElement(Object value) {

    return value == null ? JsonNull.INSTANCE : new JsonPrimitive(value);

}

1.2.4 json解析步骤

首先获取JSON元素数组:JSONArray jsonArray = new JSONArray(jsonData);

其次循环获取每个元素:JSONObject jsonObject = jsonArray.getJSONObject(index);

每次循环保存名称相对应的值:String name = jsonObject.getString("name");

1.3 Json数组转化为字符串数组

private void jsonToArray() {

    //Json数组 转为 字符串数组

    String[] arr = {"2222","3333","4444","5555"};

    //這種崩潰

    //String jsonArray = "{\"2222\",\"3333\",\"4444\",\"5555\"}";

    //這種正常

    String jsonArray = "[\"2222\",\"3333\",\"4444\",\"5555\"]";

    String[] strings = gson.fromJson(jsonArray, String[].class);

    System.out.println("Json数组 转为 字符串数组: ");

    for (String string : strings) {

        Log.e(TAG,string);

    }

}

打印日志:

2222

3333

4444

5555

1.4 toJson之字符串数组转为Json数组

private void arrayToJson() {

    String jsonArray = "[\"2222\",\"3333\",\"4444\",\"5555\"]";

    //字符串数组 转为 Json数组

    jsonArray = gson.toJson(jsonArray, new TypeToken() {}.getType());

    Log.e(TAG,jsonArray);


    //打印日誌

    //"[\"2222\",\"3333\",\"4444\",\"5555\"]"

}

1.5 fromJson之Json数组转为List

private void jsonToList() {

    //Json数组 转为 List

    String jsonArray = "[\"2222\",\"3333\",\"4444\",\"5555\"]";

    List stringList = gson.fromJson(jsonArray, new TypeToken>() {}.getType());

    for (String string : stringList) {

        Log.e(TAG,string);

    }

}

1.6 toJson之List转为Json数组

private void listToJson() {

    String jsonArray = "[\"2222\",\"3333\",\"4444\",\"5555\"]";

    List stringList = gson.fromJson(jsonArray, new TypeToken>() {}.getType());

    //List 转为 Json数组

    jsonArray = gson.toJson(stringList, new TypeToken>() {}.getType());

    Log.e(TAG,jsonArray);

    //打印日誌

    //["2222","3333","4444","5555"]

}

1.7 toJson之List转为Json数组

private void listModelToJson() {

    Person model1 = new Person("yangChong", 25, true);

    Person model2 = new Person("doubi", 26, false);

    final ArrayList lists = new ArrayList<>();

    lists.add(model1);

    lists.add(model2);

    Gson gson = new Gson();

    String s = gson.toJson(lists);

    Log.e(TAG,s);

    //打印日志

    //[{"age":25,"name":"yangChong","sex":true},{"age":26,"name":"doubi","sex":false}]

}

1.8 fromJson之Json数组转为List

private void jsonToListMode() {

    String json = "[{\"age\":25,\"name\":\"yangChong\",\"sex\":true},{\"age\":26,\"name\":\"doubi\",\"sex\":false}]";

    Gson gson = new Gson();

    List list = gson.fromJson(json, new TypeToken>() {}.getType());

    for (Person person : list) {

        Log.e(TAG,person.toString());

    }

    //打印日志

    //Person{name='yangChong', age=25, sex=true}

    //Person{name='doubi', age=26, sex=false}

}

2.高级使用

2.1 序列化和反序列化

Gson 也提供了 toJson() 和 fromJson() 两个方法用于转化 Model 与 Json,前者实现了序列化,后者实现了反序列化。

2.2 序列化

将model对象转变成json字符串

private void personModelToJson() {

    //序列化

    Person person = new Person("yangChong", 25, true);

    Gson gson = new Gson();

    String s = gson.toJson(person);

    Log.e(TAG,s);

    //打印日志

    //{"age":25,"name":"yangChong","sex":true}

}

2.3 反序列化

将json字符串转变成model对象

private void jsonToPersonModel() {

    //反序列化

    String userJson = "{\"age\":25,\"name\":\"yangChong\",\"sex\":true}";

    Gson gson = new Gson();

    Person person = gson.fromJson(userJson, Person.class);

    Log.e(TAG,person.toString());

    //打印日志

    //Person{name='yangChong', age=25, sex=true}

}

2.5 属性重命名

2.6 个性化设置

gson = new GsonBuilder()            //builder构建者模式

        .setLenient()              //json宽松

        .enableComplexMapKeySerialization() //支持Map的key为复杂对象的形式

        .setPrettyPrinting()        //格式化输出

        .serializeNulls()          //智能null

        //.setDateFormat("yyyy-MM-dd HH:mm:ss:SSS")      //格式化时间

        .disableHtmlEscaping()      //默认是GSON把HTML转义的

        .registerTypeAdapter(int.class, new JsonDeserializer() {

            //根治服务端int 返回""空字符串

            @Override

            public Integer deserialize(JsonElement json, Type typeOfT,

                                      JsonDeserializationContext context)

                    throws JsonParseException {

                //try catch不影响效率

                try {

                    return json.getAsInt();

                } catch (NumberFormatException e) {

                    return 0;

                }

            }

        })

        .create();

2.7 TypeAdapter

TypeAdapter 是一个泛型抽象类,用于接管某种类型的序列化和反序列化过程,包含两个抽象方法,分别用于自定义序列化和反序列化过程

2.7.1 举个例子

定义 TypeAdapter 的子类 UserTypeAdapter 来接管 User 类的序列化和反序列化过程

这里设定当 User 类序列化时 Json 中的Key值都是大写字母开头,反序列化时支持“name”和“Name”两种不同的 Json 风格

public class UserTypeAdapter extends TypeAdapter {

    /**

    * 序列化

    */

    @Override

    public void write(JsonWriter jsonWriter, User user) throws IOException {

        //流式序列化成对象开始

        jsonWriter.beginObject();

        //将Json的Key值都指定为大写字母开头

        jsonWriter.name("Name").value(user.getName());

        jsonWriter.name("Age").value(user.getAge());

        jsonWriter.name("Sex").value(user.isSex());

        //流式序列化结束

        jsonWriter.endObject();

    }

    /**

    * 反序列化

    */

    @Override

    public User read(JsonReader jsonReader) throws IOException {

        User user = new User();

        //流式反序列化开始

        jsonReader.beginObject();

        while (jsonReader.hasNext()) {

            switch (jsonReader.nextName()) {

                //首字母大小写均合法

                case "userName":

                case "name":

                case "Name":

                    user.setName(jsonReader.nextString());

                    break;

                case "age":

                    user.setAge(jsonReader.nextInt());

                    break;

                case "sex":

                    user.setSex(jsonReader.nextBoolean());

                    break;

            }

        }

        //流式反序列化结束

        jsonReader.endObject();

        return user;

    }

}

2.7.2 序列化和反序列化

2.8 JsonSerializer序列化接口

/**

* 序列化过程

*/

@SuppressLint("LongLogTag")

private void toJsonSerializer() {

    Gson gson = new GsonBuilder().registerTypeAdapter(User.class, new JsonSerializer() {

        @Override

        public JsonElement serialize(User user, Type type, JsonSerializationContext jsonSerializationContext) {

            JsonObject jsonObject = new JsonObject();

            jsonObject.addProperty("NameHi", user.getName());

            jsonObject.addProperty("Sex", user.isSex());

            jsonObject.addProperty("Age", user.getAge());

            return jsonObject;

        }

    }).create();

    User user = new User("leavesC", 24, true);

    String s = gson.toJson(user);

    Log.e(TAG,s);

}

2.9 JsonDeserializer反序列化接口

/**

* 反序列化过程

*/

private void toJsonDeserializer() {

    Gson gson = new GsonBuilder().registerTypeAdapter(User.class, new JsonDeserializer() {

        @Override

        public User deserialize(JsonElement jsonElement, Type type, JsonDeserializationContext jsonDeserializationContext) throws JsonParseException {

            JsonObject jsonObject = jsonElement.getAsJsonObject();

            String name = null;

            //同时支持 userName 和 name 两种情况

            if (jsonObject.has("userName")) {

                name = jsonObject.get("userName").getAsString();

            } else if (jsonObject.has("name")) {

                name = jsonObject.get("name").getAsString();

            }

            int age = jsonObject.get("age").getAsInt();

            boolean sex = jsonObject.get("sex").getAsBoolean();

            return new User(name, age, sex);

        }

    }).create();

    String json = "{\"userName\":\"leavesC\",\"sex\":true,\"age\":24}";

    User user = gson.fromJson(json, User.class);

    System.out.println();

    System.out.println(user);

    json = "{\"name\":\"leavesC\",\"sex\":true,\"age\":24}";

    user = gson.fromJson(json, User.class);

    System.out.println();

    System.out.println(user);

}

3.0 将请求网络日志按照一定格式展示

private static final String LINE_SEPARATOR = System.getProperty("line.separator");

public static void printJson(String tag, String msg) {

    String message;

    try {

        if (msg.startsWith("{")) {

            JSONObject jsonObject = new JSONObject(msg);

            //最重要的方法,就一行,返回格式化的json字符串,其中的数字4是缩进字符数

            message = jsonObject.toString(4);

        } else if (msg.startsWith("[")) {

            JSONArray jsonArray = new JSONArray(msg);

            message = jsonArray.toString(4);

        } else {

            message = msg;

        }

    } catch (JSONException e) {

        message = msg;

    }

    if(isGoodJson(message)){

        printLine(tag, true);

        String[] lines = message.split(LINE_SEPARATOR);

        for (String line : lines) {

            Log.e(tag, "║ " + line);

        }

        printLine(tag, false);

    }

}

private static void printLine(String tag, boolean isTop) {

    if (isTop) {

        Log.e(tag, "Http---------------------");

    } else {

        Log.e(tag, "Http---------------------");

    }

}

private static boolean isGoodJson(String json) {

    if (TextUtils.isEmpty(json)) {

        return false;

    }

    try {

        new JsonParser().parse(json);

        return true;

    } catch (JsonSyntaxException e) {

        return false;

    } catch (JsonParseException e) {

        return false;

    }

}

如图,日志格式如下所示:

>>>>阅读全文

日记本