Moshi 判断 JSON 是数组还是单个对象

2023-11-21

有没有办法设置 Moshiadapter自动创建一个Object or List<Object>基于 JSON 响应?目前,我可以明确地做到这一点。例如,我可以收到以下回复:

{
    "userId": "1",
    "id": "2",
    "body": "body...",
    "title": "title..."
}

Or

[
  {
    "userId": "1",
    "id": "2",
    "body": "body...",
    "title": "title..."
  }
]

我想创建Object or List<Object>无需明确指定使用哪一个。


您可以使用 JsonQualifier 来概括这一点。 从你的例子来看,你可以像这样使用它

final class Foo {
  @SingleToArray final List<User> users;
}

这是带有测试的代码,可以更彻底地演示。

@Retention(RUNTIME)
@JsonQualifier public @interface SingleToArray {
  final class Adapter extends JsonAdapter<List<Object>> {
    final JsonAdapter<List<Object>> delegateAdapter;
    final JsonAdapter<Object> elementAdapter;

    public static final Factory FACTORY = new Factory() {
      @Nullable @Override
      public JsonAdapter<?> create(Type type, Set<? extends Annotation> annotations,
          Moshi moshi) {
        Set<? extends Annotation> delegateAnnotations =
            Types.nextAnnotations(annotations, SingleToArray.class);
        if (delegateAnnotations == null) {
          return null;
        }
        if (Types.getRawType(type) != List.class) {
          throw new IllegalArgumentException(
              "Only lists may be annotated with @SingleToArray. Found: " + type);
        }
        Type elementType = Types.collectionElementType(type, List.class);
        JsonAdapter<List<Object>> delegateAdapter = moshi.adapter(type, delegateAnnotations);
        JsonAdapter<Object> elementAdapter = moshi.adapter(elementType);
        return new Adapter(delegateAdapter, elementAdapter);
      }
    };

    Adapter(JsonAdapter<List<Object>> delegateAdapter, JsonAdapter<Object> elementAdapter) {
      this.delegateAdapter = delegateAdapter;
      this.elementAdapter = elementAdapter;
    }

    @Nullable @Override public List<Object> fromJson(JsonReader reader) throws IOException {
      if (reader.peek() != JsonReader.Token.BEGIN_ARRAY) {
        return Collections.singletonList(elementAdapter.fromJson(reader));
      }
      return delegateAdapter.fromJson(reader);
    }

    @Override public void toJson(JsonWriter writer, @Nullable List<Object> value)
        throws IOException {
      if (value.size() == 1) {
        elementAdapter.toJson(writer, value.get(0));
      } else {
        delegateAdapter.toJson(writer, value);
      }
    }
  }
}

@Test public void singleToArray() throws Exception {
  Moshi moshi = new Moshi.Builder().add(SingleToArray.Adapter.FACTORY).build();
  JsonAdapter<List<String>> adapter =
      moshi.adapter(Types.newParameterizedType(List.class, String.class), SingleToArray.class);
  assertThat(adapter.fromJson("[\"Tom\",\"Huck\"]")).isEqualTo(Arrays.asList("Tom", "Huck"));
  assertThat(adapter.toJson(Arrays.asList("Tom", "Huck"))).isEqualTo("[\"Tom\",\"Huck\"]");
  assertThat(adapter.fromJson("\"Jim\"")).isEqualTo(Collections.singletonList("Jim"));
  assertThat(adapter.toJson(Collections.singletonList("Jim"))).isEqualTo("\"Jim\"");
  assertThat(adapter.fromJson("[]")).isEqualTo(Collections.emptyList());
  assertThat(adapter.toJson(Collections.<String>emptyList())).isEqualTo("[]");
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Moshi 判断 JSON 是数组还是单个对象 的相关文章

随机推荐

  • Eclipse 中的 Python 文档

    有没有办法将标准Python文档集成到Eclipse中 因此 可以在 API 函数上按 F1 并在 Eclipse 的帮助视图中获取其描述 我使用 PyDev Thanks 我也遇到了同样的问题 所以我为此目的制作了一个 Eclipse 插
  • 如何保存并检查文件是否存在于作用域存储中?

    到目前为止 我检查文件是否存在 如果不存在 则将其保存到 Environment getExternalStoragePublicDirectory Environment DIRECTORY PICTURES 中的设备 但 Android
  • 在没有 DataBind 的情况下向 GridView 添加新行

    我有一个 GridView 它允许随时编辑每一列 每一行中的值 用户输入所有更改 单击 保存 一次 所有更改均已提交 用户还必须能够单击 新建 按钮 在 GridView 中显示一个新行 是的 它必须显示在实际的 GridView 中 输入
  • 当 C++ 标准提供将名称引入全局命名空间的 C 标头时,这是否包括重载?

    即将推出的 C 0x 标准的最终委员会草案表示 每个 C 标头 每个标头都有一个 name h 形式的名称 其行为就像 标准中的每个名称 库名称空间由相应的 cname 标头位于 全局命名空间范围 这是 未指定这些名称是否是 首先声明或定义
  • MYSQL根据列数据和表名连接表

    我想知道这是否可能 我想根据表1的数据连接2个表 示例表 1 具有列 food 其数据为 hotdog 我有一张桌子叫热狗 是否可以进行 JOIN 之类的操作 SELECT FROM table1 t join t food on id f
  • DDD:聚合根

    我需要帮助来找到我的聚合根和边界 我有 3 个实体 计划 计划角色和计划培训 每个计划可以包含许多 PlannedRoles 和 PlannedTrainings 解决方案 1 起初我认为 Plan 是聚合根 因为脱离 Plan 的上下文
  • vim 中使用 powershell 的 system()

    我正在尝试在 Vim 中编写一个简单的函数来返回 powershell 命令的结果 不过 我的结果总是乱七八糟 我认为这可能是一个编码问题 但正如您所看到的 这个问题很奇怪 因为它 有点有效 但我没有任何解决问题的办法 在 vim 中设置以
  • 警报对话框或自定义警报对话框的大小

    我正在为 10 1 的所有平板电脑创建应用程序 现在我正在三星 Galaxy 选项卡上尝试此操作 我已经完成了所有部分 但关于平板电脑尺寸的警报对话框太小 我还创建了自定义警报对话框 但看起来不太好 那么告诉我我可以更改默认警报对话框的大小
  • 当 AutoGenerateColumns 设置为 True 时,如何停止在 DataGrid 中生成特定列?

    我已将 ObservableCollection 绑定到DataGrid并设置AutoGenerateColumns在具有 MVVM 应用程序的 WPF 中为 true 那我该怎么办stop a specific column要出现在 Da
  • 如何在 C# 中每隔几秒调用一个特定方法?

    机器人游戏 是我开发的第一个基础游戏 洋红色 角色是敌人 它应该在这张地图中随机移动 但它的随机移动太快 我尝试使用线程 但它会影响所有角色的速度 现在 我需要每 100 毫秒调用一次 Enemy 方法 Robot game Image 您
  • 如果我在存储过程中有多个 select 语句,如何使用 SqlDataReader

    我在 Microsoft SQL Server 2005 的存储过程中编写了三个 select 语句 两个 select 语句都返回多个记录 并且 select 语句的表列表不同 一个从主表中选择记录 另一个从子表中选择记录 在 C 代码中
  • 我该如何写上标文字?

    我有一个应用程序 其中包含大量上标数字或字母 我注意到 X span 3 span and just using sup tag around the figure 3 both yield X3 in my app But only th
  • 更改 ListView 背景 - 奇怪的行为

    我在更改 ListView 中视图的背景时遇到问题 我需要的 onClick 更改一行的背景图片 实际发生的情况 按下例如后 背景会发生变化 选择 第一个条目 但向下滚动后 第 8 个条目也被选中 滚动回到顶部 第一个不再被选择 现在选择第
  • 如何为ASP.NET身份设置密码规则?

    在我的 ASP NET 应用程序中 我在 web config 的 DefaultMembershipProvider 和 SqlMembershipProvider 中有以下设置 enablePasswordRetrieval true
  • 有符号整数溢出在 C++ 中仍然是未定义的行为吗?

    据我们所知 有符号整数溢出是未定义的行为 但C 11中有一些有趣的东西cstdint文档 有符号整数类型 宽度分别为 8 16 32 和 64 位 没有填充位 使用 2 的补码表示负值 仅当实现直接支持该类型时提供 See link 这是我
  • Java(JAXP)DocumentBuilder的XML解析差异

    之间有什么区别吗 DocumentBuilder parse InputStream and DocumentBuilder parse InputSource 我只能发现 对于第一种情况 解析器从流中检测编码 因此它更安全 而在后者中我不
  • 如何在后台使用 Flutter Method Channel(应用程序最小化/关闭)

    我正在 Flutter 应用程序中开发原生 Android 小部件 其中有刷新按钮 单击该按钮时我必须调用 Flutter 代码中的方法 我使用 Flutter Method Channel 进行通信 当应用程序位于前台时它工作正常 但当应
  • 无需 gcloud 客户端即可访问 google 容器注册表

    我有一个 CoreOS docker 主机 我想在其上开始运行容器 但是当尝试使用 docker 命令从 google 容器私有注册表中获取映像时 https cloud google com tools container registr
  • 在 Common Lisp 中,如何定义通用数据类型说明符(如整数列表)?

    我想定义一个类型说明符来描述相同类型的事物列表 所以我想有 list of integer 如同 array integer 这是内置的 我可以为特定类型创建它 如下所示 defun elements are integer seq eve
  • Moshi 判断 JSON 是数组还是单个对象

    有没有办法设置 Moshiadapter自动创建一个Object or List基于 JSON 响应 目前 我可以明确地做到这一点 例如 我可以收到以下回复 userId 1 id 2 body body title title Or us