2011-10-04 156 views
5

我一直在使用AutoBeans来映射来自非GWT-RPC基于Java的Web服务的JSON数据。除了一个映射以外,所有东西都一直在运行。有没有办法让GWT AutoBean下滑?

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

当我将其映射到客户端上的相应AutoBean接口时,我无法在解码后将MyAbstractParentObject向下转换为其子类型。我查看了GWT文档和'Googles',看看AutoBeans是否具有多态支持,但无论如何都无法得到答案。拦截器和类别似乎不能处理这个问题,只是他们想要在接口中存在的方法不是getter/setters。

我正在尝试使用JSON数据中的type字段来创建一个解决方案,以创建子类的一个实例,但AutoBean不允许我访问原始JSON,即使在调试器中我可以看到它一个名为“数据”的受保护字段。如果我尝试解码原始的bean,它将只有MyAbstractParentObject中的字段。

我能看到的唯一的选择是:

  1. 扩展或创建自己的AutoBeanCodex能够妥善处理MyAbstractParentObject的 孩子时,解码JSON。
  2. 找到一种方法在MyAbstractParentObject AutoBean 中找到原始JSON,并使用该方法即时创建子实例和实例。
  3. 切换到其他一些JSON-GWT序列化框架,如 GWTProJSONSerializer或piriti。

任何帮助,将不胜感激。

回答

4

我知道这是问了很久以前,但我在努力寻找答案了。我意识到,由于它们基本上只是JSON的漂亮包装,所以AutoBeans仍包含要向下转发的子对象字段的所有数据。所以我写了这样一个方法:

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. 
} 

- 其中typeFactory扩展AutoBeanFactory,如你所见。

这对我来说已经够用了。最棘手的部分是对HasSplittable的强制转换,因为AutoBean不扩展该接口,但是AbstractAutoBean(实现AutoBean)的确如此 - 并且调用getAutoBean()的一个子类。

您还需要复制可拆分表,否则AutoBeanCodex认为,“嘿,我已经拥有可拆分的AutoBean!在这里,你去!” - 只是给你的原始。 ;)

无论如何,你可以向下,向上...侧身!:P

延迟编辑:几个月后再次陷入困境,我想我会添加一个关于乔纳森下面提到的东西的小警告。我在这里描述的方法被设计用于一个AutoBean,它在反序列化之后还没有被修改过。这是因为(AFAIK)并不能保证你调用的任何setter实际上都会更新JSON(需要投射)。这可能不是一个大问题,因为通常你会用这个当你有一个进入的DTO,并希望将其转换为它的真正尽快类型,做什么都与它之前。在我们的案例中,我们的所有的AutoBeans都没有安装者,所以这不是一个真正的问题。 ;)

你施放它后,你可以做任何你想要与得到的豆腐,这是刚从工厂毕竟!

+0

我不得不使用AutoBeans做类似的事情,但我做了一个完整的编码,以便从AutoBean中获得可拆分表格 Splittable split = AutoBeanCodex.encode(AutoBeanUtils.getAutoBean(sourceBean)); – Jonathan

+0

@Jonathan我尝试过'AutoBeanCodex.encode()';它适用于上传,但不适用于向下转换 - 这是一个很简单的方法。 :) '编码()'使用访问者模式遍历bean的属性来产生新的'Splittable'。可悲的是,源JSON具有无法通过该bean访问的属性,但需要将其“downcast”它......并且访问者不会看到它们,所以来自encode()的JSON的Splittable '没有他们。 :( ......因此古怪直接获得'Splittable'并复制它。它正确地解码,因为所有的信息仍然存在 –

+0

我看你要什么现在看来,我认为这两种技术都有自己的。我一直在使用我上面提到的方法,因为大多数时候我将一个自动选择器转换为另一个,所以在这种情况下我做了修改,所以在这种情况下,我需要完整的访问者遍历得到所有正确的物化信息如果你没有做任何修改,并且你知道**没有做任何修改,那么使用'HasSplittable'可以使滑动的斜率变好,否则,你只能选择执行完整的编码。除非我失去了一些东西..... – Jonathan