如何让Gson严格反序列化数字类型
如何让Gson严格反序列化数字类型
嘿,我之前也被Gson这个“贴心过头”的自动转换坑过!默认情况下它会悄悄把字符串形式的数字转成Int类型,完全不符合咱们要的严格校验需求。别担心,咱们可以通过自定义TypeAdapter来解决这个问题,实现当JSON字段是字符串但要反序列化成Int时直接抛出异常的效果。
步骤1:自定义严格的Int类型适配器
咱们需要写一个TypeAdapter,强制要求JSON中的值必须是数字类型,拒绝字符串形式的数字:
import com.google.gson.TypeAdapter import com.google.gson.stream.JsonReader import com.google.gson.stream.JsonToken import com.google.gson.stream.JsonWriter import com.google.gson.JsonSyntaxException class IntStrictTypeAdapter : TypeAdapter<Int>() { override fun write(out: JsonWriter, value: Int?) { out.value(value) } override fun read(`in`: JsonReader): Int { // 检查当前JSON token是不是数字类型 if (`in`.peek() != JsonToken.NUMBER) { throw JsonSyntaxException("Expected NUMBER but was ${`in`.peek()} at path ${`in`.path}") } return `in`.nextInt() } }
步骤2:注册适配器到Gson实例
接下来,咱们用GsonBuilder把这个自定义适配器注册进去,生成严格模式的Gson对象:
import com.google.gson.Gson import com.google.gson.GsonBuilder import com.google.gson.reflect.TypeToken fun main() { // 定义要反序列化的类型(比如Map<String, Int>) val intMapType = object : TypeToken<Map<String, Int>>() {}.type // 创建严格模式的Gson实例 val strictGson = GsonBuilder() .registerTypeAdapter(Int::class.java, IntStrictTypeAdapter()) .create() // 测试用例1:JSON值是字符串"123",应该抛出异常 val str1 = """{"key":"123"}""" try { strictGson.fromJson(str1, intMapType) } catch (e: Exception) { println("符合预期,抛出异常:${e.message}") } // 测试用例2:JSON值是数字123,正常反序列化 val str2 = """{"key":123}""" val result = strictGson.fromJson(str2, intMapType) println("正常解析结果:$result") }
为什么这样有效?
默认的Gson Int适配器会尝试做“宽松”转换:如果遇到字符串,它会尝试把字符串转成数字。而咱们自定义的适配器直接校验JSON的Token类型,只有当它是JsonToken.NUMBER时才会解析,否则直接抛出JsonSyntaxException,完美实现了严格校验的需求。
如果需要对其他数字类型(比如Long、Float)做同样的严格校验,只需要照着上面的模板写对应的TypeAdapter,然后注册到GsonBuilder里就可以啦!
内容来源于stack exchange
相关产品推荐
相关产品推荐

