【问题标题】:Bypassing Gson number parser implementation绕过 Gson 数字解析器实现
【发布时间】:2014-08-12 20:26:17
【问题描述】:

我正在使用 Gson 在我的 Android 应用程序中解析 JSON。假设我要解析这个 json:

{
    "foo": 01
}

现在,根据 Json 规范 ECMA-404

一个数字以 10 为底,没有多余的前导零 [...]

表示上面的json无效。不幸的是,Gson 出于某种原因没有实现这一点,并给我foo 作为String "01"。解析时,我无法判断原始值是字符串,还是格式错误的数字。

当我从foo 收到 JsonPrimitive 时,isString 方法返回 true。它应该抛出一个JsonSyntaxException

我已经尝试过 gson 的自定义反序列化,但没有运气。我在网上到处搜索,甚至浏览了 Gson 的项目 open issues,但一无所获。

有没有办法检测这种类型的错误语法?

编辑

这是对我有用的代码:

private class Bar implements Serializable {
    private static final long serialVersionUID = 1L;
    @Expose
    @SerializedName("foo")
    private String foo;
}

public static void main(String[] args) throws Exception {
    String json = "{\"foo\" : 01}";
    Gson gson = new GsonBuilder().create();
    Bar bar = gson.getAdapter(Bar.class).fromJson(json);
}

【问题讨论】:

  • 如果您知道哪些 json 键的值是整数,那么最好将该值作为 int 获取。例如,JsonElement ele = obj.get("foo"); System.out.println(ele.getAsInt());将打印'1'。是的,但一般来说,大多数时候您不希望专门针对某些字段进行这种额外检查。

标签: java android json gson


【解决方案1】:

Gson,默认情况下以宽松模式解析。你可以使用

gson.getAdapter(type).fromJson(json);

以严格模式解析。例如

public static void main(String[] args) throws Exception {
    String json = "{\"value\" : 01}";
    Gson gson = new GsonBuilder().create();
    System.out.println(gson.getAdapter(Value.class).fromJson(json));
}

static class Value {
    Integer value;

    public String toString() {
        return "" + value;
    }
}

抛出

Exception in thread "main" com.google.gson.stream.MalformedJsonException: Use JsonReader.setLenient(true) to accept malformed JSON at line 1 column 12
    at com.google.gson.stream.JsonReader.syntaxError(JsonReader.java:1505)
    at com.google.gson.stream.JsonReader.checkLenient(JsonReader.java:1386)
    at com.google.gson.stream.JsonReader.doPeek(JsonReader.java:589)
    at com.google.gson.stream.JsonReader.peek(JsonReader.java:414)
    at com.google.gson.internal.bind.TypeAdapters$7.read(TypeAdapters.java:234)
    at com.google.gson.internal.bind.TypeAdapters$7.read(TypeAdapters.java:231)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.read(ReflectiveTypeAdapterFactory.java:93)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:172)
    at com.google.gson.TypeAdapter.fromJson(TypeAdapter.java:256)
    at com.google.gson.TypeAdapter.fromJson(TypeAdapter.java:269)
    at com.example.Example.main(Example.java:21)

这是在here讨论。

【讨论】:

  • 您好,谢谢您的回答,但是如果我希望foo 是一个字符串,它不会抛出任何异常。
  • @Luke 在我的示例中foo 是什么?
  • 请在我的回答中查看编辑。在您的示例中,如果 value 是 String 它不会抛出异常
  • @Luke 如果您指的是Integer value 字段,将其更改为String value 也会导致异常。
  • 你是对的。但我仍然无法在我提供的代码中重现这一点:/
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-10-10
  • 1970-01-01
  • 2017-02-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多