【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 = "{\n" +
                "  \"name\": \"张三\",\n" +
                "  \"age\": \"22\",\n" +
                "  \"email\": \"1432299080@qq.com\",\n" +
                "  \"sex\": \"男\",\n" +
                "  \"height\": \"178\"\n" +
                "}";
        //使用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 = "{\n" +
                "  \"t_name\": \"张三\",\n" +
                "  \"t_age\": \"22\",\n" +
                "  \"t_email\": \"1432299080@qq.com\",\n" +
                "  \"t_sex\": \"男\",\n" +
                "  \"t_height\": \"178\"\n" +
                "}";
        //使用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 = "{\n" +
                "  \"t_name\": \"张三\",\n" +
                "  \"t_age\": \"22\",\n" +
                "  \"t_email\": \"1432299080@qq.com\",\n" +
                "  \"t_sex\": \"男\",\n" +
                "  \"t_height\": \"178\"\n" +
                "}";
        //使用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 = "{\n" +
                "  \"s_name\": \"张三\",\n" +
                "  \"s_age\": \"22\",\n" +
                "  \"s_email\": \"1432299080@qq.com\",\n" +
                "  \"s_sex\": \"男\",\n" +
                "  \"s_height\": \"178\"\n" +
                "}";
        //使用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 = "[\n" +
                "  {\n" +
                "    \"t_name\": \"张三\",\n" +
                "    \"t_age\": \"22\",\n" +
                "    \"t_sex\": \"男\",\n" +
                "    \"t_email\": \"12345677890@qq.com\",\n" +
                "    \"t_height\": \"178\"\n" +
                "  },\n" +
                "  {\n" +
                "    \"t_name\": \"小红\",\n" +
                "    \"t_age\": \"22\",\n" +
                "    \"t_sex\": \"女\",\n" +
                "    \"t_email\": \"1987654321@qq.com\",\n" +
                "    \"t_height\": \"165\"\n" +
                "  }\n" +
                "]";
        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 = "{\n" +
        "  \"user\": [\n" +
        "    {\n" +
        "      \"t_name\": \"张三\",\n" +
        "      \"t_age\": \"22\",\n" +
        "      \"t_sex\": \"男\",\n" +
        "      \"t_email\": \"12345677890@qq.com\",\n" +
        "      \"t_height\": \"178\"\n" +
        "    },\n" +
        "    {\n" +
        "      \"t_name\": \"小红\",\n" +
        "      \"t_age\": \"22\",\n" +
        "      \"t_sex\": \"女\",\n" +
        "      \"t_email\": \"1987654321@qq.com\",\n" +
        "      \"t_height\": \"165\"\n" +
        "    }\n" +
        "  ]\n" +
        "}";
    //先转换成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 = "{\n" +
                "  \"roles\": \"学生\",\n" +
                "  \"auth\": \"上课\",\n" +
                "  \"user\": [\n" +
                "    {\n" +
                "      \"t_name\": \"张三\",\n" +
                "      \"t_age\": \"22\",\n" +
                "      \"t_sex\": \"男\",\n" +
                "      \"t_email\": \"12345677890@qq.com\",\n" +
                "      \"t_height\": \"178\"\n" +
                "    },\n" +
                "    {\n" +
                "      \"t_name\": \"小红\",\n" +
                "      \"t_age\": \"22\",\n" +
                "      \"t_sex\": \"女\",\n" +
                "      \"t_email\": \"1987654321@qq.com\",\n" +
                "      \"t_height\": \"165\"\n" +
                "    }\n" +
                "  ]\n" +
                "}";
        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 = "{\n" +
        "  \"roles\": \"学生\",\n" +
        "  \"auth\": \"上课\",\n" +
        "  \"course\": {\n" +
        "    \"name\": \"高数\",\n" +
        "    \"type\": \"数学\"\n" +
        "  },\n" +
        "  \"user\": [\n" +
        "    {\n" +
        "      \"t_name\": \"张三\",\n" +
        "      \"t_age\": \"22\",\n" +
        "      \"t_sex\": \"男\",\n" +
        "      \"t_email\": \"12345677890@qq.com\",\n" +
        "      \"t_height\": \"178\"\n" +
        "    },\n" +
        "    {\n" +
        "      \"t_name\": \"小红\",\n" +
        "      \"t_age\": \"22\",\n" +
        "      \"t_sex\": \"女\",\n" +
        "      \"t_email\": \"1987654321@qq.com\",\n" +
        "      \"t_height\": \"165\"\n" +
        "    }\n" +
        "  ]\n" +
        "}";
    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 = "{\n" +
        "  \"roles\": \"学生\",\n" +
        "  \"auth\": \"上课\",\n" +
        "  \"course\": {\n" +
        "    \"name\": \"高数\",\n" +
        "    \"type\": \"数学\"\n" +
        "  },\n" +
        "  \"user\": [\n" +
        "    {\n" +
        "      \"t_name\": \"张三\",\n" +
        "      \"t_age\": \"22\",\n" +
        "      \"t_sex\": \"男\",\n" +
        "      \"t_email\": \"12345677890@qq.com\",\n" +
        "      \"t_height\": \"178\",\n" +
        "      \"t_family\": [\n" +
        "        {\n" +
        "          \"f_name\": \"张大三\",\n" +
        "          \"f_relation\": \"父亲\"\n" +
        "        },\n" +
        "        {\n" +
        "          \"f_name\": \"刘女士\",\n" +
        "          \"f_relation\": \"母亲\"\n" +
        "        }\n" +
        "      ]\n" +
        "    },\n" +
        "    {\n" +
        "      \"t_name\": \"小红\",\n" +
        "      \"t_age\": \"22\",\n" +
        "      \"t_sex\": \"女\",\n" +
        "      \"t_email\": \"1987654321@qq.com\",\n" +
        "      \"t_height\": \"165\"\n" +
        "    }\n" +
        "  ]\n" +
        "}";
    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);
}

 

 

持续更新!!!! 

posted @ 2021-04-09 11:08  夏夜凉凉  阅读(529)  评论(0编辑  收藏  举报