JSON的处理总结

596 阅读22分钟

一、Gson

Gson提供了十几个fromJson()和toJson()方法,前者实现反序列化,后者实现了序列化。尽量要2.4版本以上的,因为alternate需要2.4版本。下面会介绍alternate。
<!-- 这里需要引入Gson的依赖 -->
<dependency>
    <groupId>com.google.code.gson</groupId>
    <artifactId>gson</artifactId>
    <version>2.8.6</version>
</dependency>

1.json对象的处理

(1)json串中key名与实体类名称一致

此种情况为最简单的情况,代码如下
//一个没有层级关系的普通的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(name=null, age=null, email=null, sex=null, height=null) . 处理办法为:使用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);
    }
}

2.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);
    }
}

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

(1)json对象里带json数组的情况处理

一般我们在开发的过程中,数据往往都没有上面那么整齐,那么针对整体是一个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数组呢?解决办法:这里需要修改下实体类了,即按照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对象里面同时含有字符串、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对象中有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);
}

二、FastJson

首先先介绍一下几个容易混淆的概念:
1.json对象:用 { } 表示的
    例:{ "id":"123", "name":"张三", "age":"11"}
2.json数组:由多个json对象组成,用 [ ] 表示的
    例:[{ "id":"123", "name":"张三", "age":"11"},{ "id":"321", "name":"李四", "age":"21"}]
3.序列化:json对象转字符串
4.反序列化:字符串转json对象
<!-- fastjson的依赖 -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.44</version>
</dependency>

1.JsonObject

(1)基本用法

字符串和json之间的转换
//定义一个json对象用来演示
String str = "{ \"id\":\"123\", \"name\":\"张三\", \"age\":\"11\"}";
//【字符串转json对象】
JSONObject jsonObject = JSONObject.parseObject(str);
//【json对象转字符串】
String strTemp = jsonObject.toJSONString();
//【json对象中是否包含某个key】
boolean isHasKey = jsonObject.containsKey("na");
//【json对象中是否包含某个值】
boolean isHasValue = jsonObject.containsValue("123");
//【获取json对象中某个键对应的值】
Object id = jsonObject.get("id");
//【json对象转set】
Set<Map.Entry<String, Object>> entries = jsonObject.entrySet();
//【json对象转Map】
Map<String, String> params = JSONObject.parseObject(jsonObject.toJSONString(), new TypeReference<Map<String, String>>(){});
//【Map转json对象】
String jsonStr_Map = JSONUtils.toJSONString(params);
JSONObject jsonObjectTemp = JSONObject.parseObject(jsonStr_Map);
//【遍历json对象中的所有键值对】
for (Map.Entry<String,Object> entry : jsonObject.entrySet()){
    String key = entry.getKey();
    Object value = entry.getValue();
    System.out.println("key="+key+" value="+value);
}

(2)高级用法

1.实体类与json之间的转换
//实体类
@Data
@AllArgsConstructor
public class TestUser {
    private String name;
    private Integer age;
    private Integer sex;
}

//测试类

//定义一个实体类对象用来演示
TestUser testUser = new TestUser("111",11,1);
//【实体类转json】
JSONObject jsonObj = (JSONObject)JSONObject.toJSON(testUser);
//结果:{"sex":1,"name":"111","age":11}
System.out.println(jsonObj);
//【json转实体类】 反序列化
TestUser testUserTemp = JSONObject.parseObject(jsonObj.toJSONString(), TestUser.class);
//结果:TestUser(name=111, age=11, sex=1)
System.out.println(testUserTemp);

//这里补充一个  list对象转json 
//如果有值为null,会导致这个key都被默认去掉,需要加上SerializerFeature.WriteMapNullValue 
List<User> list = new ArrayList<>();
JSONArray jsonArray = JSONArray.parseArray(JSON.toJSONString(list,SerializerFeature.WriteMapNullValue))
名称含义
QuoteFieldNames输出key时是否使用双引号,默认为true
UseSingleQuotes使用单引号而不是双引号,默认为false
WriteMapNullValue是否输出值为null的字段,默认为false
WriteEnumUsingToStringEnum输出name()或者original,默认为false
UseISO8601DateFormatDate使用ISO8601格式输出,默认为false
WriteNullListAsEmptyList字段如果为null,输出为[],而非null
WriteNullStringAsEmpty字符类型字段如果为null,输出为”“,而非null
WriteNullNumberAsZero数值字段如果为null,输出为0,而非null
WriteNullBooleanAsFalseBoolean字段如果为null,输出为false,而非null
SkipTransientField如果是true,类中的Get方法对应的Field是transient,序列化时将会被忽略。默认为true
SortField按字段名称排序后输出。默认为false
WriteTabAsSpecial把\t做转义输出,默认为false 不推荐
PrettyFormat结果是否格式化,默认为false
WriteClassName序列化时写入类型信息,默认为false。反序列化是需用到
DisableCircularReferenceDetect消除对同一对象循环引用的问题,默认为false
WriteSlashAsSpecial对斜杠’/’进行转义
BrowserCompatible将中文都会序列化为\uXXXX格式,字节数会多一些,但是能兼容IE6,默认为false
WriteDateUseDateFormat全局修改日期格式,默认为false。JSON.DEFFAULT_DATE_FORMAT = “yyyy-MM-dd”;JSON.toJSONString(obj,SerializerFeature.WriteDateUseDateFormat);
DisableCheckSpecialChar一个对象的字符串属性中如果有特殊字符如双引号,将会在转成json时带有反斜杠转移符。如果不需要转义,可以使用这个属性。默认为false
NotWriteRootClassName含义
BeanToArray将对象转为array输出
WriteNonStringKeyAsString含义
NotWriteDefaultValue含义
BrowserSecure含义
IgnoreNonFieldGetter含义
WriteEnumUsingName含义
2.JSONField注解
那么如果我想要在实体类转json的时候,排除掉某些字段该怎么做呢?
答案:使用@JSONField(serialize = false) 注解。(是否参与序列化,false代表该字段不输出,但是如果加了final,这个字段就无法被过滤).
修改后的效果如下:
@Data
@AllArgsConstructor
public class TestUser {
    @JSONField(serialize = false)
    private String name;
    private Integer age;
    private Integer sex;
}

//定义一个实体类对象用来演示
TestUser testUser = new TestUser("111",11,1);
//【实体类转json】
JSONObject jsonObj = (JSONObject)JSONObject.toJSON(testUser);
//结果:{"sex":1,"age":11}
System.out.println(jsonObj);
//【json转实体类】 反序列化
TestUser testUserTemp = JSONObject.parseObject(jsonObj.toJSONString(), TestUser.class);
//结果:TestUser(name=null, age=11, sex=1)
System.out.println(testUserTemp);
那么如果我想要在实体类转json的时候,不使用实体类中的名称该如何做呢?
答案:使用@JSONField(name = "别名") 注解。
使用字段别名,效果如下:
@Data
@AllArgsConstructor
public class TestUser {
    @JSONField(name = "t_name")
    private String name;
    private Integer age;
    private Integer sex;
}

//定义一个实体类对象用来演示
TestUser testUser = new TestUser("111",11,1);
//【实体类转json】
JSONObject jsonObj = (JSONObject)JSONObject.toJSON(testUser);
//结果:{"t_name":"111","sex":1,"age":11}
System.out.println(jsonObj);
//【json转实体类】 反序列化
TestUser testUserTemp = JSONObject.parseObject(jsonObj.toJSONString(), TestUser.class);
//结果:TestUser(name=111, age=11, sex=1)
System.out.println(testUserTemp);
那么如果现在有个时间类型的字段,我想要以固定的格式输出,该怎么办呢?
答案:使用@JSONField(format="yyyy-MM-dd HH:mm:ss") 注解。
下面先添加一个时间字段date,看看添加前后的效果:
@Data
@AllArgsConstructor
public class TestUser {
    private String name;
    private Integer age;
    private Integer sex;
    @JSONField(format="yyyy-MM-dd HH:mm:ss")
    private Date date;
}

//定义一个实体类对象用来演示
TestUser testUser = new TestUser("111",11,1,new Date());
//【实体类转json】
JSONObject jsonObj = (JSONObject)JSONObject.toJSON(testUser);
//添加前结果:{"date":1600485884579,"sex":1,"name":"111","age":11}
//添加后结果:{"date":"2020-09-19 11:25:46","sex":1,"name":"111","age":11}
System.out.println(jsonObj);
//【json转实体类】 反序列化
TestUser testUserTemp = JSONObject.parseObject(jsonObj.toJSONString(), TestUser.class);
//添加前结果:TestUser(name=111, age=11, sex=1, date=Sat Sep 19 11:24:44 CST 2020)
//添加后结果:TestUser(name=111, age=11, sex=1, date=Sat Sep 19 11:25:46 CST 2020)
System.out.println(testUserTemp);
那么如果某个字段的值是null,在序列化的时候,可以看到生成的字符串中没有对应的key,那么我想要实现,如果值为空,给其一个默认值:
这里要提及一个知识:**SerializerFeature**属性,下面列举几个,详细的可以去查api
参考:<https://www.cnblogs.com/wbxk/p/10064737.html>
1.字符类型字段如果为null,输出为"",而非null WriteNullStringAsEmpty
2.数值字段如果为null,输出为0,而非null WriteNullNumberAsZero
3.Boolean字段如果为null,输出为false,而非null WriteNullBooleanAsFalse
4.List字段如果为null,输出为[],而非null WriteNullListAsEmpty
@Data
@AllArgsConstructor
public class TestUser {
    @JSONField(serialzeFeatures=SerializerFeature.WriteNullStringAsEmpty)
    private String name;
    private Integer age;
    private Integer sex;
    @JSONField(format="yyyy-MM-dd HH:mm:ss")
    private Date date;
}

//定义一个实体类对象用来演示
TestUser testUser = new TestUser(null,11,1,new Date());
String jsonStr = JSON.toJSONString(testUser);
//加注解前:{"age":11,"date":"2020-09-19 12:49:07","sex":1}
//加注解后:{"age":11,"date":"2020-09-19 12:48:28","name":"","sex":1}
System.out.println(jsonStr);
现在想要将json对象转换成实体类对象,方法如下:
@Data
public class TestUser {
    private String name;
    private Integer age;
    private Integer sex;
    private Date date;
}

//定义一个实体类对象用来演示
TestUser testUser = new TestUser();
testUser.setName("11");
testUser.setAge(11);
testUser.setSex(1);
String jsonStr = JSON.toJSONString(testUser);
//实体类转成json对象
JSONObject jsonObject = JSONObject.parseObject(jsonStr);
//【json对象转成实体类】
TestUser testUserTemp = JSON.toJavaObject(jsonObject, TestUser.class);
//结果:TestUser(name=11, age=11, sex=1, date=null)
System.out.println(testUserTemp);
这里要注意:上面的例子里我都是用的@AllArgsConstructor来方便我创建实体类数据,但是我发现如果加上了这个注解,在使用toJavaObject方法的时候会报错。不使用这个注解没有问题。报错信息如下:
网上搜的结果为:
实体类中存在内嵌的其它类,将内部类修改为静态内部类即可,但是我这里也没有发现有内部类的字段,于是我尝试将Date类型的屏蔽,结果成功了,暂时还没有想清楚是什么问题
//报错代码如下
@Data
@AllArgsConstructor
public class TestUser {
    private String name;
    private Integer age;
    private Integer sex;
    private Date date;
}

//定义一个实体类对象用来演示
TestUser testUser = new TestUser("111",11,1,new Date());
String jsonStr = JSON.toJSONString(testUser);
JSONObject jsonObject = JSONObject.parseObject(jsonStr);
TestUser testUserTemp = JSON.toJavaObject(jsonObject, TestUser.class);

image.png

2.JsonArray

JsonArray:即json数组,由多个json对象(jsonObject)组成
//定义一个json数组类型的字符串用来演示
String jsonstr = "[{\"sex\":\"1\",\"name\":\"111\",\"age\":\"11\"},{\"sex\":\"0\", \"name\":\"222\",\"age\":\"21\"}]";
//【String转jsonArray】
JSONArray jsonArray = JSONArray.parseArray(jsonstr);
//【jsonArray转String】
String jsonstrTemp = JSON.toJSONString(jsonArray);
//【jsonArray转list】
List list = JSONObject.parseArray(jsonArray.toJSONString());
//【jsonArray转list-->对象】
List<TestUser> testUsers = JSONObject.parseArray(jsonArray.toJSONString(), TestUser.class);
//【list转jsonArray】
List listTemp = new ArrayList();
JSONArray array = JSONArray.parseArray(JSON.toJSONString(listTemp));
//【list转jsonArray--->对象】
List<TestUser> testUserList = new ArrayList<>();
JSONArray array1 = JSONArray.parseArray(JSON.toJSONString(listTemp));
//【String转List】
List<TestUser> testUserList1 = JSONObject.parseArray(jsonstr, TestUser.class);
//【循环获取jsonArray中所有的jsonObject】
for (int i = 0; i < jsonArray.size(); i++) {
    JSONObject jsonObject = jsonArray.getJSONObject(i);
    String id = jsonObject.getString("sex");
    String name = jsonObject.getString("name");
    //这里要注意:age字段也可以用getString方法来获取
    Integer age = jsonObject.getInteger("age");
}

3.JsonObject+JsonArray

如何判断一个不确定格式的json串,每个key对应的类型呢?
//【判断json类型】
String text0 = "11";
String text2 = "{ \"sex\":\"1\", \"name\":\"张三\", \"age\":\"11\"}";
String text3 = "[{ \"sex\":\"1\", \"name\":\"张三\", \"age\":\"11\"},{ \"sex\":\"0\", \"name\":\"李四\", \"age\":\"21\"}]";

Object parse0 = JSON.parse(text0);
System.out.println(parse0 instanceof java.lang.Integer);//true

Object parse2 = JSON.parse(text2);
System.out.println(parse2 instanceof JSONObject);//true

Object parse3 = JSON.parse(text3);
System.out.println(parse3 instanceof JSONArray);//true

三、Jackson

下面主要通过几个方面来介绍jackson:
1. jackson的一些常用方法
2. jackson的一些常用注解
3. JsonNode && ArrayNode && ObjectNode
4. jackson处理文件的导入导出
首先需要引入依赖
jackson-databind 依赖 jackson-core 和 jackson-annotations,当添加 jackson-databind 之后, jackson-core 和 jackson-annotations 也随之添加到 Java 项目工程中。在添加相关依赖包之后,就可以使用 Jackson。
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.11.0</version>
</dependency>

1.jackson的一些常用方法

一些概念和方法的介绍:

ObjectMapperJSON操作的核心,Jackson的所有JSON操作都是在ObjectMapper中实现。

ObjectMapper有多个JSON序列化的方法,可以把JSON字符串保存FileOutputStream等不同的介质中。

writeValue(File arg0, Object arg1)把arg1转成json序列,并保存到arg0文件中。

writeValue(OutputStream arg0, Object arg1)把arg1转成json序列,并保存到arg0输出流中。

writeValueAsBytes(Object arg0)把arg0转成json序列,并把结果输出成字节数组。

writeValueAsString(Object arg0)把arg0转成json序列,并把结果输出成字符串。
//实体类
@Data
@AllArgsConstructor
public class TestUser {
    private String name;
    private Integer age;
    private Integer sex;
    private Date date;
}

//测试类

//定义一个对象用于测试
TestUser testUser = new TestUser("1",11,1,new Date());
TestUser testUser2 = new TestUser("2",22,2,new Date());
ObjectMapper mapper = new ObjectMapper();
//【对象转String】
String str = mapper.writeValueAsString(testUser);
//结果:{"name":"1","age":11,"sex":1,"date":1600595735478}
System.out.println(str);
//【String转对象】这里要注意,版本号2.10.1以上readValue方法就会报错,2.9.5就可以
//报错信息:java.lang.ClassNotFoundException: com.fasterxml.jackson.core.exc.InputCoercionException
TestUser testUserTemp = mapper.readValue(str, TestUser.class);
//结果:TestUser(name=1, age=11, sex=1, date=Sun Sep 20 18:07:43 CST 2020)
System.out.println(testUserTemp);
//list转json-string
List<TestUser> testUserList = new ArrayList<>();
testUserList.add(testUser);
testUserList.add(testUser2);
String json = mapper.writeValueAsString(testUserList);
//结果:[{"name":"1","age":11,"sex":1,"date":1600910383747},{"name":"2","age":22,"sex":2,"date":1600910383747}]
System.out.println(json);

2.jackson的一些常用注解

@JsonIgnore

此注解用于属性上,作用是进行JSON操作时忽略该属性。

@JsonIgnoreProperties

此注解用于类上,作用是忽略多个属性,如:@JsonIgnoreProperties({"userName", "userAge"})

@JsonFormat

此注解用于属性上,作用是把Date类型直接转化为想要的格式,如@JsonFormat(pattern = "yyyy-MM-dd HH-mm-ss")。

@JsonProperty

此注解用于属性上,作用是把该属性的名称序列化为另外一个名称,如把trueName属性序列化为name, @JsonProperty("name")。

@JsonInclude

此注解可用于属性和类上,作用是排除值为null的属性,如:

@JsonInclude(JsonInclude.Include.NON_NULL)-->属性为null不参与序列化。

@JsonInclude(JsonInclude.Include.NON_EMPTY)-->属性为空或者null都不参与序列化。

@JsonUnwrapped

此注解用于属性上,作用:

1. 是去掉外包装\
2. 把成员对象中的属性提升到其容器类,并添加给定的前缀,如:@JsonUnwrapped(prefix = "user_")

@JsonAppend

此注解用于类上,为json添加虚拟属性,如:@JsonAppend(attrs = {@JsonAppend.Attr(value = "version")})

@JsonNaming

此注解用于类上,作用是将驼峰式改成下划线,如:

@JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class)

此外还有:

-   KEBAB_CASE: 属性名单词用短线分隔连接, 比如*hello-world*
-   LOWER_CASE: 属性名用小写字母而且没有分隔符, 比如*helloworld*
-   SNAKE_CASE: 属性名用小写字母而且用下划线做分隔符, 比如*hello_world*
-   UPPER_CAMEL_CASE: 属性名所有单词用大写开头而且没有分隔符, 比如*HelloWorld*

MapperFeature.USE_ANNOTATIONS

禁用所有jackson注解的功能

@JsonPropertyOrder

此注解用于类上,作用是给序列化之后的json排序,如:

@JsonPropertyOrder(value = {"userSex","userAge","userName"})

(1)JsonIgnore && JsonIgnoreProperties

@Data
@AllArgsConstructor
public class TestUser {
    @JsonIgnore
    private String name;
    private Integer age;
    private Integer sex;
    private Date date;
}

//定义一个对象用于测试
TestUser testUser = new TestUser("1",11,1,new Date());
ObjectMapper mapper = new ObjectMapper();
//【对象转String】
String str = mapper.writeValueAsString(testUser);
//加上注解前:{"name":"1","age":11,"sex":1,"date":1600913752059}
//加上注解后:{"age":11,"sex":1,"date":1600913711465}
System.out.println(str);

--------------------------------------------------------------------------------------------

@Data
@AllArgsConstructor
@JsonIgnoreProperties({"userName", "userAge"})
public class TestUser {
    private String userName;
    private Integer userAge;
    private Integer userSex;
}

//定义一个对象用于测试
TestUser testUser = new TestUser("111",11,1);
ObjectMapper mapper = new ObjectMapper();
//【对象转String】
String str = mapper.writeValueAsString(testUser);
//加上注解前:{"userName":"111","userAge":11,"userSex":1}
//加上注解后:{"userSex":1}
System.out.println(str);

(2)JsonFormat

@Data
@AllArgsConstructor
public class TestUser {
    private String name;
    private Integer age;
    private Integer sex;
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date date;
}

//定义一个对象用于测试
TestUser testUser = new TestUser("1",11,1,new Date());
ObjectMapper mapper = new ObjectMapper();
//【对象转String】
String str = mapper.writeValueAsString(testUser);
//加上注解前:{"name":"1","age":11,"sex":1,"date":1600913893613}
//加上注解后:{"name":"1","age":11,"sex":1,"date":"2020-09-24 02:17:56"}
System.out.println(str);

(3)JsonProperty

@Data
@AllArgsConstructor
public class TestUser {
    @JsonProperty("t_name")
    private String name;
    private Integer age;
    private Integer sex;
    private Date date;
}

//定义一个对象用于测试
TestUser testUser = new TestUser("1",11,1,new Date());
ObjectMapper mapper = new ObjectMapper();
//【对象转String】
String str = mapper.writeValueAsString(testUser);
//加上注解前:{"name":"1","age":11,"sex":1,"date":1600913893613}
//加上注解后:{"t_name":"1","age":11,"sex":1,"date":1600913990057}
System.out.println(str);

(4)JsonInclued

@Data
@AllArgsConstructor
public class TestUser {
    @JsonInclude(JsonInclude.Include.NON_NULL)
    private String name;
    private Integer age;
    private Integer sex;
    private Date date;
}

@Data
@AllArgsConstructor
@JsonInclude(JsonInclude.Include.NON_NULL)
public class TestUser {
    private String name;
    private Integer age;
    private Integer sex;
    private Date date;
}

//定义一个对象用于测试
TestUser testUser = new TestUser(null,11,1,new Date());
ObjectMapper mapper = new ObjectMapper();
//【对象转String】
String str = mapper.writeValueAsString(testUser);
//加上注解前:{"name":null,"age":11,"sex":1,"date":1600914468252}
//加上注解后:{"age":11,"sex":1,"date":1600914452682}
System.out.println(str);

(5)JsonUnwrapped

@Data
@AllArgsConstructor
public class TestUser {
    private String name;
    private Integer age;
    private Integer sex;
    @JsonUnwrapped
    private Teacher teacher;
}

@Data
@AllArgsConstructor
public class Teacher {
    private String tel;
    private String email;
}

//定义一个对象用于测试
TestUser testUser = new TestUser("111",11,1,new Teacher("13718999090","12345@qq.com"));
ObjectMapper mapper = new ObjectMapper();
//【对象转String】
String str = mapper.writeValueAsString(testUser);
//加上注解前:{"name":"111","age":11,"sex":1,"teacher":{"tel":"13718999090","email":"12345@qq.com"}}
//加上注解后:{"name":"111","age":11,"sex":1,"tel":"13718999090","email":"12345@qq.com"}
System.out.println(str);

----------------------------------------------------------------------------------------------
    
@Data
@AllArgsConstructor
public class TestUser {
    private String userName;
    private Integer userAge;
    private Integer userSex;
    @JsonUnwrapped(prefix = "user_")
    private Teacher teacher;
}

//定义一个对象用于测试
TestUser testUser = new TestUser("111",11,1,new Teacher("11111","11111@qq.com"));
ObjectMapper mapper = new ObjectMapper();
//【对象转String】
String str = mapper.writeValueAsString(testUser);
//加上注解前:{"userName":"111","userAge":11,"userSex":1,"teacher":{"tel":"11111","email":"11111@qq.com"}}
//加上注解后:{"userName":"111","userAge":11,"userSex":1,"user_tel":"11111","user_email":"11111@qq.com"}
System.out.println(str);

(6)JsonAppend

@Data
@AllArgsConstructor
@JsonAppend(attrs = {@JsonAppend.Attr(value = "version")})
public class TestUser {
    private String name;
    private Integer age;
    private Integer sex;
}

//定义一个对象用于测试
TestUser testUser = new TestUser("111",11,1);
ObjectMapper mapper = new ObjectMapper();
//为虚拟属性添加值
ObjectWriter writer = mapper.writerFor(TestUser.class).withAttribute("version", "1.0");
//【对象转String】
String str = writer.writeValueAsString(testUser);
//加上注解前:{"name":"111","age":11,"sex":1}
//加上注解后:{"name":"111","age":11,"sex":1,"version":"1.0"}
System.out.println(str);

(7)JsonNaming

@Data
@AllArgsConstructor
@JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class)
public class TestUser {
    private String userName;
    private Integer userAge;
    private Integer userSex;
}

//定义一个对象用于测试
TestUser testUser = new TestUser("111",11,1);
ObjectMapper mapper = new ObjectMapper();
//【对象转String】
String str = mapper.writeValueAsString(testUser);
//加上注解前:{"userName":"111","userAge":11,"userSex":1}
//加上注解后:{"user_name":"111","user_age":11,"user_sex":1}
System.out.println(str);

(8)MapperFeature.USE_ANNOTATIONS

@Data
@AllArgsConstructor
@JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class)
public class TestUser {
    private String userName;
    private Integer userAge;
    private Integer userSex;
}

//定义一个对象用于测试
TestUser testUser = new TestUser("111",11,1);
ObjectMapper mapper = new ObjectMapper();
//禁用jackson注解
mapper.disable(MapperFeature.USE_ANNOTATIONS);
//【对象转String】
String str = mapper.writeValueAsString(testUser);
//加上注解前:{"userName":"111","userAge":11,"userSex":1}
//加上注解后:{"userName":"111","userAge":11,"userSex":1}
System.out.println(str);

(9)JsonPropertyOrder

@Data
@AllArgsConstructor
@JsonPropertyOrder(value = {"userSex","userAge","userName"})
public class TestUser {
    private String userName;
    private Integer userAge;
    private Integer userSex;
}

//定义一个对象用于测试
TestUser testUser = new TestUser("111",11,1);
ObjectMapper mapper = new ObjectMapper();
//【对象转String】
String str = mapper.writeValueAsString(testUser);
//加上注解前:{"userName":"111","userAge":11,"userSex":1}
//加上注解后:{"userSex":1,"userAge":11,"userName":"111"}
System.out.println(str);

3.JsonNode && ArrayNode && ObjectNode

ObjectNode
是对象结点,可以存入对象属性。如 { "name":"Lilei", "age":"18", "school":"HNU" }
ArrayNode
是数组结点,用于存放JsonNode数据。如[ "Lilei", "XiaoHong", {"nm1": "Jay", "nm2": "Kong"} ]
JsonNode
是ObjectNode和ArrayNode的父接口。想要生成JsonNode对象都要先生成ObjectMapper类对象,它是产生Json结点的工厂。

(1)JsonNode

String jsonStr = "{\"userName\":\"111\",\"userAge\":11,\"userSex\":1}";
ObjectMapper mapper = new ObjectMapper();
//【JsonNode】
JsonNode jsonNode = mapper.readTree(jsonStr);
//结果:{"userName":"111","userAge":11,"userSex":1}
System.out.println(jsonNode);
//【判断值类型】
String nodeType = jsonNode.get("userName").getNodeType().toString()+"***"+jsonNode.get("userAge").getNodeType().toString();
//结果:STRING***NUMBER
System.out.println(nodeType);
//【遍历key】
Iterator<String> fieldNames = jsonNode.fieldNames();
while (fieldNames.hasNext()) {
    //结果:userName  userAge  userSex
    System.out.println(fieldNames.next());
}
//【遍历value】
Iterator<JsonNode> elements = jsonNode.elements();
while (elements.hasNext()) {
    //结果:"111"  11  1
    System.out.println(elements.next());
}
//【单独获取某个key的值】
JsonNode path = jsonNode.get("userName");
//结果:"111"
System.out.println(path);
//结果:true
System.out.println(jsonNode instanceof ObjectNode);
获取属性、子节点有以下两个方法:

1.path:
    路径访问安全,当访问的结点不存在时返回“MissingNode”,我将其理解为没有任何属性值的结点,也可以通过asText()转换为String类型,值为空字串;当访问的属性无效时同样返回空字串""。
    优势是不知道多层子节点的值是否一定存在时**可以连续使用**path,若不存在一律返回"";但不能判断结点是否存在。
2.get:
    路径访问不安全,其访问结点路径或属性无效时返回null,故使用连续使用get访问时,**若路径不存在会出现空指针异常**。
    优势是可以用是否为null判断结点是否存在。
3.访问技巧:
    不知道节点路径上是否所有节点都存在,可以使用
    JsonNode temp = xxxNode.path("prop1").path("prop2").....get("propN");
    if (null != temp) { do something... } 这样的方式安全得到不一定存在的节点
String jsonStr = "{\"userName\":\"111\",\"userAge\":11,\"userSex\":1}";
ObjectMapper mapper = new ObjectMapper();
//【JsonNode】
JsonNode jsonNode = mapper.readTree(jsonStr);
//【path】
JsonNode path = jsonNode.path("userName");
//结果:"111"
System.out.println(path);
JsonNode kkk = jsonNode.path("kkk");
//结果:空
System.out.println(kkk);
//【连续path】
JsonNode paths = jsonNode.path("a").path("b").path("c");
//结果:空
System.out.println(paths);
//【get】
JsonNode get1 = jsonNode.get("userName");
//结果:"111"
System.out.println(get1);
//结果:null
JsonNode get2 = jsonNode.get("kkk");
System.out.println(get2);
//【连续get】
JsonNode get3 = jsonNode.get("userName").get("kkk");
//结果:null
System.out.println(get3);
//【连续get-->如果get的结果为null之后继续get就会报错】
JsonNode get4 = jsonNode.get("userName").get("kkk").get("kkk");
//结果:java.lang.NullPointerException
System.out.println(get4);
//【asText && asInt】
String userName_userAgeText_userAgeInt = jsonNode.path("userName").asText()+"_"+jsonNode.path("userAge").asText()+"_"+jsonNode.path("userSex").asInt();
//结果:111_11_1
System.out.println(userName_userAgeText_userAgeInt);

(2)ObjectNode

ObjectMapper mapper = new ObjectMapper();
//生成对象结点
ObjectNode objNode = mapper.createObjectNode();
//【put方法--在jdk1.8中,简单值用put设置】
objNode.put("name","111");
objNode.put("age",11);
//结果:{"name":"111","age":11}
System.out.println(objNode);
//【set方法--在jdk1.8中,子节点用set设置】
ObjectNode objectNode = mapper.createObjectNode();
objectNode.put("innername", "222");
objectNode.put("innerage", 22);
objNode.set("inner", objectNode);
//结果:{"name":"111","age":11,"inner":{"innername":"222","innerage":22}}
System.out.println(objNode);

(3)ArrayNode

ObjectMapper mapper = new ObjectMapper();
//【生成数组结点】-->注意:数组结点添加元素不做简单值和结点类的区分
ArrayNode arrNode = mapper.createArrayNode();
arrNode.add("111");
//结果:["111"]
System.out.println(arrNode);
//生成对象结点
ObjectNode objNode = mapper.createObjectNode();
objNode.put("name","111");
objNode.put("age",11);
ArrayNode addObj = arrNode.add(objNode);
//结果:["111",{"name":"111","age":11}]
System.out.println(addObj);

4.Jackson处理文件的导入导出

(1)txt文件的导出

ObjectMapper mapper = new ObjectMapper();
//生成对象结点
ObjectNode objNode = mapper.createObjectNode();
objNode.put("name","111");
objNode.put("age",11);
//【写入txt文件】
OutputStream outputStream= new FileOutputStream(new File("d:/11.txt"));
mapper.writeValue(outputStream, objNode);

image.png

(2)txt文件的导入

ObjectMapper mapper = new ObjectMapper();
//【导入txt文件数据】
JsonNode jsonNode = mapper.readTree(new File("d:/11.txt"));
//结果:{"name":"111","age":11}
System.out.println(jsonNode);

(3)导入导出案例

要求:
根据实体类对象的类型生成相应的json并导出
导入json数据
映射到对象
@Data
@AllArgsConstructor
public class TestUser {
    private String userName;
    private Integer userAge;
    private Integer userSex;
    private Integer[] test;
}

ObjectMapper mapper = new ObjectMapper();
//生成数组节点
ArrayNode arrayNode = mapper.createArrayNode();
arrayNode.add(1);
arrayNode.add(2);
arrayNode.add(3);
//生成对象结点
ObjectNode objNode = mapper.createObjectNode();
objNode.put("userName","111");
objNode.put("userAge",11);
objNode.put("userSex",1);
objNode.put("test",arrayNode);
//【导出】
OutputStream outputStream= new FileOutputStream(new File("d:/test.txt"));
mapper.writeValue(outputStream, objNode);
//【导入】
JsonNode jsonNode = mapper.readTree(new File("d:/test.txt"));
TestUser testUser = mapper.treeToValue(jsonNode, TestUser.class);
//结果:TestUser(userName=111, userAge=11, userSex=1, test=[1, 2, 3])
System.out.println(testUser);

image.png

四、Json-flattener

github地址:<https://github.com/wnameless/json-flattener>
前言
下面主要通过几个方面来介绍json-flattener:
1. 扁平化处理
2. 去扁平化
<!--依赖 -->
<dependency>
     <groupId>com.github.wnameless.json</groupId>
     <artifactId>json-flattener</artifactId>
     <version>0.8.1</version>
 </dependency>

1.扁平化处理

//json
{
    "ip":"192.168.100.100",
    "type":"0",
    "index":"3",
    "timestamp":"1555317936",
    "value":
    [
        {
            "cpuIndex":"0",
            "cpuName":"Intel(R) Xeon(R) CPUE5-2620 v4",
            "cpuCores":"8",
            "cpuFreq":"2.10GHz",
            "cpuRate":"0.85"
        },
        {
            "cpuIndex":"1",
            "cpuName":"Intel(R) Xeon(R) CPUE5-2620 v4",
            "cpuCores":"8",
            "cpuFreq":"2.10GHz",
            "cpuRate":"2.05"
        }
    ]
}

//测试类
String jsonStr = "上面的json";
JSONObject jsonObj = JSONObject.parseObject(jsonStr);
Map<String, Object> flatMap = JsonFlattener.flattenAsMap(jsonObj.toString());
//将 . 改成 , 
//Map<String, Object> flatMap = new JsonFlattener(jsonObj.toString()).withSeparator(',').flattenAsMap();
for (Map.Entry<String, Object> entry : flatMap.entrySet()) {
    System.out.println(entry.getKey() + " : " + entry.getValue());
}

//效果
ip : 192.168.100.100
index : 3
type : 0
value[0].cpuCores : 8
value[0].cpuIndex : 0
value[0].cpuRate : 0.85
value[0].cpuFreq : 2.10GHz
value[0].cpuName : Intel(R) Xeon(R) CPUE5-2620 v4
value[1].cpuCores : 8
value[1].cpuIndex : 1
value[1].cpuRate : 2.05
value[1].cpuFreq : 2.10GHz
value[1].cpuName : Intel(R) Xeon(R) CPUE5-2620 v4
timestamp : 1555317936
#--------------------------------------------------------------------------------
ip : 192.168.100.100
index : 3
type : 0
value[0],cpuCores : 8
value[0],cpuIndex : 0
value[0],cpuRate : 0.85
value[0],cpuFreq : 2.10GHz
value[0],cpuName : Intel(R) Xeon(R) CPUE5-2620 v4
value[1],cpuCores : 8
value[1],cpuIndex : 1
value[1],cpuRate : 2.05
value[1],cpuFreq : 2.10GHz
value[1],cpuName : Intel(R) Xeon(R) CPUE5-2620 v4
timestamp : 1555317936

2.去扁平化

//json
{
  "registro.status": "1",
  "registro.nome": "SUELI",
  "registro.sobrenome": "BERNARDO BRITO",
  "registro.telefone": "1100128500",
  "registro.endereco": "RUA SIVI",
  "registro.numero": "20",
  "registro.complemento": "CS FR",
  "registro.bairro": "CIDADE INDUSTRIAL SATELITE DE SAO PAULO",
  "registro.cep": "07222190",
  "registro.cidade": "GUARULHOS",
  "registro.uf": "SP",
  "registro.cpfcnpj": "12345678900",
  "registro.mae": "TERESINHA",
  "registro.sobrenomemae": "DE FATIMA BERNARDO",
  "registro.nasc": "1995-08-05",
  "registro.protocolo": "320978777"
}

//测试代码
String unflattenJson = JsonUnflattener.unflatten(jsonStr);

//结果
{
  "registro": {
    "status": "1",
    "nome": "SUELI",
    "sobrenome": "BERNARDO BRITO",
    "telefone": "1100128500",
    "endereco": "RUA SIVI",
    "numero": "20",
    "complemento": "CS FR",
    "bairro": "CIDADE INDUSTRIAL SATELITE DE SAO PAULO",
    "cep": "07222190",
    "cidade": "GUARULHOS",
    "uf": "SP",
    "cpfcnpj": "12345678900",
    "mae": "TERESINHA",
    "sobrenomemae": "DE FATIMA BERNARDO",
    "nasc": "1995-08-05",
    "protocolo": "320978777"
  }
}

参考文章

1. www.cnblogs.com/jpfss/p/905… 2. blog.csdn.net/wang_snake/… 3. blog.csdn.net/blwinner/ar… 4. blog.csdn.net/u012510831/… 5. blog.csdn.net/jx2956/arti…