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

如何实现与@JsonUnwrap等效的Gson

闽念
2023-03-14

我知道Gson没有类似的功能,但是有没有办法像JsonUnwrap那样增加对Json字段的解包支持?

目标是允许这样的结构:

public class Person { 
    public int age; 
    public Name name; 
} 

public class Name { 
    public String first;
    public String last; 
}

要(反)序列化为:

{
  "age" : 18, 
  "first" : "Joey", 
  "last" : "Sixpack" 
}

而不是:

{
   "age" : 18, 
    "name" : {
        "first" : "Joey",
        "last" : "Sixpack"
    } 
 }

我知道这可能会变得相当复杂,所以我不是在寻找一个完整的解决方案,如果这是可行的,我只是寻求一些高级别的指导方针。

共有2个答案

冯风史
2023-03-14

目前,没有简单的方法可以做到这一点。无论如何,这里有一些建议/替代方法可以让它发挥作用。

GsonFire:GsonFire实现了Gson中缺少的一些有用特性。虽然它还没有提供自动包装/展开,但它可能是创建自定义逻辑的良好起点。

如果您只需要序列化,您可以在Person中为firstlast添加getter,并使用@ExposeomeodResult对它们进行序列化。不幸的是,不支持设置器(参见。当Gson反序列化JSON时,可以使用设置器吗?)。

支持序列化的另一种方法是遵循如何将字段移动到父对象的建议。

自定义TypeAdapters:支持序列化和反序列化的唯一方法之一是创建自定义TypeAdapter。这不是通用的,但会适合您的用例。

线程将html" target="_blank">嵌套对象序列化为属性已经为您提供了示例,所以这里不再重复。

乜飞航
2023-03-14

我对支持此功能的反序列化程序进行了粗略的实现。它是完全通用的(与类型无关),但也很昂贵和脆弱,我不会将其用于任何严重的情况。我发帖只是为了向其他人展示我所拥有的,如果他们最终需要做类似的事情的话。

public class UnwrappingDeserializer implements JsonDeserializer<Object> {

    //This Gson needs to be identical to the global one, sans this deserializer to prevent infinite recursion
    private Gson delegate;

    public UnwrappingDeserializer(Gson delegate) {
        this.delegate = delegate;
    }

    @Override
    public Object deserialize(JsonElement json, Type type, JsonDeserializationContext context) throws JsonParseException {
        Object def = delegate.fromJson(json, type); //Gson doesn't care about unknown fields
        Class raw = GenericTypeReflector.erase(type);
        Set<Field> unwrappedFields = ClassUtils.getAnnotatedFields(raw, GsonUnwrap.class);
        for (Field field : unwrappedFields) {
            AnnotatedType fieldType = GenericTypeReflector.getExactFieldType(field, type);
            field.setAccessible(true);
            try {
                Object fieldValue = deserialize(json, fieldType.getType(), context);
                field.set(def, fieldValue);
            } catch (IllegalAccessException e) {
                throw new RuntimeException(e);
            }
        }

        return def;
    }
}

然后可以通过新的GsonBuilder()进行全局注册。registerTypeHierarchyAdapter(Object.class,new UnwrappingDeserializer(new Gson()))。create()或通过registerTypeAdapter为特定类型创建。

注意事项:

  • 真正的实现应该递归地检查整个类结构是否存在GsonUnwrap,将结果缓存在并发映射中,并且仅在需要时执行此过程。否则,它应该立即返回def

我认为对于序列化也可以做类似的事情。从德林的答案中链接的例子可以作为一个起点。

 类似资料:
  • 问题内容: 有什么方法可以获取文档中所有对象的集合? 对于Elements来说效果很好,但是s不是Elements。 更新: 我意识到这可以通过遍历DOM来完成-如以下建议所示。我知道如何编写一个DOM- walker函数来查看文档中的每个节点。我希望有某种浏览器本机的方法可以做到这一点。毕竟,我可以通过一个内置调用获得所有s,但不是全部s 有点奇怪。 问题答案: 更新 : 我已经概述了这6种方法

  • 我正在尝试编写一个以便比较一些RDBMS、NewSQL和NoSQL。这个脚本只是执行查询并测量执行时间。 但是在mongodb-php中,函数返回一个 和是否等价(时间/数据成本)?游标不加载数据,我必须迭代游标才能加载数据…为什么在MySQL和mongoDB之间执行查询的时间如此不同或者仅仅是mongoDB的岩石... 我想知道将我的代码更改为:

  • 问题内容: 在C#中寻找与此方法相同的方法 问题答案: 在C#中超级简单:

  • 本文向大家介绍IOS等待时动画效果的实现,包括了IOS等待时动画效果的实现的使用技巧和注意事项,需要的朋友参考一下 查询时间或长或短,为了提升用户体验,目前用的比较多的手段之一就是查询等待时添加一个动态等待效果。当我们在请求网络时加载页面时有个动作效果,效果图如下: 源代码可以网上找开源项目Coding.net,上面的效果原理为两张图片组合,外面那个则为动画转动,里面的图标则是透明度的变化;主要代

  • 问题内容: 如何找到与整数等效的罗马数字。是否有提供此功能的Java库? 问题答案: 这是许多语言(包括Java )的链接。这是相关的摘录:

  • 关于事件部分,我思考了很久,也参考了许多,到底如何能用一个很简单的方法实现一模一样的on、off呢? 最后我的设计思路是: 1.有一个全局存储所有Events的数组,存放每个dom元素上的事件。 2.给每个DOM一个guid的唯一标识符,通过这个guid来找出Events数组里的事件。 由于逻辑比较复杂,我们先来画个图看看。 首先,我们利用DOM可以增加自定义属性的原理,在它的身上存一个guid。