JsonObject和Gson的使用

本文详细介绍了JSON数据格式及其在Java中的应用,包括JSON对象的创建、读取及与Java对象的相互转换。同时对比了两种流行的JSON处理库——JSON与Gson的特点与使用方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

JSON(JavaScript Object Notation, JavaScript 对象标记语言) 是一种轻量级的数据交换格式。在 JS 语言中,一切都是对象。因此,任何支持的类型都可以通过 JSON 来表示,例如字符串、数字、对象、数组等。
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:lucian
age: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-1swimming
hobits-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.支持自定义接口完成解析/生成过程。

包含以下java源文件: com.google.gson.DefaultDateTypeAdapter.class com.google.gson.ExclusionStrategy.class com.google.gson.FieldAttributes.class com.google.gson.FieldNamingPolicy.class com.google.gson.FieldNamingStrategy.class com.google.gson.Gson.class com.google.gson.GsonBuilder.class com.google.gson.InstanceCreator.class com.google.gson.JsonArray.class com.google.gson.JsonDeserializationContext.class com.google.gson.JsonDeserializer.class com.google.gson.JsonElement.class com.google.gson.JsonIOException.class com.google.gson.JsonNull.class com.google.gson.JsonObject.class com.google.gson.JsonParseException.class com.google.gson.JsonParser.class com.google.gson.JsonPrimitive.class com.google.gson.JsonSerializationContext.class com.google.gson.JsonSerializer.class com.google.gson.JsonStreamParser.class com.google.gson.JsonSyntaxException.class com.google.gson.LongSerializationPolicy.class com.google.gson.TreeTypeAdapter.class com.google.gson.TypeAdapter.class com.google.gson.TypeAdapterFactory.class com.google.gson.annotations.Expose.class com.google.gson.annotations.SerializedName.class com.google.gson.annotations.Since.class com.google.gson.annotations.Until.class com.google.gson.internal.ConstructorConstructor.class com.google.gson.internal.Excluder.class com.google.gson.internal.JsonReaderInternalAccess.class com.google.gson.internal.LazilyParsedNumber.class com.google.gson.internal.LinkedTreeMap.class com.google.gson.internal.ObjectConstructor.class com.google.gson.internal.Primitives.class com.google.gson.internal.Streams.class com.google.gson.internal.UnsafeAllocator.class com.google.gson.internal.bind.ArrayTypeAdapter.class com.google.gson.internal.bind.CollectionTypeAdapterFactory.class com.google.gson.internal.bind.DateTypeAdapter.class com.google.gson.internal.bind.JsonTreeReader.class com.google.gson.internal.bind.JsonTreeWriter.class com.google.gson.internal.bind.MapTypeAdapterFactory.class com.google.gson.internal.bind.ObjectTypeAdapter.class com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.class com.google.gson.internal.bind.SqlDateTypeAdapter.class com.google.gson.internal.bind.TimeTypeAdapter.class com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.class com.google.gson.internal.bind.TypeAdapters.class com.google.gson.reflect.TypeToken.class com.google.gson.stream.JsonReader.class com.google.gson.stream.JsonScope.class com.google.gson.stream.JsonToken.class com.google.gson.stream.JsonWriter.class com.google.gson.stream.MalformedJsonException.class
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值