Serializacja pozwala zamieni obiekt na sekwencj bajtw w
Serializacja pozwala zamienić obiekt na sekwencję bajtów, w sposób umożliwiający później wierne odtworzenie jego zawartości • Inna nazwa to trwałość (ang. persistence) – cecha oznaczająca, że życie obiektu nie jest ograniczone tylko do czasu działania programu • Działa to również w sieci, pomiędzy maszynami działającymi pod różnymi systemami operacyjnymi • Dużo klas z bibliotek Javy jest zmodyfikowanych tak, że wspierają serializację (np. kolekcje)
Zastosowania serializacji • Trwałość – zapisanie obiektów na dysk oraz odtworzenie przy kolejnym uruchomieniu programu. • Zdalne wywoływanie metod między komputerami poprzez RMI (ang. Remote Method Invocation). Pozwala to obiektowi istniejącemu na jednym komputerze zachowywać się tak, jakby istniał na drugim komputerze. Serializacja jest używana do przekazywania argumentów przy wywołaniu metod odległego obiektu oraz do zwracania wartości. • Komponenty Java. Beans – elementy z których buduje się interfejs użytkownika. W trakcie projektowania stan komponentu jest serializowany, a przy starcie programu jest on odtwarzany.
Sposoby realizacji Serializację typowo realizuje się przez: 1. Implementację w klasie, która ma być serializowana interfejsu Serializable (nie ma żadnych metod) Można także kontrolować przebieg serializacji przez: 2. Implementację w klasie interfejsu Externalizable oraz jego dwóch metod: write. External() – zapis obiektu i read. External() – odczyt obiektu, musi być też dostępny publiczny konstruktor domyślny 3. Implementację w klasie interfejsu Serializable oraz dodatkowo (!) dwóch prywatnych metod write. Object() i read. Object()
Działanie • Żeby zserializować obiekt, trzeba utworzyć strumień Object. Output. Stream i wywołać jego metodę write. Object() podając obiekt do serializacji. Może się tu pojawić wyjątek IOException. • Żeby odtworzyć obiekt, trzeba utworzyć strumień Object. Input. Stream, wywołać jego metodę read. Object() i dokonać rzutowania (read. Object() zwraca bowiem obiekt klasy Object). Mogą się tu pojawić wyjątki IOException oraz Class. Not. Found. Exception. • Słowo kluczowe transient pozwala wskazać, które składowe obiektu mają nie być serializowane.
Przykład serializowania obiektów import java. io. *; class Wezel implements Serializable { String nazwa; /*. . . */ } public class Serializacja { Wezel korzen = new Wezel(); /*. . . */ void zapisz. Wezly() throws IOException { /*. . . utworzenie strumienia wyjściowego. . . */ Object. Output. Stream out = new Object. Output. Stream( /*strumień wyj. */ ); out. write. Object(korzen); }
Przykład odtwarzania obiektów /*. . . */ void przywroc. Wezly() throws IOException, Class. Not. Found. Exception { /*. . . utworzenie strumienia wejściowego. . . */ Object. Input. Stream in = new Object. Input. Stream( /*strumień wej. */ ); } } // odczytanie obiektu i rzutowanie do // odpowiedniego typu korzen = (Wezel) in. read. Object();
Serwlety i zasoby • Serwlet działający w środowisku serwera J 2 EE występuje tylko w jednej kopii • Jeśli do swojego działania potrzebuje jakichś zasobów, to może tego dokonać przy starcie, w swojej metodzie init() • Po skończeniu pracy (przy wyładowywaniu serwletu z pamięci) powinien zwolnić zasoby w swojej metodzie destroy() • Należy przy tym uważać, żeby nie zwolnić zasobów, które są jeszcze używane
Inicjalizacja zasobów – init() • Jeśli inicjalizacja zasobów potrzebnych do działania nie udała się, serwlet powinien wyrzucić wyjątek Unavailable. Exception public class DBServlet extends Http. Servlet { /*. . . */ public void init() throws Servlet. Exception { establish. Connection(); if (connection == null) throw new Unavailable. Exception( "Couldn't get database. "); } }
Zwalnianie zasobów – destroy() • Zasoby można dodatkowo ustawić na null, aby szybciej uległy procesowi odśmiecania pamięci public class DBServlet extends Http. Servlet { /*. . . */ public void destroy() { connection. close(); connection = null; } /*. . . */ }
Serwlety i wątki • Serwer obsługujący serwlety umożliwia równoczesne wykonanie kodu serwletu dla wielu żądań klientów, tworząc wątek dla każdego żądania • Można zagwarantować, że serwlet będzie obsługiwał tylko jedno żądanie naraz implementując pusty interfejs Single. Thread. Model (serwer J 2 EE może wtedy synchronizować dostęp do serwletu lub tworzyć wiele komponentów Web'owych i kierować żądania do aktualnie wolnego egzemplarza) • Zawsze jednak trzeba zabezpieczyć się przed niepoprawnym użyciem zasobów dzielonych stosując metody synchronizacji wątków
Współdzielenie informacji • Każda aplikacja webowa (web application) posiada kontekst wykonania na serwerze J 2 EE, jest on reprezentowany przez obiekt klasy Servlet. Context • Konteksty są tworzone przez serwer J 2 EE podczas jego startu, ew. przy przeładowaniu aplikacji, na podstawie globalnego dla aplikacji pliku web. xml • Istnieje jeden kontekst dla każdej aplikacji na każdej maszynie wirtualnej, na której jest ona uruchomiona • Klasa Servlet umożliwia dostęp do swojego kontekstu poprzez metodę get. Servlet. Context()
Współdzielenie informacji • Architektura serwletów umożliwia posiadanie informacji globalnej dla całej aplikacji webowej. W tym celu trzeba użyć metod set. Attribute() oraz get. Attribute() klasy Servlet. Context void set. Attribute(String name, Object object) Object get. Attribute(String name) (!) potrzebne rzutowanie void remove. Attribute(String name) • W przypadku aplikacji rozproszonej, działającej na kilku komputerach (maszynach wirtualnych), kontekstów jest wiele, więc nie można użyć ich do przechowywania dzielonej informacji – trzeba użyć innego mechanizmu, np. bazy danych
Zdarzenia cyklu życia serwletu • Architektura serwletów przewiduje także możliwość monitorowania i reagowania na zdarzenia związane z cyklem życia serwletu (zdarzenia dotyczące aplikacji lub sesji), poprzez zdefiniowanie obiektów nasłuchujących (listeners) • W tym celu wystarczy utworzyć klasę implementującą odpowiedni interfejs (Servlet. Context. Listener, Servlet. Context. Attribute. Listener, Http. Session. Listener lub Http. Session. Attribute. Listener) oraz powiązać ją z odpowiednią sekcją w pliku web. xml
Interfejsy zdarzeń serwletu Zasięg Kontekst aplikacji Sesja Zdarzenie Inicjalizacja, destrukcja Interfejs nasłuchujący oraz klasa zdarzenia Servlet. Context. Listener Servlet. Context. Event Dodano, zmieniono Servlet. Context. Attribute. Listener lub usunięto atrybut Servlet. Context. Attribute. Event Utworzenie, unieważnienie, przeterminowanie Http. Session. Listener Http. Session. Event Dodano, zmieniono Http. Session. Attribute. Listener lub usunięto atrybut Http. Session. Binding. Event
Sesje w serwletach HTTP • Sesje są reprezentowane przez obiekty Http. Session • Dostęp do sesji odbywa się przez wywołanie metody obiektu żądania: request. get. Session() – zwraca ona obiekt sesji związany z żądaniem lub tworzy nową sesję, jeśli żądanie ma jeszcze obiektu sesji • Użycie sesji może spowodować wysłanie nagłówka HTTP, więc obiekt sesji musi być odczytany przed uzyskaniem obiektu strumienia Print. Writer • Obiekt sesji służy głównie do przechowywania par atrybut-wartość, wykorzystuje się tu metody set. Attribute() oraz get. Attribute()
Zarządzanie sesjami • Stworzenie sesji, jej modyfikacje, unieważnienie, czy przeterminowanie (timeout) generują zdarzenia, na które może reagować obiekt nasłuchujący (np. wykonując odczyt lub zapis do bazy danych) • Mechanizm sesji przechowuje wszystkich informacje związane z sesją na serwerze, zaś do użytkownika wysyłany jest jedynie identyfikator sesji w postaci ciasteczka (cookie) • Aby radzić sobie z sytuacją, gdy użytkownik wyłączy ciasteczka lub ich nie obsługuje, należy używać metody response. encode. URL() – która w takim przypadku dopisuje identyfikator sesji do adresu
Dostęp współbieżny do zasobów dzielonych • Dobrym sposobem na dzielenie informacji pomiędzy wieloma serwletami jednej aplikacji jest utworzenie dodatkowej klasy (klasy zasobów), która będzie przechowywać dane i udostępniać metody do ich odczytu i modyfikacji – obiekt tej klasy można udostępnić w kontekście aplikacji (Servlet. Context) • Powstaje jednak problem, gdy wiele serwletów (lub wątków) chce równocześnie modyfikować dane • Jednym z rozwiązań jest opatrzenie metod klasy zasobów modyfikatorem synchronized
- Slides: 17