有没有办法向下转换GWT AutoBean?

tim*_*ine 6 java polymorphism gwt json autobean

我一直在使用AutoBeans来映射来自非GWT-RPC基于Java的Web服务的JSON数据.到目前为止,除了一个映射之外,一切都在进行.

在服务器端,Class具有Map类型的属性,其中MyAbstractParentObject是大约15个不同子类的父类.

当我将它映射到客户端上的相应AutoBean接口时,我无法在解码后将MyAbstractParentObject转发为其子类型.我查看了GWT文档和"谷歌",看看AutoBeans是否具有多态支持,但无论如何都无法得到答案.拦截器和类别似乎无法处理这个问题,只是他们希望在接口中存在非getter/setter的方法.

我试图使用JSON数据中的类型字段来创建一个解决方法来创建子类的实例,但是AutoBean不允许我访问原始JSON,即使在调试器中我可以将其视为受保护的字段'数据'.如果我尝试解码原始bean,它将只有MyAbstractParentObject中的字段.

我能看到的唯一选择是:

  1. 扩展或创建我自己的AutoBeanCodex,它可以在解码JSON时正确处理MyAbstractParentObject的子节点.
  2. 找到一种方法来获取MyAbstractParentObject AutoBean中的原始JSON,并使用它来动态创建子类的实例.
  3. 切换到其他JSON-GWT序列化框架,如GWTProJSONSerializer或piriti.

任何帮助,将不胜感激.

Dar*_*nal 4

我知道这个问题很久以前就被问过,但我也很难找到答案。我意识到 AutoBeans 基本上只是 JSON 的精美包装器,因此仍然包含您想要将其向下转换到的子对象的字段的所有数据。所以我写了一个这样的方法:

public <A, B> B cast( A sourceObject, Class<B> targetClass )
{
    AutoBean<A> sourceBean = AutoBeanUtils.getAutoBean( sourceObject ); // Get the corresponding AutoBean.
    HasSplittable splittableBean = ( HasSplittable ) sourceBean;       // Implementation (if still AbstractAutoBean) supports this interface ;)
    Splittable splittable = splittableBean.getSplittable().deepCopy(); // If you don't copy it, decode() tries to be clever and returns
                                                                       // the original bean!
    AutoBean<B> targetBean = AutoBeanCodex.decode( typeFactory, targetClass, splittable ); // Create new AutoBean of
                                                                                           // the target type.
    return targetBean.as(); // Get the proxy for the outside world.
}
Run Code Online (Sandbox Code Playgroud)

-- 如您所见,typeFactory 扩展了 AutoBeanFactory。

它对我来说已经足够好了。最棘手的一点是对 HasSplittable 的强制转换,因为 AutoBean 不会扩展该接口,但 AbstractAutoBean(它实现 AutoBean)会扩展——并且它的子类是调用 getAutoBean() 返回的内容。

您还需要复制 Splittable,否则 AutoBeanCodex 会认为,“嘿,我已经有一个用于该 Splittable 的 AutoBean!给你!” ——并且只给你原件。;)

不管怎样,你可以向下、向上……向侧面投射!:P

后期编辑:几个月后再次偶然发现这一点,我想我应该对下面乔纳森提到的一些事情添加一个小警告。我在这里描述的方法旨在用于自反序列化以来未曾修改过的 AutoBean。这是因为(据我所知)无法保证您调用的任何 setter 都会实际更新 JSON(转换所需)。这可能不是什么大问题,因为通常当您有传入的 DTO 并且您希望在对其执行任何其他操作之前尽快将其转换为其真实类型时,您将使用它。在我们的例子中,我们的 AutoBean 甚至都没有设置器,所以这并不是一个真正的问题。;)

铸造完成后,您可以对最终的豆子做任何您想做的事情,毕竟它是刚从工厂出来的!