Aplikacje internetowe i rozproszone - laboratorium Enterprise JavaBeans (EJB) Celem tego zestawu ćwiczeń jest zapoznanie z technologią EJB w wersji 3.0, a w szczególności: implementacja komponentów sesyjnych, ilustracja różnic między stanowymi i bezstanowymi sesyjnymi komponentami EJB oraz tworzenie klientów dla sesyjnych komponentów EJB. Ćwiczenia zostały przygotowane dla środowiska Oracle JDeveloper 10.1.3.0.4 (do pobrania ze strony: http://www.oracle.com/ ). Autorzy ćwiczeń: Mariusz Masewicz, Marek Wojciechowski Ćwiczenie 1 W tym ćwiczeniu zostanie utworzona aplikacja i projekt w środowisku JDeveloper. Po uruchomieniu programu Oracle JDeveloper należy utworzyć nową aplikację. W tym celu należy wybrać opcję: File -> New W wyświetlonym oknie należy zaznaczyć chęć utworzenia nowej aplikacji (wygląd okna może się różnić od poniższego):
Następny ekran pozwala na ustawienie właściwości tworzonej aplikacji. Należy wprowadzić: nazwę aplikacji, nazwę katalogu, w którym znajdą się jej pliki, prefiks dla pakietów tworzonych w ramach tej aplikacji i wybrać aplikację bez wzorca Kolejnym krokiem jest stworzenie projektu w ramach aplikacji należy wprowadzić nazwę projektu: stateless
Ćwiczenie 2 Ćwiczenie będzie polegało na wygenerowaniu szkieletu sesyjnego bezstanowego komponentu EJB i analizie jego kodu. W nawigatorze aplikacji należy zaznaczyć utworzony w poprzednim ćwiczeniu projekt Następnie należy wybrać opcję: File -> New lub z menu kontekstowego wybrać opcję New W wyświetlonym oknie należy wybrać chęć utworzenia sesyjnego EJB
W wyświetlonym kreatorze należy ustawić odpowiednie parametry (wersja specyfikacji: EJB 3.0) Należy określić nazwę i typ dla tworzonego komponentu: bezstanowy z transakcjami zarządzanymi przez kontener
Następnie należy określić nazwę klasy komponentu W ostatnim kroku należy określić typy i nazwy implementowanych interfejsów (dla potrzeb tego ćwiczenia zaznaczymy zarówno interfejs zdalny jak i lokalny, choć zazwyczaj w praktyce komponent implementuje tylko jeden z tych interfejsów) Należy przeanalizować wygenerowany kod i zwróć uwagę na wykorzystane adnotacje
W klasie komponentu zadeklaruj zmienną: int counter; A następnie zdefiniuj metodę o następującej specyfikacji: public int count() zwraca wartość: counter++ package ejb1; import javax.ejb.stateless; @Stateless(name="StatelessEJB") public class StatelessEJBBean implements StatelessEJB, StatelessEJBLocal { int counter = 0; public StatelessEJBBean() { public int count() { return counter++; Korzystając z panelu struktury udostępnij metodę count() klientom zdalnym i lokalnym poprzez odpowiednie interfejsy:
Po wykonaniu poprzednich czynności podejrzyj kod interfejsów komponentu zmodyfikowanych przez kreator Uruchom utworzony komponent wewnątrz wbudowanego serwera aplikacji OC4J (opcja: Run) i przeanalizuj wyświetlane komunikaty Utwórz kreatorem przykładową aplikację klienta sesyjnego komponentu EJB. W oknie kreatora pozostaw domyślne ustawienia.
Analiza wygenerowanego kodu powinna pomóc zrozumieć sposób wykorzystywania komponentów EJB przez aplikacje (w tym wypadku została wygenerowana aplikacja konsolowa). Należy wskazać w wygenerowanym kodzie fragmenty odpowiedzialne za utworzenie instancji komponentu, oraz wywołania jego metod. Zmodyfikuj wygenerowany kod klienta, tak aby metoda count() komponentu była wywoływana 5 razy w odstępach sekundowych:...... System.out.println( statelessejb.count( ) ); Thread.sleep(1000); System.out.println( statelessejb.count( ) ); Thread.sleep(1000); System.out.println( statelessejb.count( ) ); Thread.sleep(1000); System.out.println( statelessejb.count( ) ); Thread.sleep(1000); System.out.println( statelessejb.count( ) ); Następnie należy uruchomić przykładową aplikację i przeanalizować jej wyniki. Na koniec należy uruchomić kilka procesów przykładowej aplikacji, aby w ten sposób zasymulować zachowanie komponentu w środowisku rzeczywistego serwera aplikacji, gdzie bardzo często wielu użytkowników równocześnie korzysta z tych samych komponentów. Ćwiczenie 3 W tym ćwiczeniu należy utworzyć stanowy sesyjny komponent EJB, zaimplementować w nim taką samą funkcjonalność jak w bezstanowym komponencie z poprzedniego ćwiczenia, wygenerować przykładową aplikację i porównać wyniki jej działania z wynikami aplikacji z poprzedniego ćwiczenia. Pracę należy rozpocząć od utworzenia nowego projektu w ramach tworzonej w tym ćwiczeniu aplikacji. Projektowi należy nadać nazwę stateful
W ramach projektu należy utworzyć stanowy sesyjny komponent EJB Następnie należy wykonać dokładnie te same kroki, co w poprzednim ćwiczeniu. Po kilkukrotnym uruchomieniu przykładowej aplikacji należy porównać jej wyniki z wynikami zwracanymi przez aplikację z poprzedniego ćwiczenia Należy też zasymulować równoległą pracę kilku użytkowników przykładowej aplikacji. Ćwiczenie 4 Celem ćwiczenia jest utworzenie serwletu - klienta sesyjnego bezstanowego komponentu EJB. Utwórz nowy projekt o nazwie web We właściwościach projektu wskaż projekty stateful i stateless jako wykorzystywane przez projekt web
Następnie w projekcie web należy wybrać opcję: File -> New, lub z menu kontekstowego wybrać opcję New W wyświetlonym oknie należy wybrać chęć utworzenia serwletu
Należy określić nazwę i typ dla tworzonego serwletu (można pozostawić proponowaną przez system). Implementowana będzie tylko metoda doget() Do utworzonej klasy serwletu należy zaimportować pakiet import javax.naming.initialcontext;
Następnie wewnątrz metody doget() utworzonego serwletu należy dodać poniższy kod (zaimportuj klasy Context i StatelessEJB) public void doget(httpservletrequest request, HttpServletResponse response) throws ServletException, IOException { response.setcontenttype(content_type); PrintWriter out = response.getwriter(); out.println("<html>"); out.println("<head><title>klient bezstanowego"); out.println("</title></head>"); out.println("<body>"); try { final Context context = new InitialContext(); StatelessEJB statelessejb = (StatelessEJB)context.lookup("StatelessEJB"); out.println(statelessejb.count()); catch (Exception ex) { ex.printstacktrace(); out.println("</body></html>"); out.close(); Uruchom serwlet. Odśwież kilka razy stronę w przeglądarce. Ćwiczenie 5 Celem ćwiczenia jest modyfikacja serwletu, tak aby komunikował się z komponentem EJB poprzez interfejs lokalny komponentu. Przejdź do edycji pliku web.xml w trybie okna dialogowego (menu kontekstowe Properties) Przejdź do sekcji EJB Local References i kliknij przycisk Add Dodaj referencję na lokalny EJB podając poniższe dane:
...... <ejb-local-ref> <ejb-ref-name>ejb/stateless</ejb-ref-name> <ejb-ref-type>session</ejb-ref-type> <local>ejb1.statelessejblocal</local> <ejb-link>statelessejb</ejb-link> </ejb-local-ref> W kodzie serwletu zmodyfikuj instrukcję realizującą wyszukanie komponentu EJB w JNDI (zwróć uwagę na prefiks java:comp/env pojawiający się przy odwołaniach do referencji zdefiniowanych w pliku web.xml): StatelessEJBLocal statelessejb = (StatelessEJBLocal)context.lookup("java:comp/env/ejb/stateless"); Uruchom serwlet w dwóch różnych sesjach HTTP (np. odwołując się do niego z dwóch różnych przeglądarek) i w każdej sesji odśwież stronę kilka razy. Ćwiczenie 6 Celem ćwiczenia jest utworzenie serwletu klienta stanowego sesyjnego komponentu EJB, komunikującego się z komponentem EJB poprzez interfejs lokalny komponentu. Przejdź do edycji pliku web.xml i zdefiniuj referencję lokalną na komponent stanowy (popraw nazwę pakietu jeśli jest w twojej aplikacji inna niż ejb1)
...... <ejb-local-ref> <ejb-ref-name>ejb/stateful</ejb-ref-name> <ejb-ref-type>session</ejb-ref-type> <local>ejb1.statefulejblocal</local> <ejb-link>statefulejb</ejb-link> </ejb-local-ref> W projekcie web utwórz drugi serwlet. W jego metodzie doget() umieść poniższy kod odwołujący się do stanowego EJB (analogiczny do kodu pierwszego serwletu): public void doget(httpservletrequest request, HttpServletResponse response) throws ServletException, IOException { response.setcontenttype(content_type); PrintWriter out = response.getwriter(); out.println("<html>"); out.println("<head><title>klient stanowego"); out.println("</title></head>"); out.println("<body>"); try { final Context context = new InitialContext(); StatefulEJBLocal statefulejb = (StatefulEJBLocal)context.lookup("java:comp/env/ejb/stateful"); out.println(statefulejb.count()); catch (Exception ex) { ex.printstacktrace(); out.println("</body></html>"); out.close(); Uruchom serwlet. Odśwież kilka razy stronę w przeglądarce. Spróbuj wyjaśnić dlaczego licznik nie zwiększa swojej wartości. Zmodyfikuj metodę doget() drugiego serwletu, tak aby referencja do stanowego sesyjnego komponentu EJB była przechowywana w sesji: public void doget(httpservletrequest request, HttpServletResponse response) throws ServletException, IOException { response.setcontenttype(content_type); HttpSession s = request.getsession(true); PrintWriter out = response.getwriter(); out.println("<html>"); out.println("<head><title>klient stanowego ");
out.println("</title></head>"); out.println("<body>"); StatefulEJBLocal statefulejb = (StatefulEJBLocal)s.getAttribute("licznik"); if (statefulejb == null) { try { final Context context = new InitialContext(); statefulejb = (StatefulEJBLocal)context.lookup("java:comp/env/ejb/stateful"); s.setattribute("licznik", statefulejb); catch (Exception ex) { ex.printstacktrace(); out.println(statefulejb.count()); out.println("</body></html>"); out.close(); Uruchom drugi serwlet w dwóch różnych sesjach HTTP (np. odwołując się do niego z dwóch różnych przeglądarek) i w każdej sesji odśwież stronę kilka razy.