【Android】JSON的具体使用方法之数据格式,数据解析,GSON的使用

JSON

JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,易于人类阅读和编写,同时也易于机器解析和生成。

数据格式

基本结构

  1. 对象:由花括号{}包围,包含键值对。键是字符串,值可以是字符串、数字、对象、数组、布尔值或null。

    {
        "name": "John",
        "age": 30,
        "married": true,
        "children": ["Anna", "Billy"],
        "address": {
            "street": "123 Main St",
            "city": "New York"
        }
    }
    
  2. 数组:由方括号[]包围,包含一个有序的值列表。

    [
        "apple",
        "banana",
        "cherry"
    ]
    
  3. :可以是字符串、数字、对象、数组、布尔值或null。

数据类型

  • 字符串:必须用双引号包围。

    "name": "John"
    
  • 数字:可以是整数或浮点数,不需要引号。

    "age": 30,
    "height": 1.75
    
  • 对象:一个无序的键值对集合,键必须是字符串,值可以是任何合法的JSON数据。

    "address": {
        "street": "123 Main St",
        "city": "New York"
    }
    
  • 数组:一个有序的值列表,值可以是任何合法的JSON数据。

    "children": ["Anna", "Billy"]
    
  • 布尔值truefalse

    "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对象,并提供了多种方法来获取其键对应的值。

获取值的方法

  1. opt(String key)

    • 根据键获取值,如果键不存在,则返回null
    • 推荐使用,因为不会抛出异常。
    JSONObject jsonObject = new JSONObject("{\"name\":\"John\", \"age\":30}");
    Object value = jsonObject.opt("name"); // 返回 "John"
    Object missingValue = jsonObject.opt("nonexistent"); // 返回 null
    
  2. get(String key)

    • 根据键获取值,如果键不存在,则抛出JSONException
    JSONObject jsonObject = new JSONObject("{\"name\":\"John\", \"age\":30}");
    Object value = jsonObject.get("name"); // 返回 "John"
    Object missingValue = jsonObject.get("nonexistent"); // 抛出 JSONException
    

根据值的类型获取

  1. optString(String key)

    • 根据键获取字符串值,如果键不存在或值不是字符串,则返回空字符串或null。
    String name = jsonObject.optString("name"); // 返回 "John"
    String missingName = jsonObject.optString("nonexistent"); // 返回 ""
    
  2. optInt(String key)

    • 根据键获取整数值,如果键不存在或值不是整数,则返回0或指定的默认值。
    int age = jsonObject.optInt("age"); // 返回 30
    int missingAge = jsonObject.optInt("nonexistent", -1); // 返回 -1
    
  3. optBoolean(String key)

    • 根据键获取布尔值,如果键不存在或值不是布尔值,则返回false或指定的默认值。
    boolean isMarried = jsonObject.optBoolean("married"); // 返回 true 或 false
    boolean missingMarried = jsonObject.optBoolean("nonexistent", true); // 返回 true
    
  4. optJSONObject(String key)

    • 根据键获取JSONObject对象,如果键不存在或值不是JSONObject,则返回null。
    JSONObject address = jsonObject.optJSONObject("address"); // 返回一个 JSONObject 对象或 null
    
  5. 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对象中的字段名称之间的映射。

  1. 假设我们有一个JSON字符串:
{
    "full_name": "John Doe",
    "user_age": 30,
    "is_married": true
}
  1. 我们可以创建一个对应的数据类,并使用@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

  • 15
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值