解析JSON常见API

一、 JSON官方API操作

1、JSON官方API操作

(1)JSONObject: 表示一个JSON对象

  1. **JSONObject static fromObject(Object obj):**将obi转换为JSON对象。

  2. JSONObject json=new JSONObject(Object obj)

json.toString(); 通过构造方法创建 JSONObject 对象,再调用toString() 方法转换成JSON字符串

  1. String getxxX(String key)

根据key值拿到对应的value值

将Object对象转换为JSONObject对象,取键值对,迭代器

示例代码:

public class Student {
    private String name;
    private int age;
    private String sex;
    private String bloodType;
    private String department;
    
	public String getName() {
    	return name;
	}

	public void setName(String name) {
    	this.name = name;
	}

	public int getAge() {
    	return age;
	}

	public void setAge(int age) {
    	this.age = age;
	}

	public String getSex() {
    	return sex;
	}

	public void setSex(String sex) {
    	this.sex = sex;
	}

	public String getBloodType() {
    	return bloodType;
	}

	public void setBloodType(String bloodType) {
    	this.bloodType = bloodType;
	}

	public String getDepartment() {
    	return department;
	}

	public void setDepartment(String department) {
    	this.department = department;
	}

	public Student(String name, int age, String sex, String bloodType, String department) {
    	this.name = name;
    	this.age = age;
    	this.sex = sex;
    	this.bloodType = bloodType;
    	this.department = department;
}
@SuppressWarnings("all")
public class Test {
    public static void main(String[] args) {
        Student stu=new Student("张三",30,"男","O型","计算机学院");
        JSONObject jsonObject=JSONObject.fromObject(stu);//把Object对象转换成JSONObject对象
        System.out.println(jsonObject);
        System.out.println(jsonObject.containsKey("sex"));
        System.out.println(jsonObject.containsKey(30));
        System.out.println("age对应的value值"+jsonObject.getInt("age"));
        Collection collection=jsonObject.values();//Collection是List、Set集合里面的父类型
        Iterator its=collection.iterator();
        while (its.hasNext())
            System.out.println(its.next());

        Set set=jsonObject.entrySet();//拿到键值对对应的字符
        Iterator its1=set.iterator();
        while (its1.hasNext())
            System.out.println(its1.next());

        Set set1=jsonObject.keySet();//得到key的集合
        Iterator its2=set1.iterator();
        while (its2.hasNext())
            System.out.println(its2.next());

        Iterator its3=jsonObject.keys();//直接拿到key
         while (its3.hasNext())
            System.out.println(its3.next());
    }
}

2、将JSON字符串转换成Java对象

toBean(JSONObject,Class clazz)

将JSON字符串转换成Java对象要使用JSONObject的toBean()方法

@SuppressWarnings("all")
public class test {
    public static void main(String[] args) {
        Student stu=new Student("zs",20,"男","A型","计算机学院");
        JSONObject jsonObject= JSONObject.fromObject(stu);//把Object对象转换成JSONObject对象
        
        jsonObject.put("籍贯","陕西");//jsonObject添加了新的键值对,在Student中没有对应属性,转换时赋值失败
        Student stu1=(Student) JSONObject.toBean(jsonObject,Student.class);//把jsonobject对象转换为Student类型
        /*将JSON对象像Java对象转换的时候用的反射,用反射的话它会调用无参的构造方法
         * 调用构造方法其实就是在堆内存中开辟新的空间
         * 所以两个不是相同的对象*/
        System.out.println(stu1);
    }
}

问题:JSON键值对怎样和对象属性匹配起来?

通过反射方式调用SetXXX方法来传值

小结:将JSONOnject对象像java类型转换时,要确保Java对象所属的类有无参的构造方法;而且通过属性对应的Set方法给属性赋值,上述方法都是通过反射机制完成。

​ 当Java类很复杂,如果类里面的成员属性是另外一种复合数据类型,可以在JSON里面进行嵌套。

代码主要作用:先将一个对象转换成JSON,然后再从JSON向这个对象转换生成的对象和转换之前的对象不是同一个对象。

原因:将JSON对象像Java对象转换的时候用的反射,用反射的话它会调用无参的构造方法

  • 调用构造方法其实就是在堆内存中开辟新的空间
  • 所以两个不是相同的对象
@SuppressWarnings("all")
public class test {
    public static void main(String[] args) {
    	IDCard idCard=new IDCard("610104200801235284","文林路派出所","2023.1-2033.1");
        Student student=new Student("zs",20,"男","A型","计算机学院",idCard);
        JSONObject jsonObject4=JSONObject.fromObject(student);
        System.out.println(student);

        Student student1=(Student) JSONObject.toBean(jsonObject4,Student.class);
        System.out.println(student1);
        System.out.println(student==student1);//不是同一个对象
    }
}

3、JSON数组

l JSONArray: 代表JSON数组,用法和普通数组类似

(1)JISONArray static fromObject(Object obj)

将obi转换为JSON数组

(2)size()

得到JSON数组中元素的个数

(3)get(int index)

根据下标获取JSON数组中的某个元素

(4)boolean add(Object obj)

将obi添加到JSON数组中

@SuppressWarnings("all")
public class Test2 {
    public static void main(String[] args) {
        Student stu=new Student("张三",30,"男","O型","计算机学院");

        IDCard idCard=new IDCard("610122200102234321","文林路派出所","2001-02-23");
        stu.setIdCard(idCard);
        JSONObject jsonObject=JSONObject.fromObject(stu);//把Object对象转换成JSONObject对象
        Student stu1=new Student("李四",30,"男","O型","计算机学院");

        IDCard idCard1=new IDCard("610122200202234321","文林路派出所","2002-02-23");
        stu1.setIdCard(idCard1);

        JSONArray array=new JSONArray();
        array.add(stu);// //这里虽然添加的是Student类型的对象,它能够自动把Student类型转换成JSONObject
        array.add(stu1);
        array.add(jsonObject);//也可以添加一个JSONObject
        System.out.println(array);
        System.out.println("元素个数是:"+array.size());

        JSONObject obj1=(JSONObject) array.get(2);//根据下标获取JSON数组中的某个元素
        System.out.println(obj1.getString("name"));

首先将Java对象封装起来,然后直接调用fromObject()方法就可以转化成JSONArray。

public class Test2 {
    public static void main(String[] args) {
        
        Map<String,Map<String,Float>> maps=new HashMap<String, Map<String, Float>>();
        
        Map<String,Float> subMap1=new HashMap<String, Float>();
        subMap1.put("四级通过率",0.66f);
        subMap1.put("就业率",0.88f);
        subMap1.put("获奖学生总额",22.0f);
        subMap1.put("入驻大创基地团队数",10.0f);

        Map<String,Float> subMap2=new HashMap<String, Float>();
        subMap2.put("四级通过率",0.56f);
        subMap2.put("就业率",0.68f);
        subMap2.put("获奖学生总额",32.0f);
        subMap2.put("入驻大创基地团队数",15.0f);

        Map<String,Float> subMap3=new HashMap<String, Float>();
        subMap3.put("四级通过率",0.62f);
        subMap3.put("就业率",0.38f);
        subMap3.put("获奖学生总额",27.0f);
        subMap3.put("入驻大创基地团队数",20.0f);

        maps.put("计算机学院",subMap1);
        maps.put("数学与统计",subMap1);
        maps.put("化学与化工",subMap1);

        JSONArray array1=JSONArray.fromObject(maps);
        System.out.println(array1);
    }
}

二、Gson API操作

Google提供的用来在Java对象和JSON 数据之间进行映射的Java 类库,需要导入的jar包: gson-xxx.jar

1、创建Gson对象: Gson1 gson=new Gson0);

(1) 将obi对象转换成JSON字符串

​ String toJson(Object obj)

​ obj可以是普通JavaBean、List或者Map

(2) 根据JSON字符串和要解析成的Java对象字节码生成Java对像

​ T fromJson(String str, Class clazz)

@SuppressWarnings("all")
public class GSONTest {
    public static void main(String[] args) {
        Student stu=new Student("张三",30,"男","O型","计算机学院");

        IDCard idCard=new IDCard("610122200102234321","文林路派出所","2001-02-23");
        stu.setIdCard(idCard);
		//创建Gson对象
        Gson gson=new Gson();

        String jsonStr=gson.toJson(stu);

        System.out.println(jsonStr);
    }
}
运行结果:
    {"name":"张三","age":30,"sex":"男","bloodType":"O型","department":"计算机学院","idCard":{"number":"610122200102234321","publishUnit":"文林路派出所","validDate":"2001-02-23"}}

String newJsonStr = jsonStr.replaceFirst(“计算机学院”,“文学与传播学院”);//调用String的API进行某些操作
不能破坏JSON字符串格式

@SuppressWarnings("all")
public class GSONTest {
    public static void main(String[] args) {
        Student stu=new Student("张三",30,"男","O型","计算机学院");

        IDCard idCard=new IDCard("610122200102234321","文林路派出所","2001-02-23");
        stu.setIdCard(idCard);

        Gson gson=new Gson();

        String jsonStr=gson.toJson(stu);

        System.out.println(jsonStr);

        String newJsonStr = jsonStr.replaceFirst("计算机学院","文学与传播学院");//调用String的API进行某些操作
        //不能破坏JSON字符串格式
        Student stu1 = gson.fromJson(newJsonStr,Student.class);
        System.out.println(stu1);

        String jsonStr2="{'name':'张三','age':30,'sex':'男','bloodType':'AB型','departmentName':'计算机学院'}";
        Student stu2 = gson.fromJson(jsonStr2, Student.class);
        System.out.println(stu2);

    }
}
运行结果:
    {"name":"张三","age":30,"sex":"男","bloodType":"O型","department":"计算机学院","idCard":{"number":"610122200102234321","publishUnit":"文林路派出所","validDate":"2001-02-23"}}

Student{name='张三', age=30, sex='男', bloodType='O型', department='文学与传播学院', idCard=IDCard{number='610122200102234321', publishUnit='文林路派出所', validDate='2001-02-23'}}

Student{name='张三', age=30, sex='男', bloodType='AB型', department='null', idCard=null}

Gons API也可以针对map、list集合进行转换

@SuppressWarnings("all")
public class GSONTest {
    public static void main(String[] args) {
        Student stu=new Student("张三",30,"男","O型","计算机学院");

        IDCard idCard=new IDCard("610122200102234321","文林路派出所","2001-02-23");
        stu.setIdCard(idCard);

        Gson gson=new Gson();

        String jsonStr=gson.toJson(stu);

        System.out.println(jsonStr);

        Map<String,Map<String,Float>> maps=new HashMap<String, Map<String, Float>>();
        Map<String,Float> subMap1=new HashMap<String, Float>();
        subMap1.put("四级通过率",0.66f);
        subMap1.put("就业率",0.88f);
        subMap1.put("获奖学生总额",22.0f);
        subMap1.put("入驻大创基地团队数",10.0f);

        Map<String,Float> subMap2=new HashMap<String, Float>();
        subMap2.put("四级通过率",0.56f);
        subMap2.put("就业率",0.68f);
        subMap2.put("获奖学生总额",32.0f);
        subMap2.put("入驻大创基地团队数",15.0f);

        Map<String,Float> subMap3=new HashMap<String, Float>();
        subMap3.put("四级通过率",0.62f);
        subMap3.put("就业率",0.38f);
        subMap3.put("获奖学生总额",27.0f);
        subMap3.put("入驻大创基地团队数",20.0f);

        maps.put("计算机学院",subMap1);
        maps.put("数学与统计",subMap1);
        maps.put("化学与化工",subMap1);

        String str=gson.toJson(maps);
        System.out.println(str);

    }
}
运行结果:
    {"数学与统计":{"获奖学生总额":22.0,"入驻大创基地团队数":10.0,"四级通过率":0.66,"就业率":0.88},"计算机学院":{"获奖学生总额":22.0,"入驻大创基地团队数":10.0,"四级通过率":0.66,"就业率":0.88},"化学与化工":{"获奖学生总额":22.0,"入驻大创基地团队数":10.0,"四级通过率":0.66,"就业率":0.88}}

2、Java对象与JSON字符串之间的相互转换

GSON 是通过序列化和反序列化技术实现Java对象与JSON字符串之间的相互转换的。

Java对象 _> JSON字符串( 序列化)
JSON字符串 -> Java对象 (反序列化)

GSON 提供了@Expose注解来控制字段是否参与序列化和反序列化。

@Expose //参与序列化与反序列化
private String name:
@Expose(serialize=true,deserialize=false) //参与序列化,不参与反序列化

private int age;
@Expose(serialize=false,deserialize=true) //不参与序列化,参与反序列化

private String sex;

需要通过以下方式创建的Gson对象才能对添加了@Expose注解的对象起作用。

GsonBuilder builder=new GsonBuilder();

builder.excldeFieldsWithoutExposeAnnotation();

Gson gson=builder.create();

(1)序列化实例代码:

​ 1、会忽略没加@Expose的字段;

​ 2、当serialize = false时表明该字段不参与序列化,解析的json串中没有该字段。

​ 3、如果属性是复合属性的话,必须给复合属性中的属性都加上@Expose

public class Student {

    @Expose
    private String name;
    @Expose(serialize = true,deserialize = false)
    private int age;
    @Expose(serialize = false,deserialize = true)
    private String sex;
    private String bloodType;
    private String department;

    private IDCard idCard;//新增的复合数据类型
    }
GsonBuilder builder=new GsonBuilder();
        builder.excludeFieldsWithoutExposeAnnotation();//把没有添加@Expose的字段排除了
        Gson gson1=builder.create();

        String jsonStr2=gson1.toJson(stu);
        System.out.println(jsonStr2);
运行结果:
    {"name":"张三","age":30}

(2)反序列化示例代码:

        Student stu2=gson1.fromJson(jsonStr2,Student.class);
        System.out.println(stu2);

三、FastJSON API的基本操作

FastJson是阿里巴巴开源的Java对象和JSON格式字符串的快速转换的工具库;

需要导入的jar包: fastjson2-xxx.jar

主要通过JSON类的一些静态方法提供转换操作

1、 T parseObject(String txt,Class clazz)

​ 把JSON格式的文本转换成JavaBean

2、 String toJSONString(Object obj)

​ 把JavaBean转换成JSON字符串

JSONObject
表示键值对的JSON对象
SONArray
用来存放JSONObiect的数组

public class FastJSONTest {
    public static void main(String[] args) {
        Student stu=new Student("张三",30,"男","O型","计算机学院");

        IDCard idCard=new IDCard("610122200102234321","文林路派出所","2001-02-23");
        stu.setIdCard(idCard);

        String jsonStr= JSON.toJSONString(stu);

        System.out.println(jsonStr);

        Student stu1=JSON.parseObject(jsonStr,Student.class);

        System.out.println(stu1);
    }
}
运行结果:
    {"age":30,"bloodType":"O型","department":"计算机学院","idCard":{"number":"610122200102234321","publishUnit":"文林路派出所","validDate":"2001-02-23"},"name":"张三","sex":"男"}

Student{name='张三', age=30, sex='男', bloodType='O型', department='计算机学院', idCard=IDCard{number='610122200102234321', publishUnit='文林路派出所', validDate='2001-02-23'}}

FastJson API同样可以解析map和list集合

public class FastJSONTest {
    public static void main(String[] args) {
        Student stu=new Student("张三",30,"男","O型","计算机学院");

        IDCard idCard=new IDCard("610122200102234321","文林路派出所","2001-02-23");
        stu.setIdCard(idCard);

        String jsonStr= JSON.toJSONString(stu);

        System.out.println(jsonStr);

        Student stu1=JSON.parseObject(jsonStr,Student.class);

        System.out.println(stu1);

        String jsonStr1=JSON.toJSONString(stu);

        Map<String,Map<String,Float>> maps=new HashMap<String, Map<String, Float>>();
        Map<String,Float> subMap1=new HashMap<String, Float>();
        subMap1.put("四级通过率",0.66f);
        subMap1.put("就业率",0.88f);
        subMap1.put("获奖学生总额",22.0f);
        subMap1.put("入驻大创基地团队数",10.0f);

        Map<String,Float> subMap2=new HashMap<String, Float>();
        subMap2.put("四级通过率",0.56f);
        subMap2.put("就业率",0.68f);
        subMap2.put("获奖学生总额",32.0f);
        subMap2.put("入驻大创基地团队数",15.0f);

        Map<String,Float> subMap3=new HashMap<String, Float>();
        subMap3.put("四级通过率",0.62f);
        subMap3.put("就业率",0.38f);
        subMap3.put("获奖学生总额",27.0f);
        subMap3.put("入驻大创基地团队数",20.0f);

        maps.put("计算机学院",subMap1);
        maps.put("数学与统计",subMap1);
        maps.put("化学与化工",subMap1);

        String jsonStr2= JSON.toJSONString(maps);

        System.out.println(jsonStr2);


    }
}
运行结果:
    {"age":30,"bloodType":"O型","department":"计算机学院","idCard":{"number":"610122200102234321","publishUnit":"文林路派出所","validDate":"2001-02-23"},"name":"张三","sex":"男"}

Student{name='张三', age=30, sex='男', bloodType='O型', department='计算机学院', idCard=IDCard{number='610122200102234321', publishUnit='文林路派出所', validDate='2001-02-23'}}
{"数学与统计":{"获奖学生总额":22.0,"入驻大创基地团队数":10.0,"四级通过率":0.66,"就业率":0.88},"计算机学院":{"获奖学生总额":22.0,"入驻大创基地团队数":10.0,"四级通过率":0.66,"就业率":0.88},"化学与化工":{"获奖学生总额":22.0,"入驻大创基地团队数":10.0,"四级通过率":0.66,"就业率":0.88}}

对于 JSONObject和 JSONArray的使用:

​ 1、JSONObject表示键值对的JSON对象
​ 2、SONArray用来存放JSONObiect的数组

public class FastJSONTest {
    public static void main(String[] args) {
        Student stu=new Student("张三",30,"男","O型","计算机学院");

        IDCard idCard=new IDCard("610122200102234321","文林路派出所","2001-02-23");
        stu.setIdCard(idCard);

        String jsonStr= JSON.toJSONString(stu);

        System.out.println(jsonStr);

        Student stu1=JSON.parseObject(jsonStr,Student.class);

        System.out.println(stu1);

        String jsonStr1=JSON.toJSONString(stu);

        JSONObject obj=new JSONObject();
        obj.put("name","张明");
        JSONObject obj1=new JSONObject();
        obj.put("age",30);

        JSONArray array=new JSONArray();
        array.add(obj);
        array.add(obj1);

        System.out.println(array);

    }
}

四、Jackson API的基本操作

​ 自称是目前效率最高的JSON字符串与Java对象转换的API,SpringMVC需要 导内置的解析器,同时也是SpringBoot Web启动器默认加载的API。

需要导入的3个jar包:
jackson-core.jar、
jackson-annotaions.jar
jackson-databind.jar

1、首先要创建ObjectMapper对象 :

ObjectMapper mapper=new ObjectMapper0;

(1)根据JSON字符串和要解析成的字节码生成Java对象

mapper.readValue(String str, Class clazz)

(2)将obi对象转换成JSON字符串

mapper.writeValueAsString(Object obj);

(3)以格式化形式输出JSON字符串

ObjectMapper mapper=newObjectMapper0;
mapper.writerWithDefaultPrettyPrinter().writeValueAsString(stu)

按照Student类中属性的顺序来解析

writeValueAsString(stu);要使用 JsonProcessingException 处理运行时异常

@SuppressWarnings("all")
public class JacksonTest {
    public static void main(String[] args) throws JsonProcessingException {
        Student stu=new Student("张三",30,"男","O型","计算机学院");

        IDCard idCard=new IDCard("610122200102234321","文林路派出所","2001-02-23");
        stu.setIdCard(idCard);

        ObjectMapper mapper=new ObjectMapper();

        String str=mapper.writeValueAsString(stu);//要处理运行时异常
        System.out.println(str);

        Student stu1 = mapper.readValue(str, Student.class);
        System.out.println(stu1);

    }
}
运行结果:
    {"name":"张三","age":30,"sex":"男","bloodType":"O型","department":"计算机学院","idCard":{"number":"610122200102234321","publishUnit":"文林路派出所","validDate":"2001-02-23"}}

Student{name='张三', age=30, sex='男', bloodType='O型', department='计算机学院', idCard=IDCard{number='610122200102234321', publishUnit='文林路派出所', validDate='2001-02-23'}}

使用writerWithDefaultPrettyPrinter()方法以格式化形式输出JSON字符串,便于阅读。

        String str = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(stu);

运行结果:
{
  "name" : "张三",
  "age" : 30,
  "sex" : "男",
  "bloodType" : "O型",
  "department" : "计算机学院",
  "idCard" : {
    "number" : "610122200102234321",
    "publishUnit" : "文林路派出所",
    "validDate" : "2001-02-23"
  }
}

2、几个常用注解:

@JsonIgnore:

​ 定义在JavaBean的属性上,那么该属性不参与转换

@JsonProperty:

​ 定义在属性上,给属性起别名:也可以定在属性对应的set方法上(序列化时采用的名称);也可以定义在属性对应的get方法上(反序列时采用的名称)。

@JsonlgnoreProperties(ignoreUnknown = true)

​ 定义在类上,防止JSON字符串中出现的kev值名称与JavaBean属性名欢还让致时抛出的异常。

代码示例:

@JsonIgnore: 表示该属性不参与转换

@Expose
@JsonIgnore
private String name;//表示name属性不参与转换
运行结果:
    {
  "age" : 30,
  "sex" : "男",
  "bloodType" : "O型",
  "department" : "计算机学院",
  "idCard" : {
    "number" : "610122200102234321",
    "publishUnit" : "文林路派出所",
    "validDate" : "2001-02-23"
  }

@JsonProperty: 定义在属性上,给属性起别名;也可出现在set和get方法上

@JsonProperty("年龄")
private int age;
运行结果:
   "年龄" : 30
@JsonProperty("年龄")
public void setAge(int age) {
    this.age = age;
}
@JsonProperty("年龄")
public int getAge() {
    return age;
}

@JsonlgnoreProperties(ignoreUnknown = true)

​ 定义在类上,防止JSON字符串中出现的kev值名称与JavaBean属性名欢还让致时抛出的异常。

@JsonIgnoreProperties(ignoreUnknown = true)
public class Student {
String str2="{\"sex\":\"男\",\"bloodType\":\"O型\",\"city\":\"咸阳\"}";

Student stu1 = mapper.readValue(str2, Student.class);

五、小结

  1. JSON官方API对JSONArray(JSON数组)的操作相对方便。
  2. JSON官方API解析时编写的代码量稍大,其余三种方式代码量小。
  3. 如果要解析大容量的JSON数据,FastJson和Jackson效率高。
  4. 如果要解析小容量的JSON数据GSON效率高。JSON官方API无论在大容量、小容量的JSON数据解析时,效率都一般。
  5. Gson和Jackson这两方API,提供了注解功能,能够轻松控制属性是否参与格式转换。
  6. Gson和FastJson需要的iar包最少,Jackson需要的iar次之,JSON官方需要的iar包最多。JSON官方目前维护比较慢,很长时间没有更新了。
JSONFastJsonJacksonGson
操作对 JSONArray 操作方便
代码量
jar包多且维护慢较少
注解功能提供提供
效率很高
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值