zoukankan      html  css  js  c++  java
  • 【json的处理】一、Gson处理

    目前处理json的方法有很多,这里主要总结四种方法

    1. Gson方式处理json 【json的处理】一、Gson处理

    2. FastJson方式处理json 【json的处理】三、FastJson的处理

    3. Jackson方式处理json 【json的处理】二、Jackson的处理

    4. json-flattener方式处理json 【json的处理】四、json-flattener的处理

    本文主要介绍Gson的方式

    Gson提供了十几个fromJson()和toJson()方法,前者实现反序列化,后者实现了序列化。尽量要2.4版本以上的,因为alternate需要2.4版本。下面会介绍alternate。

    话不多说,直接上干货

    前言:

    下面主要通过几个方面来介绍gson:

    1. json对象的处理

    2. json数组的处理

    3. json对象套json数组的处理

    需要引入依赖

    <!-- 这里需要引入Gson的依赖 -->
    <dependency>
        <groupId>com.google.code.gson</groupId>
        <artifactId>gson</artifactId>
        <version>2.8.6</version>
    </dependency>

    一、json对象的处理

    1. 首先先来看下最简单的(json串中key名与user实体类名称一致)

    //一个没有层级关系的普通的json对象.
    {
      "name": "张三",
      "age": "22",
      "email": "1432299080@qq.com",
      "sex": "男",
      "height": "178"
    }
    
    //一个User实体类,名称与json串中的名称完全一样.
    @Data
    public class User {
    
        private String name;
        private String age;
        private String email;
        private String sex;
        private String height;
        
    }
    
    //测试方法
    public class gsonTest {
        public static void main(String[] args) {
            //定义一个json对象格式的字符串
            String jsonStr = "{
    " +
                    "  "name": "张三",
    " +
                    "  "age": "22",
    " +
                    "  "email": "1432299080@qq.com",
    " +
                    "  "sex": "男",
    " +
                    "  "height": "178"
    " +
                    "}";
            //使用gson的fromJson方法将字符串转化成对象
            Gson gson = new Gson();
            User user = gson.fromJson(jsonStr, User.class);
            //User(name=张三, age=22, email=1432299080@qq.com, sex=男, height=178)
            System.out.println(user);
        }
    }

     2. 那么json串中key名与user实体类名称不一致该怎么办呢?

    (1)如果继续执行上面的测试代码会发现最终输出的结果为://User(name=null, age=null, email=null, sex=null, height=null)

    (2)处理办法为:使用SerializedName注解的value属性来处理,value:别名

    //准备json串
    {
      "t_name": "张三",
      "t_age": "22",
      "t_email": "1432299080@qq.com",
      "t_sex": "男",
      "t_height": "178"
    }
    
    //准备实体类
    @Data
    public class User {
    
        @SerializedName(value = "t_name")
        private String name;
        @SerializedName(value = "t_age")
        private String age;
        @SerializedName(value = "t_email")
        private String email;
        @SerializedName(value = "t_sex")
        private String sex;
        @SerializedName(value = "t_height")
        private String height;
    
    }
    
    //测试类
    public class gsonTest {
        public static void main(String[] args) {
            //定义一个json对象格式的字符串
            String jsonStr = "{
    " +
                    "  "t_name": "张三",
    " +
                    "  "t_age": "22",
    " +
                    "  "t_email": "1432299080@qq.com",
    " +
                    "  "t_sex": "男",
    " +
                    "  "t_height": "178"
    " +
                    "}";
            //使用gson的fromJson方法将字符串转化成对象
            Gson gson = new Gson();
            User user = gson.fromJson(jsonStr, User.class);
            //User(name=张三, age=22, email=1432299080@qq.com, sex=男, height=178)
            System.out.println(user);
        }
    }

    3. 那么如果是好多家接口同时传递过来不同名称的json串,又该如何处理呢?

    现在想要程序可以同时识别s和t开头的key。处理办法:只需要修改下实体类即可,使用@SerializedName的value和alternate 注解来处理,这里要注意value属性指定的就是类中的名字,而alternate 属性是接收一个String数组。

    //json串
    {
      "s_name": "张三",
      "s_age": "22",
      "s_email": "1432299080@qq.com",
      "s_sex": "男",
      "s_height": "178"
    }
    
    {
      "t_name": "张三",
      "t_age": "22",
      "t_email": "1432299080@qq.com",
      "t_sex": "男",
      "t_height": "178"
    }
    
    //实体类
    @Data
    public class User {
        //alternate需要2.4版本
        @SerializedName(value = "name",alternate = {"t_name","s_name"})
        private String name;
        @SerializedName(value = "age",alternate = {"t_age","s_age"})
        private String age;
        @SerializedName(value = "email",alternate = {"t_email","s_email"})
        private String email;
        @SerializedName(value = "sex",alternate = {"t_sex","s_sex"})
        private String sex;
        @SerializedName(value = "height",alternate = {"t_height","s_height"})
        private String height;
    }
    
    //测试类
    public class gsonTest {
        public static void main(String[] args) {
            //定义一个json对象格式的字符串
            String jsonStr = "{
    " +
                    "  "t_name": "张三",
    " +
                    "  "t_age": "22",
    " +
                    "  "t_email": "1432299080@qq.com",
    " +
                    "  "t_sex": "男",
    " +
                    "  "t_height": "178"
    " +
                    "}";
            //使用gson的fromJson方法将字符串转化成对象
            Gson gson = new Gson();
            User user = gson.fromJson(jsonStr, User.class);
            //User(name=张三, age=22, email=1432299080@qq.com, sex=男, height=178)
            System.out.println(user);
    
            //定义一个json对象格式的字符串
            String jsonStr2 = "{
    " +
                    "  "s_name": "张三",
    " +
                    "  "s_age": "22",
    " +
                    "  "s_email": "1432299080@qq.com",
    " +
                    "  "s_sex": "男",
    " +
                    "  "s_height": "178"
    " +
                    "}";
            //使用gson的fromJson方法将字符串转化成对象
            Gson gson2 = new Gson();
            User user2 = gson.fromJson(jsonStr2, User.class);
            //User(name=张三, age=22, email=1432299080@qq.com, sex=男, height=178)
            System.out.println(user2);
        }
    }

    二、 json数组的处理

    准备:

    一个没有层级的json对象组成的json数组

    使用gson提供的数据类型转换器TypeToken来处理,这里要提一下,它可以支持各种数据集合类型转换

    如果确定了数组中只有一个json对象,那么可以直接使用上面的fromJson方法并返回User对象

    //json串
    [
      {
        "t_name": "张三",
        "t_age": "22",
        "t_sex": "男",
        "t_email": "12345677890@qq.com",
        "t_height": "178"
      },
      {
        "t_name": "小红",
        "t_age": "22",
        "t_sex": "女",
        "t_email": "1987654321@qq.com",
        "t_height": "165"
      }
    ]
    
    //实体类
    @Data
    public class User {
    
        @SerializedName(value = "name",alternate = {"t_name","s_name"})
        private String name;
        @SerializedName(value = "age",alternate = {"t_age","s_age"})
        private String age;
        @SerializedName(value = "email",alternate = {"t_email","s_email"})
        private String email;
        @SerializedName(value = "sex",alternate = {"t_sex","s_sex"})
        private String sex;
        @SerializedName(value = "height",alternate = {"t_height","s_height"})
        private String height;
    
    }
    
    //测试类
    public class gsonTest {
        public static void main(String[] args) {
            String jsonStr = "[
    " +
                    "  {
    " +
                    "    "t_name": "张三",
    " +
                    "    "t_age": "22",
    " +
                    "    "t_sex": "男",
    " +
                    "    "t_email": "12345677890@qq.com",
    " +
                    "    "t_height": "178"
    " +
                    "  },
    " +
                    "  {
    " +
                    "    "t_name": "小红",
    " +
                    "    "t_age": "22",
    " +
                    "    "t_sex": "女",
    " +
                    "    "t_email": "1987654321@qq.com",
    " +
                    "    "t_height": "165"
    " +
                    "  }
    " +
                    "]";
            Gson gson = new Gson();
            Type type = new TypeToken<List<User>>() {}.getType();
            List<User> userList = gson.fromJson(jsonStr, type);
            //[User(name=张三, age=22, email=12345677890@qq.com, sex=男, height=178),
            // User(name=小红, age=22, email=1987654321@qq.com, sex=女, height=165)]
            System.out.println(userList);
        }
    }

    三、json对象套json数组的处理

    1. 一般我们在开发的过程中,数据往往都没有上面那么整齐,那么针对整体是一个json对象,里面有json数组的情况该如何处理呢?

    //准备一个特殊的json串,json对象中包含json数组且有且仅有一个数据头
    {
      "user": [
        {
          "t_name": "张三",
          "t_age": "22",
          "t_sex": "男",
          "t_email": "12345677890@qq.com",
          "t_height": "178"
        },
        {
          "t_name": "小红",
          "t_age": "22",
          "t_sex": "女",
          "t_email": "1987654321@qq.com",
          "t_height": "165"
        }
      ]
    }
    
    //实体类
    @Data
    public class User {
    
        @SerializedName(value = "name",alternate = {"t_name","s_name"})
        private String name;
        @SerializedName(value = "age",alternate = {"t_age","s_age"})
        private String age;
        @SerializedName(value = "email",alternate = {"t_email","s_email"})
        private String email;
        @SerializedName(value = "sex",alternate = {"t_sex","s_sex"})
        private String sex;
        @SerializedName(value = "height",alternate = {"t_height","s_height"})
        private String height;
    
    }
    
    //测试类
    public static void main(String[] args) {
        String jsonStr = "{
    " +
            "  "user": [
    " +
            "    {
    " +
            "      "t_name": "张三",
    " +
            "      "t_age": "22",
    " +
            "      "t_sex": "男",
    " +
            "      "t_email": "12345677890@qq.com",
    " +
            "      "t_height": "178"
    " +
            "    },
    " +
            "    {
    " +
            "      "t_name": "小红",
    " +
            "      "t_age": "22",
    " +
            "      "t_sex": "女",
    " +
            "      "t_email": "1987654321@qq.com",
    " +
            "      "t_height": "165"
    " +
            "    }
    " +
            "  ]
    " +
            "}";
        //先转换成json对象
        JsonObject jsonObject = new JsonParser().parse(jsonStr).getAsJsonObject();
        //再获取数据头并转换成json数组
        JsonArray jsonArray = jsonObject.getAsJsonArray("user");
        
        //方法1  ------------------------------------------------------------------
        Gson gson = new Gson();
        Type type = new TypeToken<List<User>>() {}.getType();
        List<User> userList = gson.fromJson(jsonArray.toString(), type);
        //[User(name=张三, age=22, email=12345677890@qq.com, sex=男, height=178),
        // User(name=小红, age=22, email=1987654321@qq.com, sex=女, height=165)]
        System.out.println(userList);
        
        //方法2  ------------------------------------------------------------------
        Gson gson2 = new Gson();
        ArrayList<User> userList2 = new ArrayList<>();
        //循环遍历
        for (JsonElement user : jsonArray) {
            //通过反射 得到UserBean.class
            User userTemp = gson.fromJson(user, new TypeToken<User>() {}.getType());
            userList2.add(userTemp);
        }
        //[User(name=张三, age=22, email=12345677890@qq.com, sex=男, height=178),
        // User(name=小红, age=22, email=1987654321@qq.com, sex=女, height=165)]
        System.out.println(userList2);
    }

    2. 那么如果是json对象中同时包含普通字符串和json数组呢?

    解决办法:这里需要修改下实体类了,即按照json的格式来处理

    //准备json
    {
      "roles": "学生",
      "auth": "上课",
      "user": [
        {
          "t_name": "张三",
          "t_age": "22",
          "t_sex": "男",
          "t_email": "12345677890@qq.com",
          "t_height": "178"
        },
        {
          "t_name": "小红",
          "t_age": "22",
          "t_sex": "女",
          "t_email": "1987654321@qq.com",
          "t_height": "165"
        }
      ]
    }
    
    //实体类
    @Data
    public class JsonTest {
        private String roles;
        private String auth;
        private List<User> user;
    }
    
    @Data
    public class User {
        @SerializedName(value = "name",alternate = {"t_name","s_name"})
        private String name;
        @SerializedName(value = "age",alternate = {"t_age","s_age"})
        private String age;
        @SerializedName(value = "email",alternate = {"t_email","s_email"})
        private String email;
        @SerializedName(value = "sex",alternate = {"t_sex","s_sex"})
        private String sex;
        @SerializedName(value = "height",alternate = {"t_height","s_height"})
        private String height;
    }
    
    //测试类
    public class gsonTest {
        public static void main(String[] args) {
            String jsonStr = "{
    " +
                    "  "roles": "学生",
    " +
                    "  "auth": "上课",
    " +
                    "  "user": [
    " +
                    "    {
    " +
                    "      "t_name": "张三",
    " +
                    "      "t_age": "22",
    " +
                    "      "t_sex": "男",
    " +
                    "      "t_email": "12345677890@qq.com",
    " +
                    "      "t_height": "178"
    " +
                    "    },
    " +
                    "    {
    " +
                    "      "t_name": "小红",
    " +
                    "      "t_age": "22",
    " +
                    "      "t_sex": "女",
    " +
                    "      "t_email": "1987654321@qq.com",
    " +
                    "      "t_height": "165"
    " +
                    "    }
    " +
                    "  ]
    " +
                    "}";
            JsonTest jsonTest = new Gson().fromJson(jsonStr, JsonTest.class);
            //JsonTest(roles=学生, auth=上课, 
            //user=[User(name=张三, age=22, email=12345677890@qq.com, sex=男, height=178),
            //User(name=小红, age=22, email=1987654321@qq.com, sex=女, height=165)])
            System.out.println(jsonTest);
        }
    }

    3. 那么如果再复杂一点呢?比如说json对象里面同时含有字符串、json对象、json数组呢?

    处理办法:仍然是修改实体类

    其实从这几种情况来看,如果json格式发生了变化,那么处理办法就是修改总的jsonTest类。

    //准备json
    {
      "roles": "学生",
      "auth": "上课",
      "teacher": {
        "name": "张老师",
        "age": "40"
      },
      "user": [
        {
          "t_name": "张三",
          "t_age": "22",
          "t_sex": "男",
          "t_email": "12345677890@qq.com",
          "t_height": "178"
        },
        {
          "t_name": "小红",
          "t_age": "22",
          "t_sex": "女",
          "t_email": "1987654321@qq.com",
          "t_height": "165"
        }
      ]
    }
    
    //实体类
    @Data
    public class JsonTest {
        private String roles;
        private String auth;
        private Course course;
        private List<User> user;
    }
    
    @Data
    public class Course {
        private String name;
        private String type;
    }
    
    @Data
    public class User {
        @SerializedName(value = "name",alternate = {"t_name","s_name"})
        private String name;
        @SerializedName(value = "age",alternate = {"t_age","s_age"})
        private String age;
        @SerializedName(value = "email",alternate = {"t_email","s_email"})
        private String email;
        @SerializedName(value = "sex",alternate = {"t_sex","s_sex"})
        private String sex;
        @SerializedName(value = "height",alternate = {"t_height","s_height"})
        private String height;
    }
    
    //测试类
    public static void main(String[] args) {
        String jsonStr = "{
    " +
            "  "roles": "学生",
    " +
            "  "auth": "上课",
    " +
            "  "course": {
    " +
            "    "name": "高数",
    " +
            "    "type": "数学"
    " +
            "  },
    " +
            "  "user": [
    " +
            "    {
    " +
            "      "t_name": "张三",
    " +
            "      "t_age": "22",
    " +
            "      "t_sex": "男",
    " +
            "      "t_email": "12345677890@qq.com",
    " +
            "      "t_height": "178"
    " +
            "    },
    " +
            "    {
    " +
            "      "t_name": "小红",
    " +
            "      "t_age": "22",
    " +
            "      "t_sex": "女",
    " +
            "      "t_email": "1987654321@qq.com",
    " +
            "      "t_height": "165"
    " +
            "    }
    " +
            "  ]
    " +
            "}";
        JsonTest jsonTest = new Gson().fromJson(jsonStr, JsonTest.class);
        //JsonTest(roles=学生, auth=上课, course=com.winterchen.model.Course@41975e01,
        //user=[User(name=张三, age=22, email=12345677890@qq.com, sex=男, height=178),
        //User(name=小红, age=22, email=1987654321@qq.com, sex=女, height=165)])
        System.out.println(jsonTest);
    }

    4. 下面补充一个特殊情况:json对象中有json数组,json数组中还有json数组

    //准备json
    {
      "roles": "学生",
      "auth": "上课",
      "course": {
        "name": "高数",
        "type": "数学"
      },
      "user": [
        {
          "t_name": "张三",
          "t_age": "22",
          "t_sex": "男",
          "t_email": "12345677890@qq.com",
          "t_height": "178",
          "family": [
            {
              "f_name": "张大三",
              "f_relation": "父亲"
            },
            {
              "f_name": "刘女士",
              "f_relation": "母亲"
            }
          ]
        },
        {
          "t_name": "小红",
          "t_age": "22",
          "t_sex": "女",
          "t_email": "1987654321@qq.com",
          "t_height": "165"
        }
      ]
    }
    
    //准备实体类
    @Data
    public class JsonTest {
        private String roles;
        private String auth;
        private Course course;
        private List<User> user;
    }
    @Data
    public class Course {
        private String name;
        private String type;
    }
    @Data
    public class Family {
        private String f_name;
        private String f_relation;
    }
    @Data
    public class User {
        @SerializedName(value = "name",alternate = {"t_name","s_name"})
        private String name;
        @SerializedName(value = "age",alternate = {"t_age","s_age"})
        private String age;
        @SerializedName(value = "email",alternate = {"t_email","s_email"})
        private String email;
        @SerializedName(value = "sex",alternate = {"t_sex","s_sex"})
        private String sex;
        @SerializedName(value = "height",alternate = {"t_height","s_height"})
        private String height;
        @SerializedName(value = "family",alternate = {"t_family","s_family"})
        private List<Family> family;
    }
    
    //测试类
    public static void main(String[] args) {
        String jsonStr = "{
    " +
            "  "roles": "学生",
    " +
            "  "auth": "上课",
    " +
            "  "course": {
    " +
            "    "name": "高数",
    " +
            "    "type": "数学"
    " +
            "  },
    " +
            "  "user": [
    " +
            "    {
    " +
            "      "t_name": "张三",
    " +
            "      "t_age": "22",
    " +
            "      "t_sex": "男",
    " +
            "      "t_email": "12345677890@qq.com",
    " +
            "      "t_height": "178",
    " +
            "      "t_family": [
    " +
            "        {
    " +
            "          "f_name": "张大三",
    " +
            "          "f_relation": "父亲"
    " +
            "        },
    " +
            "        {
    " +
            "          "f_name": "刘女士",
    " +
            "          "f_relation": "母亲"
    " +
            "        }
    " +
            "      ]
    " +
            "    },
    " +
            "    {
    " +
            "      "t_name": "小红",
    " +
            "      "t_age": "22",
    " +
            "      "t_sex": "女",
    " +
            "      "t_email": "1987654321@qq.com",
    " +
            "      "t_height": "165"
    " +
            "    }
    " +
            "  ]
    " +
            "}";
        JsonTest jsonTest = new Gson().fromJson(jsonStr, JsonTest.class);
        //JsonTest(roles=学生, auth=上课, course=Course(name=高数, type=数学),
        // user=[User(name=张三, age=22, email=12345677890@qq.com, sex=男, height=178,
        // family=[Family(f_name=张大三, f_relation=父亲), Family(f_name=刘女士, f_relation=母亲)]),
        // User(name=小红, age=22, email=1987654321@qq.com, sex=女, height=165, family=null)])
        System.out.println(jsonTest);
    }

    持续更新!!!! 

  • 相关阅读:
    Python迭代器的反复使用
    快速求幂模运算实现
    rural lifestyle & city lifestyle
    Python实现 扩展的欧几里德算法求(模逆数)最大公约数
    jupyter themes一行命令设置个人最爱界面
    python数组、矩阵相乘的多种方式
    有一组整型数,其中除了2个数字以外的其它数字都是俩俩成对出现的,编写程序找出这2个不成对出现的数字。
    Linux线程池技术处理多任务
    编写函数求两个整数 a 和 b 之间的较大值。要求不能使用if, while, switch, for, ?: 以 及任何的比较语句。
    C++const类型的引用参数
  • 原文地址:https://www.cnblogs.com/flyinghome/p/14636278.html
Copyright © 2011-2022 走看看