Есть ли способ уменьшить GWT AutoBean? - PullRequest
6 голосов
/ 05 октября 2011

Я использую AutoBeans для отображения данных JSON, поступающих от веб-службы, не основанной на GWT-RPC Java. Пока все работает, кроме одного сопоставления.

На стороне сервера у класса есть свойство типа Map, где MyAbstractParentObject является родительским классом около 15 различных дочерних классов.

Когда я сопоставляю это с соответствующим интерфейсом AutoBean на клиенте, я не могу понижать MyAbstractParentObject до его дочернего типа после того, как он был декодирован. Я просмотрел все документы GWT и «Googles», чтобы увидеть, есть ли у AutoBeans полиморфная поддержка, но не смог получить ответ в любом случае. Кажется, что перехватчики и категории не способны справиться с этим, просто методы, которые они хотят существовать в интерфейсе, не являются получателями / установщиками.

Я пытался сделать обходной путь, используя поле типа в данных JSON для создания экземпляра дочернего класса, но AutoBean не дает мне доступ к необработанному JSON, хотя в отладчике я вижу его как защищенное поле под названием «данные». Если я попытаюсь декодировать исходный компонент, он будет иметь только поля в MyAbstractParentObject.

Единственные альтернативы, которые я вижу, это:

  1. Расширение или создание собственного AutoBeanCodex, который может правильно обрабатывать потомки MyAbstractParentObject, когда он декодирует JSON.
  2. Найдите способ получить необработанный JSON в автоинструменте MyAbstractParentObject. и использовать его для создания и экземпляра дочернего класса на лету.
  3. Переключиться на другую платформу сериализации JSON-GWT, например GWTProJSONSerializer или пириты.

Буду признателен за любую помощь.

Ответы [ 2 ]

4 голосов
/ 14 июня 2013

Я знаю, что об этом спрашивали давным-давно, но я тоже изо всех сил пытался найти ответ.Я понял, что 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.
}

- где typeFactory расширяет AutoBeanFactory, как вы можете видеть.

Это сработало достаточно хорошо для меня.Самым хитрым было приведение к HasSplittable, так как AutoBean не расширяет этот интерфейс, а AbstractAutoBean (который реализует AutoBean) - и подкласс этого является тем, что возвращается вызовами getAutoBean ().

Youтакже необходимо скопировать Splittable, иначе AutoBeanCodex думает: «Эй, у меня уже есть AutoBean для этого Splittable! Вот, пожалуйста!»- и просто дает вам оригинал.;)

В любом случае, вы можете бросить вниз, вверх ... в сторону!: P

Позднее редактирование: Спустя несколько месяцев, наткнувшись на это, я решил добавить небольшое предостережение о том, что Джонатан упомянул ниже.Метод, который я описал здесь, предназначен для использования в AutoBean, который не был изменен с момента десериализации.Это потому, что (AFAIK) нет гарантии, что любые вызываемые вами сеттеры действительно обновят JSON (необходимый для приведения).Это, вероятно, не имеет большого значения, так как обычно вы будете использовать это, когда у вас есть входящий DTO и вы хотите привести его к типу real как можно скорее, прежде чем делать с ним что-то еще.В нашем случае ни у одного из наших AutoBeans даже не было сеттеров, так что это не было проблемой.;)

После того, как вы разыгрываете его, вы можете делать все, что захотите, с полученным бином, который, в конце концов, только что с фабрики!

0 голосов
/ 26 января 2012

Я не очень знаком с AutoBean, но вы, вероятно, можете использовать сериализатор / десериализатор из RestyGWT.Он поддерживает полиморфизм, используя аннотации.

ссылка на документацию: http://restygwt.fusesource.org/documentation/restygwt-user-guide.html#Polymorphic_Sub_Types

...