文章目录
- 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