文章目录
- JSON
- 数据格式
- 基本结构
- 数据类型
- 数据解析
- 获取值的方法
- 根据值的类型获取
- GSON
- 1. 添加Gson依赖
- 2. 创建数据类
- 3. 使用Gson
- 序列化
- 反序列化
- 4. 其他问题
- 处理嵌套对象
- 字段名不一致
JSON
JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,易于人类阅读和编写,同时也易于机器解析和生成。
数据格式
基本结构
-
对象:由花括号
{}
包围,包含键值对。键是字符串,值可以是字符串、数字、对象、数组、布尔值或null。{ "name": "John", "age": 30, "married": true, "children": ["Anna", "Billy"], "address": { "street": "123 Main St", "city": "New York" } }
-
数组:由方括号
[]
包围,包含一个有序的值列表。[ "apple", "banana", "cherry" ]
-
值:可以是字符串、数字、对象、数组、布尔值或null。
数据类型
-
字符串:必须用双引号包围。
"name": "John"
-
数字:可以是整数或浮点数,不需要引号。
"age": 30, "height": 1.75
-
对象:一个无序的键值对集合,键必须是字符串,值可以是任何合法的JSON数据。
"address": { "street": "123 Main St", "city": "New York" }
-
数组:一个有序的值列表,值可以是任何合法的JSON数据。
"children": ["Anna", "Billy"]
-
布尔值:
true
或false
。"married": true
-
null:表示空值。
"middle_name": null
示例:
{
"name": "John Doe",
"age": 30,
"married": true,
"children": [
{
"name": "Anna",
"age": 10
},
{
"name": "Billy",
"age": 5
}
],
"address": {
"street": "123 Main St",
"city": "New York",
"zip": "10001"
},
"phone_numbers": ["123-456-7890", "987-654-3210"],
"email": "john.doe@example.com",
"website": null
}
数据解析
在Java中,JSONObject
类用于表示一个JSON对象,并提供了多种方法来获取其键对应的值。
获取值的方法
-
opt(String key):
- 根据键获取值,如果键不存在,则返回
null
。 - 推荐使用,因为不会抛出异常。
JSONObject jsonObject = new JSONObject("{\"name\":\"John\", \"age\":30}"); Object value = jsonObject.opt("name"); // 返回 "John" Object missingValue = jsonObject.opt("nonexistent"); // 返回 null
- 根据键获取值,如果键不存在,则返回
-
get(String key):
- 根据键获取值,如果键不存在,则抛出
JSONException
。
JSONObject jsonObject = new JSONObject("{\"name\":\"John\", \"age\":30}"); Object value = jsonObject.get("name"); // 返回 "John" Object missingValue = jsonObject.get("nonexistent"); // 抛出 JSONException
- 根据键获取值,如果键不存在,则抛出
根据值的类型获取
-
optString(String key):
- 根据键获取字符串值,如果键不存在或值不是字符串,则返回空字符串或null。
String name = jsonObject.optString("name"); // 返回 "John" String missingName = jsonObject.optString("nonexistent"); // 返回 ""
-
optInt(String key):
- 根据键获取整数值,如果键不存在或值不是整数,则返回0或指定的默认值。
int age = jsonObject.optInt("age"); // 返回 30 int missingAge = jsonObject.optInt("nonexistent", -1); // 返回 -1
-
optBoolean(String key):
- 根据键获取布尔值,如果键不存在或值不是布尔值,则返回false或指定的默认值。
boolean isMarried = jsonObject.optBoolean("married"); // 返回 true 或 false boolean missingMarried = jsonObject.optBoolean("nonexistent", true); // 返回 true
-
optJSONObject(String key):
- 根据键获取
JSONObject
对象,如果键不存在或值不是JSONObject
,则返回null。
JSONObject address = jsonObject.optJSONObject("address"); // 返回一个 JSONObject 对象或 null
- 根据键获取
-
optJSONArray(String key):
- 根据键获取
JSONArray
对象,如果键不存在或值不是JSONArray
,则返回null。
JSONArray children = jsonObject.optJSONArray("children"); // 返回一个 JSONArray 对象或 null
- 根据键获取
GSON
1. 添加Gson依赖
在build.gradle
文件中添加Gson依赖:
dependencies {
implementation 'com.google.code.gson:gson:2.8.8'
}
2. 创建数据类
假设我们有一个代表用户的JSON数据,我们首先需要创建一个对应的数据类:
public class User {
private String name;
private int age;
private boolean isMarried;
//...
}
3. 使用Gson
在你的Activity或Fragment中使用Gson进行JSON序列化和反序列化。
序列化
对象转JSON
String userJson = gson.toJson(user);
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 创建User对象
User user = new User("John Doe", 30, true);
// 创建Gson对象
Gson gson = new Gson();
// 将User对象序列化为JSON
String userJson = gson.toJson(user);
Log.d("MainActivity", "User JSON: " + userJson); // 输出: {"name":"John Doe","age":30,"isMarried":true}
}
}
反序列化
JSON转对象
Gson gson = new Gson();
User user = gson.fromJson(userJson, User.class);
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// JSON字符串
String userJson = "{\"name\":\"John Doe\",\"age\":30,\"isMarried\":true}";
// 创建Gson对象
Gson gson = new Gson();
// 将JSON字符串反序列化为User对象
User user = gson.fromJson(userJson, User.class);
Log.d("MainActivity", "User Name: " + user.getName()); // 输出: John Doe
Log.d("MainActivity", "User Age: " + user.getAge()); // 输出: 30
Log.d("MainActivity", "User Married: " + user.isMarried()); // 输出: true
}
}
4. 其他问题
处理嵌套对象
创建相应的数据类,并使用Gson进行处理。
public class Address {
private String street;
private String city;
//...
}
public class User {
private String name;
private int age;
private boolean isMarried;
private Address address;
//...
}
然后在Activity中使用Gson进行序列化和反序列化:
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 创建嵌套的User对象
Address address = new Address("123 Main St", "New York");
User user = new User("John Doe", 30, true, address);
// 创建Gson对象
Gson gson = new Gson();
// 将User对象序列化为JSON
String userJson = gson.toJson(user);
Log.d("MainActivity", "User JSON: " + userJson); // 输出嵌套的JSON字符串
// 将嵌套的JSON字符串反序列化为User对象
User userFromJson = gson.fromJson(userJson, User.class);
Log.d("MainActivity", "User Name: " + userFromJson.getName()); // 输出: John Doe
Log.d("MainActivity", "User Address: " + userFromJson.getAddress().getStreet()); // 输出: 123 Main St
}
}
字段名不一致
在使用Gson进行JSON序列化和反序列化时,字段名不一致的问题可以通过@SerializedName
注解来解决。@SerializedName
注解允许你指定JSON中的字段名称与Java对象中的字段名称之间的映射。
- 假设我们有一个JSON字符串:
{
"full_name": "John Doe",
"user_age": 30,
"is_married": true
}
- 我们可以创建一个对应的数据类,并使用
@SerializedName
注解来处理字段名不一致的问题:
public class User {
@SerializedName("full_name")
private String name;
@SerializedName("user_age")
private int age;
@SerializedName("is_married")
private boolean isMarried;
//...
}
感谢您的阅读
如有错误烦请指正
参考:
1. Android网络请求之JSON数据解析_哔哩哔哩_bilibili