在 Gson 中,如何在反序列化期间检测类型不匹配?

In Gson, how to detect type mismatch during deserialization?

gson.fromJson(json, type) 将 json 转换为 class 对象。假设我有 json 看起来像

的数据
{
  "randomTiles": "true",
  "randomNumbers": "false",
  "randomPorts": "false",
  "name": "test"
}

和 class json 反序列化为

public class CreateGameRequest {
    public String name;
    public boolean randomTiles;
    public boolean randomNumbers;
    public boolean randomPorts;
}

当我打电话给

gson.fromJson(json, type)

然后它应该解析 json 数据并将其转换为 CreateGameRequest 对象。现在的问题是假设数据类型不正确,所以它看起来像

{
  "randomTiles": "asdasd",
  "randomNumbers": "zxczxc",
  "randomPorts": "asdzxc",
  "name": "test"
}

现在调用 json.fromJson() 或者换句话说当反序列化到上面的 class 对象时,Gson 默默地认为 "asdasd" 是 "false" 而不会抛出类型异常不匹配。我注意到 .fromJson() 抛出 JsonSyntaxException 但仅当我在 json 对象的 boolean 字段中有一个不带引号的数字时才会抛出该异常,但似乎没有检测到json 对象的 boolean 字段中的 "true" "false" 以外的文本..你知道我如何检测 json 对象是否有字符串以外的字符串"true" "false" 在 boolean 字段中?感谢您的帮助!

Gson 尽最大努力将 JSON 值转换为 boolean 值,将大多数所有内容都视为 false-y。我相信它使用 Boolean.valueOf(String) 进行转换。

您可以通过注册自己的反序列化器来更加严格

class JsonBooleanDeserializer implements JsonDeserializer<Boolean> {
    @Override
    public Boolean deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
        try {
            String value = json.getAsJsonPrimitive().getAsString();
            if ("true".equals(value) || "false".equals(value)) {
                return Boolean.valueOf(value);
            } else {
                throw new JsonParseException("Cannot parse json '" + json.toString() + "' to boolean value");
            }
        } catch (ClassCastException e) {
            throw new JsonParseException("Cannot parse json '" + json.toString() + "' to boolean value", e);
        }
    }
}

Gson gson = new GsonBuilder()
    .registerTypeAdapter(Boolean.class, deserializer)
    .registerTypeAdapter(boolean.class, deserializer)
    .create();