java - Gson Parser 接受 toString 表示而不是 Json 语法
问题描述
在调试一段将字符串反序列化为对象的代码时,我意识到那里的 JSON 解析正在使用 toString 表示而不是对象的 json 表示。
波乔:
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 转义字符串,但没有帮助。
解决方案
这是 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。将 * 解析器设置为 lenient 会导致它忽略以下语法错误:* *
*
*/- 以非执行 * 前缀开头的流,
")]}'\n"
. *- 包含多个顶级值的流。通过严格的解析,* 每个流必须只包含一个顶级值。*
- 任何类型的顶级值。使用严格解析,顶级 * 值必须是对象或数组。*
- 数字可能是 {@link Double#isNaN() NaNs} 或 {@link * Double#isInfinite() infinities}。*
- 以 {@code //} 或 {@code #} 开头和 * 以换行符结尾的行尾注释。*
- C 风格的注释以 {@code /*} 开头并以 * {@code *}{@code /} 结尾。此类注释可能不会嵌套。*
- 未加引号或 {@code 'singlequoted'} 的名称。*
- 未加引号或 {@code 'singlequoted'} 的字符串。*
- 由 {@code ;} 而不是 {@code ,} 分隔的数组元素。*
- 不必要的数组分隔符。这些被解释为好像 null * 是省略的值。*
- 名称和值由 {@code =} 或 {@code =>} 分隔,而不是 * {@code :}。*
- 由 {@code ;} 而不是 {@code ,} 分隔的名称/值对。*
以上就是 Gson 解析你的字符串并反序列化的原因。
如果您的名称/值(未加引号)有任何“:”,则上述内容将不起作用,因为 Gson 将(在您的情况下)解释为 name=[value 或 anotherName???]:value (Gson 不是那么宽松)。
使用正确的有效 JSON 并反序列化。
推荐阅读
- vue.js - 如何对计算对象中的数组使用“v-for”
- unity3d - 如何从 Branch SDK 读取 Facebook 应用程序链接
- mysql - 无法为 MySQL root 用户设置密码
- javascript - 我可以将选定单选按钮中的特定图像添加到 Javascript 中的值吗
- java - Spring Boot 2.1.4 ControllerAdvice 不起作用
- ios - 消耗品与非消耗品
- fiware - 在 Wirecloud 混搭中创建 NGSI 源订阅
- kubernetes - Kubernetes CRI 的最新 protobuf API 在哪里?
- javascript - 如何使用引导程序在单击同一页面上的另一个按钮时保持选中按钮?
- bash - 通过根据开始和结束匹配将内容分成几行,使用 awk 或 sed 解析 json 文件