gson自定义TypeAdapter

本文介绍了如何在后台接口返回JSON数据中,同一键值可能对应多种类型的情况下,通过自定义Gson的TypeAdapter进行有效解析和转换。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、背景

后台接口返回的json数据同一个key的value分多种类型

比如

//类型一
{
	"cover":"http://xxxx/xxx/xx"
}
//类型二
{
	"cover":{
		"blurred":"http://xxx/xxx",
		"detail":"http://xxx/xxx",
		"feed":"http://xxx/xxx",
		"homepage":"http://xxx/xxx"
	}
}

2、实现

/**
 * Description: Gson Adapter for [Cover];返回的json数据中key为cover的值有两种类型,需要自定义解析
 * Author : pxq
 * Date : 2020/8/14 11:39 PM
 */
class CoverTypeAdapter : TypeAdapter<Cover>() {
    override fun write(writer: JsonWriter?, value: Cover?) {
        writer ?: return
        if (value == null) {
            writer.nullValue()
        } else {
            writer.value(value.blurred)
            writer.value(value.detail)
            writer.value(value.feed)
            writer.value(value.homepage)
        }
    }

    override fun read(reader: JsonReader?): Cover {
        reader ?: return Cover("", "", "", "")
        var token = reader.peek()
        // 是cover 字符串
        if (token == JsonToken.STRING) {
            val coverUrl = reader.nextString()
            return Cover("", coverUrl, "", coverUrl)
        } else {  // 是cover 对象
            var blurred = ""
            var detail = ""
            var feed = ""
            var homepage = ""
            // 开始解析Cover对象
            reader.beginObject()
            while (reader.peek().also {
                    token = it
                } != JsonToken.END_OBJECT) {
                // 忽略NULL
                if (token == JsonToken.NULL) {
                    // 跳过NULL
                    reader.nextNull()
                    continue
                }
                // 读取json name
                reader.nextName()?.apply {
                    var value = ""
                    // 只读取String类型,忽略其他,比如NULL
                    if (reader.peek() == JsonToken.STRING) {
                        value = reader.nextString()
                    }
                    // 赋值
                    when (this) {
                        "blurred" -> blurred = value
                        "detail" -> detail = value
                        "feed" -> feed = value
                        "homepage" -> homepage = value
                        else -> Unit
                    }
                }
            }
            reader.endObject()
            return Cover(blurred, detail, feed, homepage)
        }
    }

}


// 使用
data class Data(
    ...
    @JsonAdapter(CoverTypeAdapter::class)
    val cover: Cover
}
`Gson` 是 Google 提供的一个用于 Java 对象序列化和反序列化的库。当你需要自定义类型转换时,可以使用 `TypeAdapter`。对于 `BigDecimal` 类型,你可以创建一个专门处理 `BigDecimal` 的适配器。 首先,你需要创建一个实现了 `TypeAdapter<BigDecimal>` 接口的类,通常这个类会有一个构造函数接收一个 `JsonDeserializer<BigDecimal>` 和一个 `JsonSerializer<BigDecimal>` 来分别解析 JSON 字符串为 `BigDecimal` 和将 `BigDecimal` 序列化为 JSON 字符串: ```java import com.google.gson.TypeAdapter; import com.google.gson.stream.JsonReader; import com.google.gson.stream.JsonWriter; import java.io.IOException; import java.math.BigDecimal; public class BigDecimalTypeAdapter extends TypeAdapter<BigDecimal> { private final JsonSerializer<BigDecimal> serializer; private final JsonDeserializer<BigDecimal> deserializer; public BigDecimalTypeAdapter(JsonSerializer<BigDecimal> serializer, JsonDeserializer<BigDecimal> deserializer) { this.serializer = serializer; this.deserializer = deserializer; } @Override public void write(JsonWriter out, BigDecimal value) throws IOException { serializer.serialize(value, out); } @Override public BigDecimal read(JsonReader in) throws IOException { return deserializer.deserialize(in); } } ``` 然后,在使用 `Gson` 进行序列化或反序列化时,你可以注册这个自定义的 `TypeAdapter`: ```java import com.google.gson.GsonBuilder; import com.google.gson.TypeAdapterFactory; public static Gson createCustomizedGson() { TypeAdapterFactory factory = new TypeAdapterFactory() { @Override public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) { if (type.getRawType().equals(BigDecimal.class)) { return (TypeAdapter<T>) new BigDecimalTypeAdapter(gson.getAdapter(BigDecimal.class), new BigDecimalJsonDeserializer()); } return null; // 返回默认的 TypeAdapter,如果类型不是 BigDecimal } }; Gson gson = new GsonBuilder() .registerTypeAdapterFactory(factory) .create(); return gson; } // 使用自定义的 BigDecimalTypeAdapter BigDecimal bd = new BigDecimal("123.45"); String json = createCustomizedGson().toJson(bd); // 序列化为 JSON BigDecimal bdFromJson = createCustomizedGson().fromJson(json, BigDecimal.class); // 反序列化从 JSON 到 BigDecimal ``` 这里我们假设你已经有一个 `BigDecimalJsonDeserializer` 类用于解析 JSON 字符串到 `BigDecimal`。记得在实际项目中添加这个类并实现相应的逻辑。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值