1、什么是JSON

JSON:JavaScript Object Notation,一种轻量级的数据交换格式。用于软件与软件之间、服务器与客户端之间的数据交换。它是一种独立于编程语言的数据格式,有很强的的可读性,而且由于字符简洁,它的传输速度很快。

2、JSON的语法格式

JSON支持的数据类型有:基本类型数据(如字符串、数字等)、对象、数组。在JSON中,对象用 { } 括起来,数组用 [ ] ,存在映射关系的数据(键值对)用 :表示关系,如 “name” : " Alex"。键值对之间用 ,隔开。比如下面这个例子:

{
  "teamName": "Avengers",
  "teamMembers": [
    {
      "name": "TonyStark",
      "AKA": "IronMan"
    },
    {
      "name": "SteveRogers",
      "AKA": "CaptainAmerica"
    },
    {
      "name": "ThorOdinson",
      "AKA": "Thor"
    },
    {
      "name": "BruceBanner",
      "AKA": "Hulk"
    },
    {
      "name":"Natasha Romanoff",
      "AKA": "BlackWidow"
    },
    {
      "name": "ClintBarton",
      "AKA": "Hawkeye"
    }
  ],
  "teamLeader": "NickFury",
  "mission": "keep the world safe"
}

有一些JSON在线解析工具可以很清楚的看到JSON文档的结构,上述JSON文档解析后呈现如下结构:

JSON 字符串映射对象 java_json

3、JSON相关解析工具

目前JSON的解析工具有很多,比如谷歌的GSON、阿里巴巴的FastJson等,使用这两个工具都要去下载相关的jar包,并导入项目中使用。
GSON jar包下载地址:https://search.maven.org/artifact/com.google.code.gson/gson/2.8.6/jar
fastjson jar包下载地址:https://search.maven.org/search?q=a:fastjson
接下来以gson为例讲解json的生成和解析。

4、GSON工具

接下来以上面的json文件为例来说明GSON工具的使用方法。

4.1、生成

因为上面的例子中有一个大对象Avengers里面包含了一个对象数组即成员,每个成员都是一个对象,所以这里用了两个类Team和Member,类的内容如下(属性的getter和setter方法省略):

class Team{
    String teamName;
    String teamLeader;
    String mission;
    ArrayList members;

    public Team(String teamName, String teamLeader,String mission, ArrayList members) {
        this.teamName = teamName;
        this.teamLeader = teamLeader;
        this.mission = mission;
        this.members = members;
    }
    @Override
    public String toString() {
        return "Team{" +
                "teamName='" + teamName + '\'' +
                ", teamLeader='" + teamLeader + '\'' +
                ", mission='" + mission + '\'' +
                ", members=" + members.toString() +
                '}';
    }
}
class Member{
    String name;
    String AKA;
    public Member(String name, String AKA) {
        this.name = name;
        this.AKA = AKA;
    }
    public Member() {
    }  
    @Override
    public String toString() {
        return "Member{" +
                "name='" + name + '\'' +
                ", AKA='" + AKA + '\'' +
                '}';
    }
}

接着创建对象和对象数组,包括6个复仇者联盟成员,把这6个成员放到meembers数组里,再创建Avengers对象,具体如下:

Member m1 = new Member("TonyStark","IronMan");
Member m2 = new Member("SteveRogers","CaptainAmerica");
Member m3 = new Member("ThorOdinson","Thor");
Member m4 = new Member("BruceBanner","Hulk");
Member m5 = new Member("NatashaRomanoff","BlackWidow");
Member m6 = new Member("ClintBarton","Hawkeye");
ArrayList<Member> members = new ArrayList();
members.add(m1);
members.add(m2);
members.add(m3);
members.add(m4);
members.add(m5);
members.add(m6);
Team Avengers = new Team("Avengers","NickFury","keep the world safe",members);

将上述内容转成json格式:

Gson gson = new Gson();
String s = gson.toJson(Avengers,Team.class);

json内容如下:

{"teamName":"Avengers","teamLeader":"NickFury","mission":"keep the world safe","members":[{"name":"TonyStark","AKA":"IronMan"},{"name":"SteveRogers","AKA":"CaptainAmerica"},{"name":"ThorOdinson","AKA":"Thor"},{"name":"BruceBanner","AKA":"Hulk"},{"name":"NatashaRomanoff","AKA":"BlackWidow"},{"name":"ClintBarton","AKA":"Hawkeye"}]}

也可以直接写入json文件:

Writer writer = new FileWriter("Avengers.json");
gson.toJson(Avengers,writer);
writer.close();

这里记得要刷新或者关闭缓存区,否则文件里没有内容。

4.2、解析

如果我们拿到的是一个json格式的字符串,可以通过以下方式读:

String str = "{\"teamName\":\"Avengers\",\"teamLeader\":\"NickFury\",\"mission\":\"keep the world safe\",\"members\":[{\"name\":\"TonyStark\",\"AKA\":\"IronMan\"},{\"name\":\"SteveRogers\",\"AKA\":\"CaptainAmerica\"},{\"name\":\"ThorOdinson\",\"AKA\":\"Thor\"},{\"name\":\"BruceBanner\",\"AKA\":\"Hulk\"},{\"name\":\"NatashaRomanoff\",\"AKA\":\"BlackWidow\"},{\"name\":\"ClintBarton\",\"AKA\":\"Hawkeye\"}]}";
Gson g = new Gson();
HashMap hashMap = g.fromJson(str, HashMap.class);

通过转为HashMap类型,可以通过HashMap的相关操作获取json数据。比如通过keyset()可以获取键值对的键,和上面在json在线解析工具解析后得到的视图一样,通过get()可以获取对应的值:

System.out.println("key: "+hashMap.keySet());
for (Object o: hashMap.keySet()) {
    System.out.println(o+":"+hashMap.get(o));
}

结果如下:

JSON 字符串映射对象 java_java_02


这里的member是一个数组,也可以转为数组的格式:

ArrayList members = (ArrayList) hashMap.get("members");

如果已经存在对应的类,可以直接转为对应的类:

Team Avengers = g.fromJson(str,Team.class);

从文件中读(要转为Reader):

InputStream is = new FileInputStream("Avengers.json");
Reader reader = new InputStreamReader(is);
Team Avengers = g.fromJson(reader,Team.class);

5、fastjson工具

同样以上面的json数据来说明fastjson的使用方法。

5.1、生成

上面创建Team和Member类在这里不再赘述。在创建成功以后,使用JSON.toJSONString()方法,可以转成String类型,注意相关属性要提供getter方法,否则转后的JSON数据里没有这个属性。

String str = JSON.toJSONString(Avengers);

测试了在把Team里所有的getMember方法注释掉以后,打印出来的结果就不包含members信息:

JSON 字符串映射对象 java_JSON_03


除了转成字符串以外,也可以转成文件:

Writer w = new FileWriter("AvengersFastJson.json");
JSON.writeJSONString(w,Avengers);
w.close();

5.2、解析

当获得了json格式的字符串时,可以解析成hashMap类型:

String str = "{\"members\":[{\"aKA\":\"IronMan\",\"name\":\"TonyStark\"},{\"aKA\":\"CaptainAmerica\",\"name\":\"SteveRogers\"},{\"aKA\":\"Thor\",\"name\":\"ThorOdinson\"},{\"aKA\":\"Hulk\",\"name\":\"BruceBanner\"},{\"aKA\":\"BlackWidow\",\"name\":\"NatashaRomanoff\"},{\"aKA\":\"Hawkeye\",\"name\":\"ClintBarton\"}],\"mission\":\"keep the world safe\",\"teamLeader\":\"NickFury\",\"teamName\":\"Avengers\"}";
HashMap hashMap = JSON.parseObject(str, HashMap.class);
System.out.println(hashMap.keySet());
for (Object o : hashMap.keySet()) {
     System.out.println(o + ": " + hashMap.get(o));
}

如果存在对应的类,可以解析成该类,解析后可以调用类的方法和属性:

Team Avengers = JSON.parseObject(str, Team.class);

从文件中读入(可以直接读入字节流):

InputStream is = new FileInputStream("AvengersFastJson.json");
Team Avengers = JSON.parseObject(is,Team.class);