GWT i kod generowany z XSD
Ostatnio zmierzyliśmy się z ciekawym zadaniem integracji pewnej aplikacji z innym systemem poprzez REST.
Aplikacja nad którą pracujemy to w pewnym sensie interfejs do większego systemu (frontend). Jest to system oparty o Springframework 2.5 a interfejs użytkownika zbudowany jest w większości w GWT. Po stronie serwerowej nasza aplikacja komunikuje się z innym systemem poprzez REST, wymieniając informacje w XML’u.
Oczywiście przesyłane wiadomości opisane zostały w XSD.
Długo szukaliśmy odpowiedniego rozwiązania serializacji i deserializacji (lub marschalingu i demarschalingu – jak ktoś woli) przesyłanych komunikatów do obiektów w Javie. XSD we wczesnej fazie projektu dość często się zmienia, więc podstawowym założeniem było automatyczne generowanie kodu. Poprzednio używaliśmy JAXB do tego typu rozwiązań, jednak w tym wypadku chcieliśmy współdzielić generowany kod z kodem GWT, i tu zrodziły się problemy. JAXB używa np. BigInteger dla xs:integer, a ta klasa nie ma odpowiednika w GWT, jednak w tym przypadku udało się prze-definiować typ generowany przez JAXB. Sztuczka ta jednak nie sprawdziła się w przypadku xs:dateTime – gdzie JAXB używa XMLGregorianCalendar, nawet przy wymuszeniu użycia Date JAXB definiował, używając anotacji specjalne klasy do bindowania wartości – z którymi kompilator GWT za nic sobie nie radził.
Postanowiłem więc spróbować innej biblioteki. Po przeszukaniu dostępnych opcji, i próbie wykorzystania kilku z nich ostatecznie zdecydowaliśmy się na JiBX, który bardzo polecam w tego typu problemie – z generowanym kodem świetnie radzi sobie kompilator (a raczej translator) GWT.
A oto kilka użytecznych rozwiązań problemów z jakimi przyszło się zmierzyć:
Przede wszystkim by można było dany obiekt przesłać poprzez RPC, jego klasa musi implementować interfejs com.google.gwt.user.client.rpc.IsSerializable, używając JiBX jest to zadanie bardzo proste.
W tym celu stworzyłem dekorator dla generowanego kodu:
[java]
package com.konri.app.dto.jixbtools;
import org.eclipse.jdt.core.dom.FieldDeclaration;
import org.eclipse.jdt.core.dom.MethodDeclaration;
import org.jibx.schema.codegen.IClassHolder;
import org.jibx.schema.codegen.extend.ClassDecorator;
public class IsSerializableDecorator implements ClassDecorator
{
@Override
public void start(IClassHolder holder)
{
holder.addImport(“com.google.gwt.user.client.rpc.IsSerializable”);
holder.addInterface(“com.google.gwt.user.client.rpc.IsSerializable”);
}
@Override
public void valueAdded(String basename, boolean collect, String type, FieldDeclaration field, MethodDeclaration getmeth, MethodDeclaration setmeth, String descript, IClassHolder holder)
{
}
@Override
public void finish(IClassHolder holder)
{
}
}
[/java]
By użyć dekoratora należy zdefiniować rozszerzenie dla generatora kodu (dal przykładu założyłem, że generuję kod z dwóch plików XSD: person.xsd oraz portfolio.xsd):
[xml]
[/xml]
A to fragment skryptu dla Ant’a, łączącego wszystko w całość:
[xml]
Zostaw odpowiedź!
Musisz się zalogować aby móc komentować.

