android/java中gson的用法

GSON 是 Google 提供的用于在 Java 对象和 JSON 数据之间进行序列化和反序列化的库。

1. 添加依赖

build.gradle 中添加:

gradle 复制代码
dependencies {
    implementation 'com.google.code.gson:gson:2.10.1'
}

2. 基本用法

创建 Gson 实例

java 复制代码
Gson gson = new Gson();

简单对象序列化和反序列化

java 复制代码
// 序列化:对象 → JSON
User user = new User("John", 25, "john@example.com");
String json = gson.toJson(user);
// 结果: {"name":"John","age":25,"email":"john@example.com"}

// 反序列化:JSON → 对象
String jsonString = "{\"name\":\"John\",\"age\":25,\"email\":\"john@example.com\"}";
User user = gson.fromJson(jsonString, User.class);

3. 复杂对象处理

处理集合

java 复制代码
// List 序列化
List<User> users = Arrays.asList(
    new User("Alice", 30, "alice@example.com"),
    new User("Bob", 28, "bob@example.com")
);
String json = gson.toJson(users);

// List 反序列化
String jsonArray = "[{\"name\":\"Alice\",\"age\":30,\"email\":\"alice@example.com\"},{\"name\":\"Bob\",\"age\":28,\"email\":\"bob@example.com\"}]";
User[] userArray = gson.fromJson(jsonArray, User[].class);
List<User> userList = gson.fromJson(jsonArray, new TypeToken<List<User>>(){}.getType());

处理 Map

java 复制代码
// Map 序列化
Map<String, Object> data = new HashMap<>();
data.put("name", "John");
data.put("scores", Arrays.asList(90, 85, 92));
String json = gson.toJson(data);

// Map 反序列化
String jsonMap = "{\"math\":90,\"english\":85,\"science\":92}";
Map<String, Integer> scores = gson.fromJson(jsonMap, new TypeToken<Map<String, Integer>>(){}.getType());

4. 自定义序列化/反序列化

使用 @SerializedName 注解

java 复制代码
public class User {
    @SerializedName("user_name")
    private String name;
    
    @SerializedName("user_age")
    private int age;
    
    private String email;
    
    // 构造方法、getter、setter
}

自定义序列化器

java 复制代码
public class DateSerializer implements JsonSerializer<Date> {
    private static final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    
    @Override
    public JsonElement serialize(Date date, Type type, JsonSerializationContext context) {
        return new JsonPrimitive(dateFormat.format(date));
    }
}

public class DateDeserializer implements JsonDeserializer<Date> {
    @Override
    public Date deserialize(JsonElement json, Type type, JsonDeserializationContext context) throws JsonParseException {
        try {
            return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(json.getAsString());
        } catch (ParseException e) {
            throw new JsonParseException(e);
        }
    }
}

使用自定义序列化器

java 复制代码
Gson gson = new GsonBuilder()
    .registerTypeAdapter(Date.class, new DateSerializer())
    .registerTypeAdapter(Date.class, new DateDeserializer())
    .create();

5. GsonBuilder 配置

java 复制代码
Gson gson = new GsonBuilder()
    .setPrettyPrinting()                    // 美化输出
    .serializeNulls()                       // 序列化 null 值
    .setDateFormat("yyyy-MM-dd")           // 设置日期格式
    .disableHtmlEscaping()                 // 禁用 HTML 转义
    .excludeFieldsWithoutExposeAnnotation() // 只序列化有 @Expose 注解的字段
    .create();

@Expose 注解使用

java 复制代码
public class User {
    @Expose
    private String name;
    
    @Expose(serialize = false, deserialize = true) // 只反序列化,不序列化
    private String password;
    
    private String secret; // 不会被序列化或反序列化
}

6. 实际应用示例

网络请求数据解析

java 复制代码
public class ApiResponse {
    private int code;
    private String message;
    private User data;
    
    // getter, setter
}

// 解析网络响应
String responseJson = "{\"code\":200,\"message\":\"success\",\"data\":{\"name\":\"John\",\"age\":25}}";
ApiResponse apiResponse = gson.fromJson(responseJson, ApiResponse.class);

配置数据存储

java 复制代码
// 保存配置到 SharedPreferences
public void saveConfig(Context context, Config config) {
    SharedPreferences prefs = context.getSharedPreferences("config", Context.MODE_PRIVATE);
    String json = gson.toJson(config);
    prefs.edit().putString("config", json).apply();
}

// 从 SharedPreferences 读取配置
public Config loadConfig(Context context) {
    SharedPreferences prefs = context.getSharedPreferences("config", Context.MODE_PRIVATE);
    String json = prefs.getString("config", "");
    if (!json.isEmpty()) {
        return gson.fromJson(json, Config.class);
    }
    return null;
}

7. 处理特殊场景

忽略字段

java 复制代码
public class User {
    private String name;
    private int age;
    
    @Exclude
    private transient String temporaryData; // 使用 transient 关键字
    
    // 使用 @Exclude 注解(需要配合 excludeFieldsWithoutExposeAnnotation)
}

处理多态类型

java 复制代码
public abstract class Animal {
    String type;
}

public class Dog extends Animal {
    String breed;
}

public class Cat extends Animal {
    boolean likesCatnip;
}

// 使用 RuntimeTypeAdapterFactory
RuntimeTypeAdapterFactory<Animal> adapterFactory = RuntimeTypeAdapterFactory
    .of(Animal.class, "type")
    .registerSubtype(Dog.class, "dog")
    .registerSubtype(Cat.class, "cat");

Gson gson = new GsonBuilder()
    .registerTypeAdapterFactory(adapterFactory)
    .create();

8. 最佳实践

  1. 重用 Gson 实例:Gson 是线程安全的,建议重用实例
  2. 处理异常:始终处理 JsonSyntaxException
  3. 性能考虑:对于大量数据,考虑使用流式 API
  4. 安全考虑:不要反序列化不可信的 JSON 数据
java 复制代码
try {
    User user = gson.fromJson(jsonString, User.class);
} catch (JsonSyntaxException e) {
    // 处理 JSON 语法错误
    e.printStackTrace();
}
相关推荐
摇滚侠2 小时前
Spring Boot3零基础教程,为什么有Reactive-Stream 规范,响应式编程,笔记101
java·spring boot·笔记
用户0273851840263 小时前
【Android】活动的正/异常生命周期和启动模式、标志位详解
android
周杰伦fans3 小时前
C# 中 Entity Framework (EF) 和 EF Core 里的 `AsNoTracking` 方法
开发语言·c#
小灰灰搞电子3 小时前
Rust Slint实现控件尺寸的扩展与收缩源码分享
开发语言·后端·rust
☆cwlulu3 小时前
git分支管理详解
开发语言·git·青少年编程
天天摸鱼的java工程师3 小时前
八年 Java 开发手敲:SpringBoot+SpringSecurity+JWT 实战,前后分离权限注解落地就能跑
java·后端
冰淇淋@3 小时前
idea启动项目报错java: OutOfMemoryError: insufficient memory
java·ide·intellij-idea
techzhi3 小时前
this view is read-only (IntelliJ IDEA)
java·ide·intellij-idea
编程学委3 小时前
Idea(2023版)使用Svn
java·svn·intellij-idea