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