当前位置: 首页 > 知识库问答 >
问题:

使Gson行为依赖于深度

孙朗
2023-03-14

有没有合理的方法让Gson以不同于顶层对象的方式处理嵌套对象?要序列化的东西是实体,它们都有一个< code>id。嵌套的实体应该用它的< code>id来代替(以缩短输出并可能避免无休止的递归)。

假设有一个

@AllArgsConstructor class User {
    int id;
    String name;
    User parent;
}

我执行

User grampa = new User(3, "Grampa", null);
User homer = new User(2, "Homer", grampa);
User bart = new User(1, "Bart", homer);

当序列化<code>bart</code>时,我得到的是

{
    id: 1,
    name: "Bart",
    father: {
        id: 2,
        name: "Homer",
        father: {
            id: 3,
            name: "Grampa"
        }
    }
}

这比我需要的要多得多。我实际上从不想序列化嵌套实体,它们的 id已经足够好了。

使用 <罢工> 全球的 线程局部变量hack和一个< code > typedadapterfactory 我可以得到

{
    id: 1,
    name: "Bart",
    father: 2,
}

这正是我想要的。我更喜欢< code>fatherId而不是< code>father,我当然更喜欢比全局变量更简单的东西。

我不想创建一个DAO,反射性或类似地扫描对象(然后我可以自己做整个序列化,不是吗?

共有1个答案

凌嘉勋
2023-03-14

我认为 Gson 文档为“更理智”的方法指明了道路。创建一个 TypeAdapter 工厂,该工厂封装状态并返回引用该状态的内部类 TypeAdapter 实例,如下所示:

public class UserTypeAdapterFactory {
    private Set<Integer> serializedUsers = new HashSet<>();

    public JsonSerializer<User> getTypeAdapter() {
        return (user, type, context) -> {
            JsonObject el = new JsonObject();
            el.addProperty("id", user.getId());
            el.addProperty("name", user.getName());

            if(user.getFather() != null) {
                JsonArray els = new JsonArray();
                int fatherId = user.getFather().getId();
                if(!serializedUsers.contains(fatherId)) {
                    JsonElement father = context.serialize(user.getFather());
                    if (father.isJsonArray()) {
                        els.addAll(father.getAsJsonArray());
                    } else {
                        els.add(father);
                    }
                    serializedUsers.add(fatherId);
                }
                el.addProperty("fatherId", fatherId);
                els.add(el);
                return els;
            } else {
                return el;
            }
        };
    }
}

Gson gson = new GsonBuilder()
    .registerTypeAdapter(
        User.class, 
        new UserTypeAdapterFactory().getTypeAdapter())
    .build();
System.out.println(gson.toJson(
    new User(1, "Bart", new User(2, "Homer", new User(3, "Grampa", null)))));

应打印:

[{"id":3,"name":"Grampa"},{"id":2,"name":"Homer","fatherId":3},{"id":1,"name":"Bart","fatherId":2}]
 类似资料:
  • 问题内容: 我找不到golang依赖于c运行时的信息吗?如果依赖它,它是否会在go-binary中静态编译以使Go-app可以在任何地方工作而无需依赖? 这是有关什么是C运行时的主题 libcmt是Microsoft编译器提供的C标准库的(几种)实现。它们提供三种基本类型的库的“调试”和“发行”版本:单线程(始终静态链接),多线程静态链接和多线程动态链接(尽管取决于您使用的编译器版本)使用,其中一

  • 作为foo-3.0.0.jar的“旧版本圈”使用bar-2.0.0.jar,bar-2.0.0.jar使用foo-1.0.0.jar。 这不是关于构建foo.jar或bar.jar,而是关于构建依赖于foo.jar或bar.jar的项目。

  • 但当我将扩展名更改为时就会失败。 经过一些调试后,我确信如果使用类似的url的话,请求甚至不会被映射 对于高日志级别,我可以看到映射被Spring捕获: MVC-Config: 有人知道吗?

  • 问题内容: 我第一次使用Maven时,就陷入了依赖关系。 我使用Eclipse创建了一个Maven项目并添加了依赖项,并且该项目运行正常。 但是当我尝试通过命令行运行它时: 它下载依赖项,成功构建,但是当我尝试运行它时,出现NoClassDefFoundError: 我的是这样的: 谁能帮我? 问题答案: 默认情况下,Maven不会在生成的JAR文件中捆绑依赖项,并且在尝试通过命令行执行JAR文件

  • 例如,Foos的资源可能如下所示: 对于酒吧:

  • 我正在使用垃圾,模拟和模拟MVC来测试网络应用程序的工作。我正在与一个我无法弄清楚的注入的依赖关系作斗争。我的网络应用程序结构如下。 和服务级别 我需要测试此控制器的搜索方法,但是service2当前不活动,因此必须模拟对它的调用。我可以模拟service2,但不知道如何在控制器的mockMVC实例中注入service2的模拟。据我所知,mockito中的@InjectMocks只注入一层深度的m