GWT десериализация постоянных объектов (JPA) - PullRequest
2 голосов
/ 11 января 2011

В настоящее время я занимаюсь разработкой Java / GWT-приложения, которое размещено на сервере приложений weblogic. Я использую EJB3.0 с EclipseLink в качестве постоянного слоя. К сожалению, у моего GWT есть проблемы с десериализацией постоянных объектов.

Вам может быть полезно знать, что я

  • иметь библиотеку EclipseLink в моем классе (включая javax.persistence.Entity)
  • я не получаю объекты постоянства из базы данных или менеджера постоянства - я создаю объекты со стандартным кодом Java
  • используйте Eclipse IDE для разработчиков Java EE для разработки и развертывания, и я компилирую свой код GWT с помощью плагина GWT (GWT 2.1.0) - мой исходный код разделен на несколько проектов
  • Я почти уверен, что проблемы возникают на стороне клиента, так как HTTP-ответ моего сервера одинаков в моем рабочем и в моем неработающем примере
  • попытался исправить патч javax.persistence.Entity и попытался включить несколько библиотек, которые включали javax.persistence.Entity, но ничего не помогло
  • минимальный проект только с этим кодом работает нормально, но этот код, интегрированный в среду нашего проекта, не работает

ОБНОВЛЕНИЕ: похоже, что вся эта тема - некоторая проблема с rpc.enhancedClasses. Я добавил интересное содержимое моих сгенерированных .gwt.rpc -файлов. Кажется необычным то, что данные, передаваемые по HTTP, одинаковы, хотя эти файлы .rpc различаются. Эти ссылки могут быть интересны: RemoteService.gwt.xml и документация для расширенных классов

На моем сервере представлен список экземпляров класса SerialClass; интерфейс выглядит так:

public interface GreetingService extends RemoteService {
    List<SerialClass> greetServer();
}

My onModuleLoad () - Метод получает эти экземпляры и создает всплывающее окно браузера с информацией:

public void onModuleLoad() {
    GreetingServiceAsync server = (GreetingServiceAsync) GWT.create(GreetingService.class);
    server.greetServer(new AsyncCallback<List<SerialClass>>() {
        public void onFailure(Throwable caught) {
        }

        public void onSuccess(List<SerialClass> result) {

            String resultString = "";
            try {
                for (SerialClass serial : result) {
                    if (serial == null) {
                        resultString += "null ";
                    } else {
                        resultString += ">" + serial.id + "< ";
                    }
                }
            } catch (Throwable t) {
                Window.alert("failed to process");
            }

            Window.alert("success:" + resultString);
        }
    });

}

Мой сервер выглядит так:

public class GreetingServiceImpl extends RemoteServiceServlet implements GreetingService {
    public List<SerialClass> greetServer() throws IllegalArgumentException {
        List<SerialClass> list = new ArrayList<SerialClass>();
        for (int i = 0; i < 100; i++) {
            list.add(new SerialClass());
        }
        return list;
    }
}

Случай 1 => все отлично работает

Я использую это SerialClass (либо без аннотации, либо с любой аннотацией, отличной от Entity - например, javax.persistence.PersistenceContext работает нормально):

//@Entity
public class SerialClass implements Serializable, IsSerializable {
    public int id = 4711;
}

Всплывающее окно содержит (как и ожидалось):

success:>4711< >4711< >4711< >4711< >4711< >4711< >4711< >4711< >4711< >4711< >4711< >4711< >4711< >4711< >4711< >4711< >4711< >4711< >4711< >4711< >4711< >4711< >4711< >4711< >4711< >4711< >4711< >4711< >4711< >4711< >4711< >4711< >4711< >4711< >4711< >4711< >4711< >4711< >4711< >4711< >4711< >4711< >4711< >4711< >4711< >4711< >4711< >4711< >4711< >4711< >4711< >4711< >4711< >4711< >4711< >4711< >4711< >4711< >4711< >4711< >4711< >4711< >4711< >4711< >4711< >4711< >4711< >4711< >4711< >4711< >4711< >4711< >4711< >4711< >4711< >4711< >4711< >4711< >4711< >4711< >4711< >4711< >4711< >4711< >4711< >4711< >4711< >4711< >4711< >4711< >4711< >4711< >4711< >4711< >4711< >4711< >4711< >4711< >4711< >4711<

Данные, отправленные по HTTP, выглядят так:

//OK[4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,100,1,["java.util.ArrayList/3821976829","serial.shared.SerialClass/10650133"],0,6]

Сгенерированный .xml.rpc -файл (4F138A4EA095EA4C468507AF3CA19D8F.gwt.rpc) содержит:

my.package.SerialClass, true, true, false, false, my.package.SerialClass/2805025871, 2805025871
[Lmy.package.SerialClass;, true, true, false, false, [Lmy.package.SerialClass;/600614154, 600614154

Случай 2 => он вообще не работает

Я использую это SerialClass:

@Entity
public class SerialClass implements Serializable, IsSerializable {
    public int id = 4711;
}

Мое всплывающее окно содержит ( ЭТО МОЯ ПРОБЛЕМА ):

success:>2< null >2< null >2< null >2< null >2< null >2< null >2< null >2< null >2< null >2< null >2< null >2< null >2< null >2< null >2< null >2< null >2< null >2< null >2< null >2< null >2< null >2< null >2< null >2< null >2< null >2< null >2< null >2< null >2< null >2< null >2< null >2< null >2< null >2< null >2< null >2< null >2< null >2< null >2< null >2< null >2< null >2< null >2< null >2< null >2< null >2< null >2< null >2< null >2< null >2< null 

Данные, отправленные по HTTP, выглядят так (точно так же!):

//OK[4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,4711,2,100,1,["java.util.ArrayList/3821976829","serial.shared.SerialClass/10650133"],0,6]

Сгенерированный .xml.rpc -файл (E81A9E44448F41D2EC63CD508632C10B.gwt.rpc) содержит:

my.package.SerialClass, true, true, false, false, my.package.SerialClass/2805025871, 2805025871
@ClientFields,my.package.SerialClass,id
[Lmy.package.SerialClass;, true, true, false, false, [Lmy.package.SerialClass;/600614154, 600614154

Нет подозрительных выходов журнала - ни на сервере, ни на клиенте. Все HTTP-ответы имеют код возврата 200.

Мой текущий обходной путь

Я собираюсь попытаться создать объекты переноса как копию моего SerialClass - эти объекты переноса будут выглядеть точно так же, но не будут иметь аннотации @Entity.

В качестве альтернативы я мог бы попытаться использовать RequestFactory (спасибо @Hilbrand за подсказку).

Я действительно не знаю, как решить эту проблему, и я очень благодарен за любые предложения, советы, подсказки, ссылки и т. Д.

Ответы [ 6 ]

3 голосов
/ 11 января 2011

С GWT RPC вы не можете сериализовать какой-либо класс, содержащий код, который не может быть скомпилирован в JavaScript, и, поскольку вы предлагаете способ продвижения вперед, это создание объектов передачи.

Альтернативой является использованиеGWT 2.1 RequestFactory, см. Также эту статью http://blog.ltgt.net/gwt-211-requestfactory. Но и на стороне клиент / сервер он отличается от RPC, поэтому вам нужно реорганизовать реализацию на стороне клиент / сервер, что может стоить больше времени, чем написание объектов переноса.*

1 голос
/ 22 марта 2011

Хорошо, мы нашли решение! Спасибо всем, кто мне помог!

GWT не удалось сериализовать объекты моего аннотированного класса, потому что .gwt.rpc -файлы не были доступны через контекст сервлета.

Решением было создать всего один военный файл , содержащий все ресурсы javascript, html и rpc. Этот военный файл теперь также содержит определения сервлета (в web.xml). Наш java-код развернут в отдельных модулях (jar-файлах), на которые ссылается этот war-файл.

1 голос
/ 09 марта 2011

Я упоминал, как использовать сущности JPA 2.0 на уровне GWT на мой блог .Кроме того, у меня есть проект затмения, имитирующий ваш сценарий.Вы можете скачать его, используя эту ссылку .Я использовал GWT 2.2, если ваша версия gwt ниже 2.1, вы также должны добавить gwt-java-math в ваш проект.

0 голосов
/ 10 марта 2011

Я справился с этим, создав DTO или объекты-значения.GWT требует исходные файлы на стороне клиента.Я не думаю, что есть способ обойти это.

0 голосов
/ 13 января 2011

Нет необходимости создавать копии ваших стоимостных объектов.Я сталкивался с такой проблемой раньше.Я загрузил скелет приложения , чтобы помочь вам начать работу (за исключением библиотек).Дайте мне знать, если вы не можете использовать SVN.

0 голосов
/ 11 января 2011

Обход:

Вы должны предоставить источники использованных аннотаций для компиляции компилятором GWT.

Просто создайте специальный каталог с исходными текстами, который будет использоваться только для GWT-компиляции, и скопируйте туда источники аннотаций.

...