Json入门

来源:互联网 发布:亚投行薪水待遇知乎 编辑:程序博客网 时间:2024/06/08 16:20

JSON(JavaScript Object Notation, JavaScript 对象标记语言) 是一种轻量级的数据交换格式。在 JS 语言中,一切都是对象。因此,任何支持的类型都可以通过 JSON 来表示,例如字符串、数字、对象、数组等JSON 是 JS 对象的字符串表示法,它使用文本表示一个 JS 对象的信息,本质是一个字符串。
JSON 与 JS 对象的关系:JSON 是 JS 对象的字符串表示法,它使用文本表示一个 JS 对象的信息,本质是一个字符串。如:

//这是一个对象,注意键名也是可以使用引号包裹的var obj = {a: 'Hello', b: 'World'}; //这是一个 JSON 字符串,本质是一个字符串var json = '{"a": "Hello", "b": "World"}'; 

JSON 和 JS 对象互转,如:

//从对象转换为 JSON 字符串var json = JSON.stringify({a: 'Hello', b: 'World'}); //从 JSON 转换为对象var obj = JSON.parse('{"a": "Hello", "b": "World"}'); 

Json数据格式应用在很多场景中,笔者在移动应用开发的过程中深有体会。在做安卓项目的时候,服务器端和客户端之间的数据使用了json数据格式作为传输数据的媒介,在客户端将数据转化为json格式通过socket传送到服务器端,在服务器端将json格式的数据解析为对象,再进行数据持久化操作。本文主要介绍两种开源的Json库——JSON和GSON,JSON是Android SDK官方的库,Gson是google开源的库,基本能够满足一般开发过程中的需求。

1. Java中的JSON

1.1 JSON的使用

导入jar包(json.jar)后,我们可以new一个JSONObject对象操作json数据,json支持String、bool、number和数组类型,以下代码是使用put方法往JSON对象中放入数据,最后我们可以通过toString()方法将JSON对象中的数据打印出来。该种方法构建的JSON对象会自动隐藏value为null的整条数据。

JSONObject json = new JSONObject();Object object = null;json.put("name", "lucian");json.put("age", 20);json.put("isBoy", true);json.put("birthday", "1996-8-14");json.put("hobbits", new String[]{"swimming", "bike"});json.put("content", object);System.out.println(json.toString());

1.2 使用Map构建JSON

JSONObject的构造方法中支持传入Map类型参数。由于json中的数据是Key-Value方式存储,而Map的数据格式也Key-Value,所以我们可以通过创建一个Map对象,将数据存入map中,再将map传参进json对象中,放入数据的方式与之前的方法类似。但需要注意的是,Map类是接口,所以不能直接new Map类,需要new Map类的一个具体实现类,下面代码中使用了HashMap作为Map对象的具体实现。

Map map = new HashMap<>();JSONObject json = new JSONObject(map);Object object = null;map.put("name", "lucian");map.put("age", 20);map.put("isBoy", true);map.put("birthday", "1996-8-14");map.put("hobbits", new String[]{"swimming", "bike"});map.put("content", object);System.out.println(json.toString());

1.3 通过javaBean构建JSON对象

在具体项目的开发中,json应用较多的场景是对javaBean进行转化,而不是一个个单独的数据,所以相应的,JSONObject类构造器支持传入对象参数。我们新建了一个People类如下:

public class People {    private String name;    private int age;    private boolean isBoy;    private String birthday;    private String[] hobbits;    private Object content;    public People(String name, int age, boolean isBoy, String birthday, String[] hobbits, Object content) {        super();        this.name = name;        this.age = age;        this.isBoy = isBoy;        this.birthday = birthday;        this.hobbits = hobbits;        this.content = content;    }    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 boolean isBoy() {        return isBoy;    }    public void setBoy(boolean isBoy) {        this.isBoy = isBoy;    }    public String getBirthday() {        return birthday;    }    public void setBirthday(String birthday) {        this.birthday = birthday;    }    public String[] getHobbits() {        return hobbits;    }    public void setHobbits(String[] hobbits) {        this.hobbits = hobbits;    }    public Object getContent() {        return content;    }    public void setContent(Object content) {        this.content = content;    }}

通过构造器模拟创建一个包含数据的People对象,可以直接将该javaBean转化为json对象。

People people = new People("lucian", 20, true, "1996-08-14", new String[]{"swimming", "bike"}, null);JSONObject jsonObject = new JSONObject(people);System.out.println(jsonObject.toString());

1.4 从文件读取json

首先,我们创建一个test.json文本文件,其中存储一些json格式数据,如下:

{    "hobbits": [        "swimming",        "bike"    ],    "name": "lucian",    "age": 20,    "isBoy": true,    "birthday": "1996-8-14",    "content": null}

首先我们需要获取到test.json的路径,然后读取到整个文件的内容,存储到content变量中,注意,这儿我们使用了FileUtils工具包,需要导入commons-io.jar,用于简化整个文件读取的操作。然后将content变量以构造方法传参的形式创建出json对象。

File file = new File(JSONGet.class.getResource("test.json").getPath());String content = FileUtils.readFileToString(file);JSONObject jsonObject = new JSONObject(content);

此时,jsonObjct对象中便存储了test.json的数据。接下来,我们需要了解如何获取该对象中的数据。对于普通的json数据类型,只需要使用getString、getInt等方法便可以获得。代码如下:

System.out.println("name:" + jsonObject.getString("name"));System.out.println("age:" + jsonObject.getInt("age"));

输出:

name:lucianage:20

而对于数组类型的数据较为特殊,需要声明一个JSONArray对象,通过getJSONArray方法将json数组赋给JSONArray对象引用,通过遍历该对象输出数据。代码如下:

JSONArray hobbits = jsonObject.getJSONArray("hobbits");for (int i = 0; i < hobbits.length(); i++) {    System.out.println("hobits-" + (i+1) + hobbits.get(i));}

输出如下:

hobits-1swimminghobits-2bike

2. Gson的使用

2.1 Gson简介

Gson是google解析Json的一个开源框架,它与JsonObject相比,功能更加强大,性能上更加出色,使用上也更加便捷与简单。需要导入gson相关jar包gson.jar。

2.2 Gson生成Json数据

首先最常规的一种生成方式便是new一个Gson对象,再通过含参构造器实例化一个People对象,通过gson.toJson方法将实例化的people对象传入Gson中,生成Json数据。

People people = new People("lucian", 20, true, "1996-08-14", new String[]{"swimming", "bike"}, null);Gson json = new Gson();System.out.println(json.toJson(people));

并且Gson可以通过gsonBuilder创建一个Gson对象,并对该对象设置格式化输出。

People people = new People("lucian", 20, true, "1996-08-14", new String[]{"swimming", "bike"}, null);GsonBuilder gsonBuilder = new GsonBuilder();//格式化输出gsonBuilder.setPrettyPrinting();Gson json = gsonBuilder.create();System.out.println(json.toJson(people));

在实际应用当中,我们可能会有一些个性化需求,例如name属性的属性名需要是大写的,在gson中,我们便可以通过设置FieldNamingStrategy对json对象中属性的名称进行更改,示例如下:

People people = new People("lucian", 20, true, "1996-08-14", new String[]{"swimming", "bike"}, null);GsonBuilder gsonBuilder = new GsonBuilder();gsonBuilder.setFieldNamingStrategy(new FieldNamingStrategy() {    @Override    public String translateName(Field arg0) {        if(arg0.getName().equals("name")) {            return "NAME";        }        return arg0.getName();    }});Gson json = gsonBuilder.create();System.out.println(json.toJson(people));

上述示例中,将属性名为name的属性重新更改了其属性名为NAME。
需要更改属性名还有另外一种更加方便快捷的方法,便是在People类的相应属性上增加注释,将People类中的相应代码修改为如下代码,效果与上述示例相同。

@SerializedName(value = "NAME")private String name;

json中并没有给我们提供注释这一功能,而有时候我们又需要对json的数据进行一个解释说明,用一位老师的话来说,就是使用曲线救国的方法,在json中再增加一个变量description,在其中存入注解。但是很多时候我们并不希望这部分数据直接的显示出来。我们可以通过在相应的属性上加上transient关键字,打印数据时便不会输出这一属性。如下:

//不显示private transient boolean isBoy;

2.3 Gson解析

我们仍然使用之前的test.json文件作为测试数据,解析方法和JSONObject基本相同。获取数组数据时更加方便,可以直接get而不需要新建jsonarray对象。

File file = new File(JSONGet.class.getResource("test.json").getPath()); String content = FileUtils.readFileToString(file);  Gson gson = new GsonBuilder().create();People people = gson.fromJson(content, People.class);System.out.println(people.getName());System.out.println(people.getHobbits()[0]);

2.4 Gson解析——带日期转换

在JSONObject中,日期只能以String类型的方式进行输出,而Date类型的日期格式比较容易为我们所用。所以Gson支持Date类型数据的转化。首先我们需要对People类稍加修改,修改为PeopleWithBirthday(构造方法和get、set方法在此省略)。

public class PeopleWithBirthday {    private String name;    private int age;    private transient boolean isBoy;    private Date birthday;    private String[] hobbits;    private Object content;}

注意属性birthday为Date类型,通过gson构造器设置了json文件中的日期格式,以下代码是对json文件中的日期进行解析并格式化输出。

Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd").create();PeopleWithBirthday people = gson.fromJson(content, PeopleWithBirthday.class);SimpleDateFormat ff = new SimpleDateFormat("yyyy-MM-dd");String tmp = ff.format(people.getBirthday());System.out.println(tmp);

输出结果为:1996-08-14

关于JSON库的总结

功能:映射Java Object和json格式数据
特点:
1.通过Annotation注解来声明;
2.支持自定义属性名字;
3.支持包含或排除属性;
4.支持自定义接口完成解析/生成过程。

1 0