Gson解析器接受toString表示而不是Json语法

bqucvtff  于 2023-10-18  发布在  其他
关注(0)|答案(2)|浏览(120)

在调试一段将字符串转换为对象的代码时,我意识到JSON解析使用的是toString表示,而不是对象的JSON表示。
Pojo:

import lombok.Builder;
import lombok.Data;

@Data
@Builder
public class Pojo {

    int a;
    String b;
}

解析逻辑:

Gson gsonInstance =
        new GsonBuilder()
                .setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES)
                .setDateFormat("yyyy-MM-dd")
                .create();
String json2 = "{a=5, b=field}";
Pojo obj = gsonInstance.fromJson(json2, Pojo.class);

System.out.println(obj);

当我向Pojo添加包含“:“的字段时,这开始被打破。就像约会一样。
围绕这两个问题:1)Gson是如何支持这一点的?我找不到任何医生同样的2)如何处理我前面提到的与toString实现有关的日期问题?我试着在Java中转义字符串,但没有帮助。

uqzxnwby

uqzxnwby1#

这是Gson的一个特性,它实际上是有文档记录的,但文档有点隐藏。参考:Gson.java。JSON标准化的最终调用是
public <T> T fromJson(JsonReader reader, Type typeOfT) throws JsonIOException, JsonSyntaxException
在代码的主体中,请参考:

reader.setLenient(true);

现在参考JsonReader.java

public final void setLenient(boolean lenient)

方法的javadoc声明如下:
/* 将此解析器配置为接受自由的解析器。默认情况下,* 这个解析器是严格的,只接受RFC 4627指定的JSON。将 * parser设置为lenient会导致它忽略以下语法错误:- -

  • 以非执行 * 前缀")]}'\n"开头的流。*
  • 包含多个顶级值的流。使用严格解析,* 每个流必须包含一个顶级值。*
  • 任何类型的顶级值。使用严格解析,顶级 * 值必须是对象或数组。*
  • 数字可以是{@link Double#isNaN()NaNs}或{@link * Double#isInfinite()infinities}。*
  • 以{@code //}或{@code #}和 * 开头并以换行符结尾的行结束注解。*
  • 以{@code /*}开头,以 * {@code }{@code /}结尾的C风格注解。此类注解不可嵌套。
  • 不带引号或{@code 'single quoted'}的名称。*
  • 未加引号或{@code 'single quoted'}的字符串。*
  • 数组元素由{@code ;}而不是{@code,}。*
  • 不必要的数组分隔符。这些被解释为null * 是省略的值。*
  • 名称和值由{@code =}或{@code =>}而不是 * {@code:}分隔。*
  • 名称/值对由{@code ;}而不是{@code,}。*
  • /

以上就是Gson解析你的字符串并将其解析的原因。
如果你的名字/值(未加引号)有任何“:”,上面的代码将不起作用,原因是Gson将(在你的情况下)解释为name=[value或anotherName???]:value(Gson没有那么宽松)。
使用正确有效的JSON并反序列化。

hzbexzde

hzbexzde2#

您需要一个启用了复杂Map键序列化的Gson。

new Gson().newBuilder().enableComplexMapKeySerialization().create();

https://www.javadoc.io/doc/com.google.code.gson/gson/latest/com.google.gson/com/google/gson/GsonBuilder.html#enableComplexMapKeySerialization()

相关问题