java.util.Date
oraz typu wyliczeniowego - enumeracji.Gwoli przypomnienia w tym przypadku nie chodzi o serializację obiektów z poziomu javy, tylko o ręczne preparowania plików XML zawierających zserializowane obiekty, które zostaną zdeserializowane z użyciem standardowego mechanizmu -
java.beans.XMLDecoder
, a następnie zostaną użyte jako dane wejściowe dla testów jednostkowych.Niemniej przy serializacji obiektu z poziomy javy, który ma jedno pole o typie
java.util.Date
a drugie o typie wyliczeniowym, uzyskamy efekt dalece niezadowalający, którego na pewno nie będziemy chcieli naśladować.Pole o typie wyliczeniowym w ogóle nie zostanie zapisane. Z kolei pole z datom zostanie zapisane, ale w formie liczby milisekund od 1 stycznia 1970r. Na pewno nie jest to wygodna postać dla człowieka, anie do odczytu, a tym bardziej do zapisu. W każdym razie
java.beans.XMLEncoder
zserializuje java.util.Date
w następujący sposób:
<void property="birthDate"> <object class="java.util.Date"> <long>439254000000</long> </object> </void>Not tak... to przecież całkiem logiczne, bo jest to jedyny nie "potępiony" sposób ustawiania daty jaki oferuje interfejs
java.util.Date
.Normalnie (w javie) jakbym miał uzyskać datę ze stringa, to bym skorzystał z
java.text.SimpleDateFormat
. No ale jak go użyć w tym XML'u... już podaję:
<void id="sdf" class="java.text.SimpleDateFormat"> <string>yyyy-MM-dd</string> <void id="date0" method="parse"> <string>1983-12-03</string> </void> </void> ... <object class="pl.dwalczak.Osoba"> ... <void property="dataUrodzin"> <object idref="date0"/> </void> ... </object>Pierwsza część konstrukcji (znacznik
void
z id="sdf"
), to deklaracja, której w javie odpowiada:
java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy-MM-dd"); java.util.Date date0 = sdf.parse("1983-12-03");Nie definiuje ona żadnego zserializowanego obiektu, a jedynie zmienne, które mogą być wykorzystane przy definiowaniu zserializowanych obietków. Może być umieszczona w elemencie głównym, lub też bezpośrednio w zserializowanym obiekcie.
Druga część konstrukcji (znacznik
object
) definiuje obiekt typu pl.dwalczak.Osoba
, w którym ustawia pole dataUrodzin
wcześniej zdefiniowaną zmienną date0
.Wracając do typu wyliczeniowego.
Załóżmy, że klasa
pl.dwalczak.Osoba
posiada pole typOsoby
o typie pl.dwalczak.TypOsoby
, który jest enumeracjom:
package pl.dwalczak; public enum TypOsoby { OsobaFizyczna, OsobaPrawna; }Wówczas ustawienie pola
typOsoby
dla obiektu pl.dwalczak.Osoba
może wyglądać następująco:
<void property="type"> <object class="com.dwalczak.TypOsoby" field="OsobaFizyczna"/> </void>Lub tak:
<void property="type"> <object class="com.dwalczak.TypOsoby" method="valueOf"> <string>OsobaPrawna</string> </object> </void>
Podsumowanie
O ile problem z serializowaniem wartości typu wyliczeniowego, nie specjalnie zmniejsza atrakcyjność formatu standardowej serializacji obiektów XML w J2SE, jako ogólnego formatu zapisywania danych testowych, gdyż manualnie można to zapisać w całkiem przyzwoitej formie. To problem z datą faktycznie obniża tą atrakcyjność, gdyż formuła zapisu jej w "ludzkiej" postaci jest trochę za długa i skomplikowana. Mimo to, myślę że stosowanie tego formatu może być mniej pracochłonne niż projektowanie własnego i pisanie kodu deserializującego z niego obiekty.Zasoby
Long Term Persistence of JavaBeans Components: XML SchemaSergey Malenkov's Blog - How to encode Type-Safe Enums?
Brak komentarzy:
Prześlij komentarz