【Android】JSON的具体使用方法之数据格式,数据解析,GSON的使用
文章目录
- 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 {@Overrideprotected 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对象序列化为JSONString 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 {@Overrideprotected 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 DoeLog.d("MainActivity", "User Age: " + user.getAge()); // 输出: 30Log.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 {@Overrideprotected 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对象序列化为JSONString 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 DoeLog.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