Cyfroteka.pl

klikaj i czytaj online

Cyfro
Czytomierz
00401 005963 13642164 na godz. na dobę w sumie
Java EE 6. Programowanie aplikacji WWW - książka
Java EE 6. Programowanie aplikacji WWW - książka
Autor: Liczba stron: 232
Wydawca: Helion Język publikacji: polski
ISBN: 978-83-246-2659-5 Data wydania:
Lektor:
Kategoria: ebooki >> komputery i informatyka >> programowanie >> j2ee - programowanie
Porównaj ceny (książka, ebook, audiobook).

Już dziś sięgnij po jedyne kompendium wiedzy
na temat Java EE!

Java Enterprise Edition to standard tworzenia aplikacji biznesowych wykorzystujących język Java. Opracowany przez firmę Sun Microsystems, działa w oparciu o wielowarstwową architekturę komponentową, oferując programistom bardzo rozbudowane możliwości tworzenia oprogramowania funkcjonującego na niemal dowolnym sprzęcie, w każdym systemie operacyjnym, z wykorzystaniem licznych serwerów aplikacji. Duża popularność rozwiązań Java EE i coraz powszechniejszy dostęp do technologii WWW sprawiają, że programiści sprawnie posługujący się tego rodzaju narzędziami rzadko figurują na listach osób poszukujących pracy, a jeśli już jakimś cudem się na nich znajdą, bardzo szybko otrzymują atrakcyjne propozycje zatrudnienia. Nauka swobodnego poruszania się w tym środowisku może też być wspaniałą, poszerzającą horyzonty przygodą, a gdy poznasz platformę Java EE, będziesz dysponował potężnym narzędziem, ułatwiającym tworzenie nawet najbardziej skomplikowanych aplikacji internetowych w bardzo efektywny i szybki sposób.

Studenci, programiści i hobbyści pragnący poznać środowisko Java Enterprise Edition często napotykają problem ze znalezieniem solidnych źródeł wiedzy, które pozwoliłyby im szybko i łatwo wejść w świat tej coraz bardziej popularnej technologii. Lukę tę z powodzeniem wypełnia książka 'Java EE 6. Programowanie aplikacji WWW '.

Dzięki niej wszyscy zainteresowani tematem zyskają możliwość poznania Java EE od podstaw i zdobycia praktycznej wiedzy, na podstawie której będą mogli rozwijać swoje umiejętności programistyczne w przyszłości. Ten podręcznik pozwala na szybkie rozpoczęcie przygody z tworzeniem aplikacji webowych, skutecznie wprowadzając w zagadnienia wykorzystywanych przy tym platform i mechanizmów, lecz nie pomijając też informacji o charakterze ogólnym. Jeśli niewiele mówią Ci skróty JSP, JPA, JSF czy JPQL, a chciałbyś zmienić ten stan rzeczy, bez wątpienia powinieneś sięgnąć po tę książkę, podobnie jak wszystkie osoby zainteresowane bezproblemowym używaniem całego spektrum nowoczesnych narzędzi oferowanych przez środowisko Java EE.

Spraw, aby tworzenie aplikacji WWW z wykorzystaniem Java EE
nie miało przed Tobą tajemnic.

Znajdź podobne książki Ostatnio czytane w tej kategorii

Darmowy fragment publikacji:

Java Enterprise Edition to standard tworzenia aplikacji biznesowych wykorzystujących język Java. Opracowany przez fi rmę Sun Microsystems, działa w oparciu o wielowarstwową architekturę komponentową, oferując pro- gramistom bardzo rozbudowane możliwości tworzenia oprogramowania funkcjonującego na niemal dowolnym sprzęcie, w każdym systemie operacyjnym, z wykorzystaniem licznych serwerów aplikacji. Duża popularność rozwiązań Java EE i coraz powszechniejszy dostęp do technologii WWW sprawiają, że programiści sprawnie posługujący się tego rodzaju narzędziami rzadko fi gurują na listach osób poszukujących pracy, a jeśli już jakimś cudem się na nich znajdą, bardzo szybko otrzymują atrakcyjne propozycje zatrudnienia. Nauka swobodnego poru- szania się w tym środowisku może też być wspaniałą, poszerzającą horyzonty przygodą, a gdy poznasz platformę Java EE, będziesz dysponował potężnym narzędziem, ułatwiającym tworzenie nawet najbardziej skomplikowa- nych aplikacji internetowych w bardzo efektywny i szybki sposób. Studenci, programiści i hobbyści pragnący poznać środowisko Java Enterprise Edition często napotykają problem ze znalezieniem solidnych źródeł wiedzy, które pozwoliłyby im szybko i łatwo wejść w świat tej coraz bardziej popularnej technologii. Lukę tę z powodzeniem wypełnia książka „Java EE 6. Programowanie aplikacji WWW”. Dzięki niej wszyscy zainteresowani tematem zyskają możliwość poznania Java EE od podstaw i zdobycia prak- tycznej wiedzy, na podstawie której będą mogli rozwij ać swoje umiejętności programistyczne w przyszłości. Ten podręcznik pozwala na szybkie rozpoczęcie przygody z tworzeniem aplikacji webowych, skutecznie wprowadzając w zagadnienia wykorzystywanych przy tym platform i mechanizmów, lecz nie pomij ając też informacji o charak- terze ogólnym. Jeśli niewiele mówią Ci skróty JSP, JPA, JSF czy JPQL, a chciałbyś zmienić ten stan rzeczy, bez wątpienia powinieneś sięgnąć po tę książkę, podobnie jak wszystkie osoby zainteresowane bezproblemowym używaniem całego spektrum nowoczesnych narzędzi oferowanych przez środowisko Java EE. Tworzenie serwletów Zastosowanie szablonów JSP Integracja danych z aplikacjami za pomocą mechanizmu JPA Używanie interfejsów i komponentów Korzystanie z technologii JSF Uniwersalny i wygodny dostęp do danych, czyli język JPQL Praktyczne przykłady realizacji SPRAW, ABY TWORZENIE APLIKACJI WWW Z WYKORZYSTANIEM JAVA EE NIE MIAŁO PRZED TOBĄ TAJEMNIC. 37,00 zł 5 6 1 5 Krzysztof Rychlicki-Kicior K r z y s z t o f R y c h l i c k i - K c o r i i J a v a E E 6 P r o g r a m o w a n e a p i l i k a c j i W W W Java EE 6 Programowanie aplikacji WWW Szybko i bez kłopotów poznaj Java Enterprise Edition Naucz się praktycznie tworzyć ciekawe aplikacje WWW Dołącz do elity programistów nowoczesnych rozwiązań webowych Już dziś sięgnij po jedyne kompendium wiedzy na temat Java EE! Java EE 6. Programowanie aplikacji WWW Autor: Krzysztof Rychlicki-Kicior ISBN: 978-83-246-2659-5 Format: 158×235, stron: 232 (cid:127) Szybko i bez k³opotów poznaj Java Enterprise Edition (cid:129) Naucz siê praktycznie tworzyæ ciekawe aplikacje WWW (cid:129) Do³¹cz do elity programistów nowoczesnych rozwi¹zañ webowych Ju¿ dziœ siêgnij po jedyne kompendium wiedzy na temat Java EE! Java Enterprise Edition to standard tworzenia aplikacji biznesowych wykorzystuj¹cych jêzyk Java. Opracowany przez firmê Sun Microsystems, dzia³a w oparciu o wielowarstwow¹ architekturê komponentow¹, oferuj¹c programistom bardzo rozbudowane mo¿liwoœci tworzenia oprogramowania funkcjonuj¹cego na niemal dowolnym sprzêcie, w ka¿dym systemie operacyjnym, z wykorzystaniem licznych serwerów aplikacji. Du¿a popularnoœæ rozwi¹zañ Java EE i coraz powszechniejszy dostêp do technologii WWW sprawiaj¹, ¿e programiœci sprawnie pos³uguj¹cy siê tego rodzaju narzêdziami rzadko figuruj¹ na listach osób poszukuj¹cych pracy, a jeœli ju¿ jakimœ cudem siê na nich znajd¹, bardzo szybko otrzymuj¹ atrakcyjne propozycje zatrudnienia. Nauka swobodnego poruszania siê w tym œrodowisku mo¿e te¿ byæ wspania³¹, poszerzaj¹c¹ horyzonty przygod¹, a gdy poznasz platformê Java EE, bêdziesz dysponowa³ potê¿nym narzêdziem, u³atwiaj¹cym tworzenie nawet najbardziej skomplikowanych aplikacji internetowych w bardzo efektywny i szybki sposób. Studenci, programiœci i hobbyœci pragn¹cy poznaæ œrodowisko Java Enterprise Edition czêsto napotykaj¹ problem ze znalezieniem solidnych Ÿróde³ wiedzy, które pozwoli³yby im szybko i ³atwo wejœæ w œwiat tej coraz bardziej popularnej technologii. Lukê tê z powodzeniem wype³nia ksi¹¿ka „Java EE 6. Programowanie aplikacji WWW”. Dziêki niej wszyscy zainteresowani tematem zyskaj¹ mo¿liwoœæ poznania Java EE od podstaw i zdobycia praktycznej wiedzy, na podstawie której bêd¹ mogli rozwijaæ swoje umiejêtnoœci programistyczne w przysz³oœci. Ten podrêcznik pozwala na szybkie rozpoczêcie przygody z tworzeniem aplikacji webowych, skutecznie wprowadzaj¹c w zagadnienia wykorzystywanych przy tym platform i mechanizmów, lecz nie pomijaj¹c te¿ informacji o charakterze ogólnym. Jeœli niewiele mówi¹ Ci skróty JSP, JPA, JSF czy JPQL, a chcia³byœ zmieniæ ten stan rzeczy, bez w¹tpienia powinieneœ siêgn¹æ po tê ksi¹¿kê, podobnie jak wszystkie osoby zainteresowane bezproblemowym u¿ywaniem ca³ego spektrum nowoczesnych narzêdzi oferowanych przez œrodowisko Java EE. (cid:129) Tworzenie serwletów (cid:129) Zastosowanie szablonów JSP (cid:129) Integracja danych z aplikacjami za pomoc¹ mechanizmu JPA (cid:129) U¿ywanie interfejsów i komponentów (cid:129) Korzystanie z technologii JSF (cid:129) Uniwersalny i wygodny dostêp do danych, czyli jêzyk JPQL (cid:129) Praktyczne przyk³ady realizacji Spraw, aby tworzenie aplikacji WWW z wykorzystaniem Java EE nie mia³o przed Tob¹ tajemnic Spis treści Część I Podstawy ....................................................................... 7 Rozdział 1. Java EE — naprawdę krótkie wprowadzenie ...................................... 9 Web vs Enterprise ........................................................................................................... 10 Serwery aplikacji ............................................................................................................ 11 Streszczenie, czyli krótki przewodnik po niniejszej publikacji ...................................... 11 Serwlety — na dobry początek ................................................................................. 11 Deskryptor wdrożenia .............................................................................................. 12 JSP — HTML + Java ............................................................................................... 13 JPA — czas na dane! ................................................................................................ 13 JSF — wyższy poziom prezentacji ........................................................................... 13 Facelets ..................................................................................................................... 14 Rozdział 2. Pierwsza aplikacja webowa ............................................................ 15 Integrowanie Tomcata z Netbeansem ............................................................................. 16 Pierwsza aplikacja .......................................................................................................... 17 Dodawanie nowych elementów ...................................................................................... 18 Pierwszy serwlet? ........................................................................................................... 20 Rozdział 3. Serwlet — na dobry początek ......................................................... 25 Życie serwletu ................................................................................................................ 25 Serwlet pod lupą ............................................................................................................. 26 Żądanie — odpowiedź .................................................................................................... 27 Przesyłanie odpowiedzi ............................................................................................ 29 Om nom nom, czyli ciasteczka w pełnej krasie ........................................................ 31 Sesje — nie tylko dla studentów .............................................................................. 31 Konfiguracja w kodzie Javy — można tego uniknąć ...................................................... 33 Parametry serwletów ................................................................................................ 34 Kontekst serwletów .................................................................................................. 35 Trzech muszkieterów? .................................................................................................... 36 Atrybuty a mnogość żądań ....................................................................................... 36 Słuchowisko ................................................................................................................... 39 ServletContextListener ............................................................................................. 39 ServletContextAttributeListener ............................................................................... 39 ServletRequestAttributeListener i ServletRequestListener ....................................... 39 HttpSessionAtributteListener i HttpSessionListener ................................................ 40 4 Java EE 6. Programowanie aplikacji WWW HttpSessionBindingListener ..................................................................................... 40 Sesja + wiele JVM = HttpSessionActivationListener ............................................... 40 Filtry ............................................................................................................................... 41 Techniczny aspekt filtrów ........................................................................................ 41 Konfiguracja filtrów w pliku web.xml ..................................................................... 42 Rozdział 4. JSP — gdy out.println() nie wystarcza ............................................. 45 Zacznijmy od początku, czyli JSP w świecie serwletów ................................................ 46 Pliki JSP dostępne bezpośrednio .............................................................................. 46 Pliki JSP wywoływane z poziomu serwletów .......................................................... 46 Pochodzenie JSP — dziedzictwo serwletów .................................................................. 47 Pierwsze kroki w JSP ..................................................................................................... 47 Docenić wygodę, czyli jak to lat temu kilka bywało… ............................................ 50 Expression Language — elegancja i wygoda ................................................................. 54 Remedium — warto było czekać! ............................................................................ 55 Dostęp do obiektów w języku EL ............................................................................. 56 Beany, czyli ziarna — kult kawy wiecznie żywy ..................................................... 57 Ziarna + EL = kolejne ułatwienie ............................................................................. 58 Ziarna, mapy i co dalej? ........................................................................................... 59 EL — nie tylko atrybuty ........................................................................................... 59 Akcje JSP ....................................................................................................................... 61 Include vs Forward — odsłona druga ....................................................................... 62 Akcje + ziarna = kolejne potężne narzędzie ............................................................. 63 Dynamiczne generowanie elementów ...................................................................... 66 Rozdział 5. JSTL — wisienka na torcie JSP ....................................................... 69 Skrzynka z narzędziami .................................................................................................. 69 Rdzeń .............................................................................................................................. 70 c:out .......................................................................................................................... 70 Ale to już było, czyli c:set ........................................................................................ 72 Czwarty muszkieter .................................................................................................. 73 Kontrola sterowania ................................................................................................. 73 Pętelka do kompletu ................................................................................................. 75 Wyjątki + JSP = … .................................................................................................. 76 Adresy URL — same kłopoty ........................................................................................ 77 Adresy URL bez tajemnic ........................................................................................ 77 Tajemnica sesji… ..................................................................................................... 78 Trzech tenorów ............................................................................................................... 79 Na deser — funkcje! ....................................................................................................... 80 Przez kolekcje do serca ............................................................................................ 80 Funkcje łańcuchowe ................................................................................................. 81 Podsumowanie ................................................................................................................ 82 Część II Frameworki webowe ..................................................... 83 Rozdział 6. JavaServer Faces ........................................................................... 85 Frameworki — kolejny dowód na lenistwo człowieka ................................................... 85 JSF — kanonu ciąg dalszy .............................................................................................. 86 JSF, czyli MVC w praktyce ...................................................................................... 87 Kontroler — uniwersalny spawacz ........................................................................... 88 Małe zanurzenie .............................................................................................................. 88 Pierwsze przykłady .................................................................................................. 89 Aplikacja Notowania giełdowe ....................................................................................... 90 Tajemniczy zapis — # vs $ ...................................................................................... 95 Notowania historyczne, czyli kolekcja w kolekcji ................................................... 97 Spis treści 5 Najpierw szablon, później treść ................................................................................ 98 Klient szablonu ......................................................................................................... 99 Przygotowania… .................................................................................................... 100 Czas na obliczenia! ................................................................................................. 103 Mały zastrzyk ......................................................................................................... 105 JSF — komponenty, komponenty, komponenty! ......................................................... 106 Output — (prawie) wszystko, czego do szczęścia potrzeba ................................... 107 UIInput — teraz do szczęścia nie brakuje już nic ................................................... 108 Powrót do szarej rzeczywistości… ......................................................................... 112 Zasady działania JSF .................................................................................................... 115 Przykładowa aplikacja — maszyna licząca ............................................................ 115 Przywrócenie widoku (1) ....................................................................................... 118 Pobranie danych z żądania (2) ................................................................................ 119 Walidacja (3) .......................................................................................................... 119 Aktualizacja wartości w modelu (ziarnach — 4) .................................................... 120 Wywołanie zadeklarowanych uprzednio metod (5) ............................................... 120 Renderowanie odpowiedzi (6) ................................................................................ 120 Cykl życia w praktyce .................................................................................................. 120 Podsumowanie .............................................................................................................. 121 Rozdział 7. Konwertowanie i walidacja ........................................................... 123 Uroki transformacji ...................................................................................................... 123 Konwertery standardowe ........................................................................................ 124 Piszemy konwerter! ................................................................................................ 126 Walidator — nieodłączny partner konwertera .............................................................. 130 Walidatory — prawie jak konwertery .................................................................... 131 Walidacja niestandardowa — jak zawsze więcej pracy .......................................... 132 Część III Obsługa danych .......................................................... 135 Rozdział 8. JPA, czyli ORM + Java .................................................................. 137 Dostęp do danych w Javie ............................................................................................ 137 Oświecenie ............................................................................................................. 138 Pierwszy przykład ........................................................................................................ 139 Założenia ................................................................................................................ 139 Realizacja ............................................................................................................... 139 Tworzenie projektu ................................................................................................ 140 Hibernate a JPA — co i jak w ORM-owym świecie .............................................. 141 Pierwsza klasa encji ............................................................................................... 141 Jednostka utrwalania .............................................................................................. 145 Graficzna strona aplikacji ....................................................................................... 146 Dodawanie przychodni ........................................................................................... 150 EntityManager i spółka… ...................................................................................... 152 Menedżer encji — elegancki dostęp != łatwa sprawa ............................................ 153 Nudni słuchacze — nareszcie przydatni! ............................................................... 156 C już jest, czas na RUD .......................................................................................... 158 Niewiele Ci mogę dać… (póki nie pozwolisz mi zaprezentować danych) ............. 158 Słuchacz akcji vs akcja — starcie numer 2 ............................................................. 160 Istotny drobiazg — nasza aplikacja to niemowa! ................................................... 162 Rozdział 9. Związki między encjami — jedna tabela to za mało! ...................... 165 Przychodnia… i co dalej? ............................................................................................. 165 Związki między tabelami — krótkie przypomnienie .............................................. 165 Związki SQL w praktyce ........................................................................................ 166 Jeden do wielu, wiele do jednego ........................................................................... 167 6 Java EE 6. Programowanie aplikacji WWW Wiele do wielu — najwyższy stopień wtajemniczenia ........................................... 167 Dodajemy tabele do bazy ....................................................................................... 168 Encje klas Javy — czas na związki! ............................................................................. 170 Encja Przychodnia — zmiana na lepszy model ...................................................... 171 Czas na nowości! .................................................................................................... 172 Wizyta — encja JPA w pełnej krasie ..................................................................... 178 CRUD dla lekarza — to już było, ale nie do końca ...................................................... 183 Nowy lekarz — nowe pole, duża zmiana ............................................................... 184 Magikonwersja ....................................................................................................... 185 Ziarnko do ziarnka i zbierze się aplikacja .............................................................. 186 Kolejne metody ziarna LekarzBean… .................................................................... 188 Na zakończenie — edycja ...................................................................................... 189 Pacjenci — suplement ............................................................................................ 191 Danie główne: all in one, czyli wizyty! ........................................................................ 192 Od czegoś trzeba zacząć, czyli zmiany ................................................................... 193 Dodawanie wizyty .................................................................................................. 196 Ostatnie ziarno ....................................................................................................... 197 Edycja i usuwanie — powrót ................................................................................. 200 Koniec coraz bliżej, czyli edycja w pełnej krasie ................................................... 201 Podsumowanie .............................................................................................................. 202 Rozdział 10. JPQL i jego możliwości ................................................................. 203 Prawie jak SQL… „prawie” robi różnicę ..................................................................... 203 Podstawy ...................................................................................................................... 204 Pobieranie z wariantami ......................................................................................... 204 JPQL a atrybuty złożone i null ............................................................................... 206 Nieco więcej o SELECT ........................................................................................ 207 Funkcje obliczeniowe ............................................................................................. 208 Operacje niezwiązane z pobieraniem ..................................................................... 209 Mechanizmy zaawansowane ........................................................................................ 209 JOIN na lewo, JOIN na prawo… ............................................................................ 210 Grupowanie i sortowanie ........................................................................................ 211 Podzapytania — prawdziwa moc ........................................................................... 212 Podsumowanie .............................................................................................................. 213 Dodatki ..................................................................................... 215 Dodatek A Instalacja serwera Apache Tomcat ............................................... 217 Pobranie ........................................................................................................................ 217 Konfiguracja ................................................................................................................. 217 Dodatek B Bibliografia .................................................................................. 219 Skorowidz ....................................................................................................... 221 Rozdział 3. Serwlet — na dobry początek Aplikacja z poprzedniego rozdziału wprowadziła kilka istotnych elementów, których omawianiem zajmiemy się w przeciągu najbliższych trzech rozdziałów. Rozpocznie- my od podstawy podstaw, czyli elementu, który jest wykorzystywany pośrednio lub bezpośrednio we wszystkich aplikacjach webowych — mowa o serwlecie. Serwlet, czyli klasa rozszerzająca możliwości serwera aplikacji, może być traktowany jako pojęcie niesłychanie ogólne. Praktycznie jedynym istotnym wymaganiem sta- wianym serwletom jest działanie w trybie żądanie — odpowiedź — serwlet powinien generować treść odpowiedzi w oparciu o to, co otrzyma w żądaniu. W poprzednim rozdziale spotkałeś się z jednym z typowych zastosowań serwletów — generowaniem kodu HTML. Nie jest to jednak w żadnym razie kres ich możliwości — nic nie stoi na przeszkodzie, aby za pomocą serwletów generować zarówno dane tekstowe (np. w formacie XML), jak i dane binarne (np. pliki wykonywalne, obrazy, etc.). Zanim jednak zabierzemy się za praktyczne przykłady (pierwszy z nich mogłeś przeanali- zować w poprzednim rozdziale), konieczne jest krótkie wprowadzenie teoretyczne, w którym dowiesz się, jak serwlet współpracuje z serwerem aplikacji, a także jakie podstawowe opcje związane z serwletami można ustawić w pliku web.xml. Życie serwletu Gdy uruchamiasz zwykłą aplikację, graficzną lub konsolową, w swoim systemie ope- racyjnym, możesz w większości przypadków określić precyzyjnie, kiedy rozpoczyna się, a kiedy kończy jej działanie. W przypadku popularnych technologii dynamicznych stron internetowych (np. PHP) pliki są interpretowane na bieżąco (aczkolwiek istnieje możliwość ich pośredniej kompilacji). Jak można opisać cykl życia serwletu? Zacznijmy od klasy w takiej postaci, jaką już znamy — nieskompilowanego kodu źró- dłowego. Zanim serwer zostanie uruchomiony, wszystkie pliki klas muszą zostać pod- dane kompilacji. Powstałe pliki (o rozszerzeniu .class) są kopiowane do odpowiednich 26 Część I ♦ Podstawy katalogów. Dopiero wtedy serwer może być uruchomiony, na nowo lub ponownie. Na szczęście w nowszych wersjach serwerów aplikacji (np. Apache Tomcat 6) istnieje możliwość automatycznego wykrywania i aktualizacji klas w trakcie działania serwera. Gdy uruchamiasz serwer aplikacji, z punktu widzenia naszego serwletu nie dzieje się nic istotnego. Następuje wtedy, rzecz jasna, inicjalizacja samego serwera, a także nie- których ustawień całej aplikacji webowej. Sam serwlet pozostaje jednak nienaruszo- ny. Cała zabawa zaczyna się, gdy dowolny użytkownik Twojej aplikacji po raz pierw- szy spróbuje z niego skorzystać. Serwer wykonuje wtedy następujące czynności: (cid:141) załadowanie klasy serwletu, (cid:141) utworzenie instancji serwletu, (cid:141) wywołanie metody init(), (cid:141) wywołanie metody service(). Gdy serwlet znajdzie się w trakcie wywołania metody service(), może on rozpocząć normalną obsługę żądań. Od tego momentu w przypadku otrzymania przezeń dowol- nego żądania HTTP, nastąpi próba wywołania odpowiedniej metody serwletu, według schematu nazwa/doNazwa(), np. GET/doGet(), POST/doPost(), itd. Sporo pracy, nieprawdaż? Na szczęście do obowiązków programisty należy obsługa wybranych metod ze słowem do w nazwie. Jeśli więc chcesz, aby serwlet obsługiwał tylko żądanie GET, zadeklaruj jedynie metodę doGet(). W przypadku klasy serwletu utworzonej przez Netbeans, proces tworzenia serwletu został uproszczony jeszcze bardziej. Twórcy szablonu założyli (skądinąd słusznie), że znamienita większość programistów korzysta jedynie z metod HTTP GET i POST. Z tego względu w klasie serwletu są przesłaniane dwie metody — doGet() i doPost(), które odwołują się do jednej i tej samej metody — o nazwie processRequest(). Z jednej strony ułatwia to życie w większości sytuacji, z drugiej jednak mogą się zdarzyć sytu- acje, w których inaczej chcemy zareagować w przypadku żądania GET, a inaczej w przy- padku POST. W takiej sytuacji należy usunąć wygenerowany mechanizm i napisać wła- sne metody obsługi doGet() i/lub doPost(). Serwlet pod lupą Przed chwilą poznałeś przepływ sterowania w serwlecie; najwyższa pora, abyś zapo- znał się pokrótce z kluczowymi klasami powiązanymi z obsługą serwletów. Omówię jedynie najważniejsze elementy; warto je zapamiętać, ponieważ będą się one pojawiać także w dalszych przykładach, ilustrujących kolejne omawiane technologie. Jak już wspomniałem, serwlety, którymi zajmujemy się w niniejszej książce, dziedzi- czą po klasie HttpServlet. Ze względu na fakt, że serwlet z założenia jest konstrukcją niezwykle uniwersalną, w hierarchii dziedziczenia pojawiają się dodatkowe elementy, które ową uniwersalność wprowadzają. Oto krótki opis elementów hierarchii dziedzi- czenia, począwszy od tych najbardziej ogólnych: Rozdział 3. ♦ Serwlet — na dobry początek 27 (cid:141) Interfejs Servlet — określa najważniejsze metody, które muszą implementować wszystkie serwlety. Metody te są niezależne od stosowanych protokołów przesyłania danych, a dotyczą one głównie zarządzania cyklem życia serwletu (init(), service(), destroy()). (cid:141) Abstrakcyjna klasa GenericServlet — podstawowa implementacja interfejsów Servlet i ServletConfig, dająca dostęp do parametrów i ustawień serwletu. Klasa ta zawiera proste implementacje metod obu interfejsów, dzięki czemu stanowi podstawę dla klasy HttpServlet i wszystkich innych klas serwletów. (cid:141) Klasa HttpServlet — to właśnie po tej klasie będziesz dziedziczył, tworząc własne serwlety. Poza własnymi implementacjami metod ze wspomnianych wcześniej interfejsów, klasa HttpServlet udostępnia metody do*, czyli doGet(), doPost() etc. Dzięki temu we własnych serwletach musisz zdefiniować jedynie te metody, które Twój serwlet zamierza obsługiwać. Protokół HTTP zawiera definicje ośmiu metod: GET, POST, PUT, HEAD, OPTIONS, TRACE, DELETE, CONNECT. Serwlety mogą obsługiwać wszystkie metody, na wyżej omówionej zasadzie. W praktyce zdecydowanie najczęściej stosuje się metody GET i POST i to na nich skupimy się w dalszej części tego rozdziału. Żądanie — odpowiedź Mimo niewątpliwie istotnej roli klasy HttpServlet, w trakcie pracy z serwletami czę- ściej przyjdzie Ci zapewne korzystać z interfejsów HttpServletRequest/HttpServlet (cid:180)Response. Reprezentują one odpowiednio obiekty żądania i odpowiedzi, przekazy- wane do metod doGet(), doPost() etc. Pełny nagłówek metody doGet() wygląda na- stępująco: protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, java.io.IOException Twoim zadaniem jest takie zdefiniowanie metod do*, aby generowały one odpowiedź, zazwyczaj zależną od przesłanych parametrów. Wszystkie niezbędne metody znajdziesz w dwóch wyżej wspomnianych klasach. Zacznijmy od interfejsu HttpServletRequest — to na jego podstawie będziemy w kolejnych przykładach generować odpowiedzi przesyłane za pomocą interfejsu HttpServletResponse. Niemal wszystkie metody HttpServletRequest są faktycznie przydatne, niemniej w tym miejscu omówimy metody najistotniejsze z punktu widzenia samych serwletów: (cid:141) Object getParameter(String nazwa) — pobiera parametr o danej nazwie przesłany w żądaniu. (cid:141) Enumeration String getParameterNames() — pobiera nazwy wszystkich parametrów znajdujących się w danym żądaniu. (cid:141) String getRemoteUser() — zwraca login uwierzytelnionego użytkownika lub null, w przypadku braku uwierzytelnienia. 28 Część I ♦ Podstawy (cid:141) Cookie[] getCookies() — zwraca tablicę ciasteczek — specjalnych plików przechowywanych na komputerze użytkownika. (cid:141) String getQueryString() — zwraca łańcuch parametrów, przesłanych w adresie URL (za znakiem zapytania). (cid:141) String getHeader(String nazwa) — zwraca wartość nagłówka HTTP o podanej nazwie. (cid:141) int getIntHeader(String nazwa) — zwraca wartość nagłówka HTTP o podanej nazwie jako liczbę całkowitą. (cid:141) long getDateHeader(String nazwa) — zwraca wartość nagłówka HTTP o podanej nazwie jako liczbę milisekund, począwszy od początku epoki (1 stycznia 1970 roku). Wartość ta może być przekazana w konstruktorze klasy Date. (cid:141) String getContextPath() — zwraca ścieżkę kontekstu aplikacji. (cid:141) String getServletPath() — zwraca ścieżkę dostępu do serwletu. (cid:141) String getPathInfo() — zwraca dodatkowe informacje zawarte w ścieżce. Trzy ostatnie metody są ze sobą związane, ponieważ zwracają one kolejne elementy adresu URL, wykorzystanego do wykonania żądania. Przeanalizujmy poniższy przy- kład, prezentujący wiadomość o określonym identyfikatorze: http://localhost:8080/MojaAplikacja/serwlety/info/235/ Pomijamy oczywiście nazwę protokołu (http) i nazwę serwera z portem (localhost:8080). Zostaje nam więc ciąg: /MojaAplikacja/serwlety/info/235/ Metoda getContextPath() zwraca fragment adresu określający naszą aplikację: /MojaAplikacja Ścieżka do kontekstu zawsze zaczyna się od ukośnika (ale nigdy na nim się nie koń- czy!), chyba że aplikacja zostanie umieszczona w katalogu głównym serwera — wte- dy zwracana wartość to łańcuch pusty. Fragment ten jest wspólny dla wszystkich pli- ków wchodzących w skład tej aplikacji. Kolejny fragment adresu określa ścieżkę do serwletu. W naszym przypadku jest to fragment: /serwlety/info Powyższy łańcuch znaków musi pasować do odpowiednich wzorców, zdefiniowanych w deskryptorze wdrożenia (pamiętasz znacznik url-pattern z poprzedniego roz- działu?). Zasady określania odpowiednich ścieżek do serwletów omówimy w następ- nym rozdziale; na razie wystarczy Ci informacja, że ten fragment adresu umożliwia jednoznaczne zidentyfikowanie serwletu. Ostatni fragment ścieżki (/235/) zostanie zwrócony przez metodę getPathInfo(). Do- kładnie rzecz biorąc, metoda getPathInfo() zwraca fragment adresu URL od ścieżki serwletu do początku łańcucha parametrów (czyli do znaku zapytania). Oznacza to, że nawet dołączenie parametrów, tak jak w poniższym przykładzie, nie zmieni warto- ści ścieżki. http://localhost:8080/MojaAplikacja/serwlety/info/235?param=1 Rozdział 3. ♦ Serwlet — na dobry początek 29 Przesyłanie odpowiedzi Po przeanalizowaniu wszystkich możliwych atrybutów żądania musisz odesłać klien- towi odpowiedź. Do tego celu służy obiekt interfejsu HttpServletResponse. W jego przypadku otrzymujemy nieco mniejszy zestaw metod, jednak nie oznacza to wcale mniejszych możliwości. Przede wszystkim musimy określić, jakie operacje chcemy wykonywać w związku z przesyłaniem odpowiedzi do klienta: (cid:141) przesłanie odpowiedzi w postaci danych tekstowych lub binarnych, (cid:141) utworzenie i przesłanie ciasteczek, (cid:141) dodanie do odpowiedzi dowolnych nagłówków, (cid:141) przekierowanie żądania lub przesłanie kodu błędu. Transmisja danych Chociaż technologie internetowe mają swoją specyfikę, nie zapominajmy, że żyjemy w świecie Javy. Z tego względu operacje zarówno odczytu, jak i zapisu wiążą się z wykorzystaniem strumieni i/lub obiektów klas Reader/Writer. Nie inaczej jest w tym przypadku: zanim prześlemy jakiekolwiek dane, musimy uzyskać odpowiednie obiek- ty zapisujące: (cid:141) ServletOutputStream getOutputStream() — zwraca strumień zapisu dla danych binarnych (cid:141) PrintWriter getWriter() — zwraca obiekt zapisujący dla danych tekstowych. W przypadku danych binarnych możemy skorzystać z obiektu klasy ServletOutput (cid:180)Stream. Jest to zwykły strumień zapisu, rozszerzony o możliwość zapisywania do- wolnych danych typów prymitywnych, a także łańcuchów znaków (za pomocą metod print() i println()). Z tej klasy należy korzystać w przypadku przesyłania plików — jeśli serwer musi w dynamiczny sposób wygenerować treść takiego pliku. Znacznie częściej przyjdzie Ci jednak korzystać z danych tekstowych. W tym przypad- ku zazwyczaj będziesz korzystać z obiektu klasy PrintWriter i jego metody println(). Nagłówki i ciasteczka O ile w przypadku żądania mamy do czynienia z odczytem nagłówków i ciasteczek przesłanych przez klienta, o tyle w przypadku odpowiedzi występuje proces odwrot- ny. Aby dodać ciasteczko, wystarczy skorzystać z metody addCookie(): void addCookie(Cookie c) Więcej na temat ciasteczek w osobnym podrozdziale. W przypadku nagłówków sytu- acja jest nieco bardziej skomplikowana — do dyspozycji mamy dwie metody (wraz z odpowiednikami dla liczb i dat): void addHeader(String nazwa, String wartość) void setHeader(String nazwa, String wartość) 30 Część I ♦ Podstawy Na czym polega różnica? Otóż metoda addHeader() doda podaną wartość do już istnie- jącej zawartości nagłówka, natomiast metoda setHeader() zastąpi wartość, jeśli tako- wa już istnieje. Tak samo działają bliźniacze metody addIntHeader(), addDateHeader(), setIntHeader() i setDateHeader(). Kody odpowiedzi, błędy i przekierowania Do obowiązków odpowiedzi HTTP należy także przekazywanie kodów odpowiedzi, jeśli chcemy zaznaczyć, że odpowiedź nie zostanie zakończona w zwykły sposób. Aby przekazać kod odpowiedzi, korzystamy z metody setStatus(): void setStatus(int kod) W ten sposób przekazujemy kody, które nie określają sytuacji problematycznych. W przypadku błędów (np. 404 — brak zasobu) zaleca się zdecydowanie wykorzysty- wanie metody sendError(): void sendError(int kod) void sendError(int kod, String komunikat) Jak widać, istnieje możliwość przesłania dodatkowej informacji na temat samego błę- du. Ostatnią funkcjonalność związaną z kodami odpowiedzi stanowi przekierowanie. Chociaż z technicznego punktu widzenia przekierowanie jest też rodzajem kodu od- powiedzi, do przekierowania wykorzystuje się oddzielną metodę: void sendRedirect(String adres) Korzystając z metod sendError() i sendRedirect(), należy pamiętać o subtelnych kwestiach związanych z fizycznym przesyłaniem danych do klienta. Przesyłanie ko- munikatów o błędach lub przekierowań wiąże się z dość brutalną ingerencją w proces przesyłania odpowiedzi. Proces ten jest natychmiast przerywany, a klient otrzymuje odpowiedź z wybranym kodem odpowiedzi. Co jednak stanie się, gdy zdążymy wy- słać do klienta jakieś dane? Odpowiedź jest prosta — nastąpi błąd. Po wysłaniu danych nie możesz ingerować w treść nagłówków, przez co nie możesz ustawić kodu odpowiedzi, a co za tym idzie także przekierowania. Czy oznacza to, że musisz uważać, gdzie wywołujesz metodę println() obiektu PrintWriter? Na szczęście nie do końca. Domyślnym zachowaniem obiektu w przypadku odpowiedzi jest zapisywanie danych do bufora. Oznacza to, że dane zostaną wysłane po zakończeniu metody lub w przy- padku wywołania metody flush() tego obiektu. Co za tym idzie, poniższa konstruk- cja (wewnątrz metody doGet()) nie spowoduje wygenerowania błędu: PrintWriter out = response.getWriter(); out.println( test ); response.sendRedirect( url/do/innego/serwletu ); Jeśli przed wywołaniem metody sendRedirect() wywołasz metodę out.flush(), wte- dy błąd nastąpi. Zazwyczaj jednak takie wywołanie jest pomijane, dzięki czemu pro- blem występuje stosunkowo rzadko. Rozdział 3. ♦ Serwlet — na dobry początek 31 Om nom nom, czyli ciasteczka w pełnej krasie Twórcy aplikacji webowych, podobnie jak Ciasteczkowy Potwór, mają szczególny sentyment do ciasteczek (ang. cookies). Są to niewielkie pliki przechowywane na kom- puterach użytkowników aplikacji webowych, dzięki czemu jesteśmy w stanie zapamię- tywać ich preferencje, loginy i hasła itd. Metody operujące na ciasteczkach poznaliśmy w poprzednim podrozdziale, ale teraz zaprezentujemy ich działanie w praktycznym przykładzie (listing 3.1): Listing 3.1. Przykład obsługi ciasteczek protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType( text/html;charset=UTF-8 ); PrintWriter out = response.getWriter(); try { Cookie lastVisit = null; for (Cookie c : request.getCookies()) if (c.getName().equals( obecnosc )) { lastVisit = c; break; } if (lastVisit != null) out.println( Twoja ostatnia wizyta na stronie miała miejsce w dniu + lastVisit.getValue()); else out.println( Do tej pory nie odwiedziłeś/aś naszej strony. Wstydź się! ); lastVisit = new Cookie( obecnosc , new Date().toString()); response.addCookie(lastVisit); } finally { out.close(); } } Zadaniem powyższego serwletu jest przechowywanie informacji o dacie ostatniej wi- zyty na stronie i wyświetlanie jej. W przypadku braku ciasteczka z datą (co jest równo- znaczne z pierwszymi odwiedzinami na tej stronie, przynajmniej od czasu wyczysz- czenia ciasteczek w przeglądarce) wyświetlamy inną informację. Warto zwrócić uwagę na dwie kwestie. Po pierwsze, jeśli chcemy odczytać już istniejące ciasteczka — ko- rzystamy z metody getCookies() znajdującej się w obiekcie request. Jeśli chcemy dodać ciasteczko — korzystamy z obiektu response. Nigdy odwrotnie! Sprawa druga, znacznie bardziej przykra — powyższy sposób dostępu do ciasteczek użytkownika (pętla for..in) stanowi jedyną metodę znajdywania ciasteczek o określonej nazwie. W przypadku tworzenia prawdziwych aplikacji trzeba zdefiniować osobną metodę do wyszukiwania ciasteczek. Sesje — nie tylko dla studentów Obsługa sesji jest kolejnym nieodłącznym elementem niemal wszystkich aplikacji we- bowych. W przypadku JEE interakcje z sesją możemy prowadzić na różne sposoby, 32 Część I ♦ Podstawy także za pomocą poznanych już klas. W tym rozdziale poznamy sposób na dostęp do sesji za pomocą obiektu klasy HttpServletRequest. Kluczową rolę odgrywa metoda getSession(), występująca w dwóch wariantach: HttpSession getSession() HttpSession getSession(boolean czyTworzyc) Na wstępie zaznaczę, że pierwszy wariant tej metody jest równoważny drugiemu wy- wołanemu z parametrem true. Drugi wariant postępuje różnie w zależności od prze- kazanej wartości logicznej: (cid:141) Jeśli parametr ma wartość true, metoda zwraca obiekt sesji lub tworzy nowy, jeśli ten nie istnieje. (cid:141) Jeśli parametr ma wartość false, metoda zwraca obiekt sesji lub null, jeśli ten nie istnieje. Jak widać, wartość true należy przekazać, jeśli chcesz po prostu uzyskać dostęp do sesji. Wartość false stosuje się, gdy chcesz sprawdzić, czy sesja istnieje. Można sko- rzystać z tego mechanizmu, aby sprawdzić, czy dane żądanie jest pierwszym żądaniem użytkownika w danej sesji. Mechanizm ten jest realizowany w poniższym przykładzie z listingu 3.2: Listing 3.2. Przykład wykorzystania sesji protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType( text/html;charset=UTF-8 ); PrintWriter out = response.getWriter(); try { if (request.getSession(false)==null) { out.println( Witaj na stronie po raz pierwszy! ); request.getSession(); } else out.println( Witaj na stronie po raz kolejny! ); } finally { out.close(); } } Jeśli po utworzeniu sesji chcesz sprawdzić, czy sesja została dopiero co utworzona, skorzystaj z metody isNew(): (cid:141) boolean isNew() — zwraca true, jeśli obiekt sesji został utworzony podczas tego żądania. Korzystanie z obiektu sesji Podstawowa funkcjonalność obiektu sesji sprowadza się do dwóch metod: (cid:141) Object getAttribute(String nazwa) — zwraca atrybut sesji o podanej nazwie. Rozdział 3. ♦ Serwlet — na dobry początek 33 (cid:141) void setAttribute(String nazwa, Object wartość) — dodaje obiekt do sesji, przypisując mu podany klucz (nazwę). Jeśli jakiś obiekt o takiej samej nazwie już istniał, zostanie on zastąpiony. Wiemy już, jak utworzyć sesję, wiemy też, jak z niej skorzystać. Pozostało nam omó- wienie, jakie są warunki zakończenia sesji. Może ono nastąpić w wyniku kilku różnych sytuacji: (cid:141) ręczne zakończenie sesji przez programistę, (cid:141) upłynięcie czasu życia sesji, (cid:141) zamknięcie okna przeglądarki przez użytkownika. Ostatni przypadek, jest rzecz jasna, najprostszy — nie wymaga on naszej ingerencji. Ręczne zakończenie sesji wiąże się z wywołaniem następującej metody: (cid:141) void invalidate() — kończy sesję. Najciekawiej sytuacja wygląda w przypadku określania terminu ważności sesji. Istnie- ją bowiem dwie możliwości określenia tej wartości — pierwsza z nich jest stosowana w pliku konfiguracyjnym web.xml: web-app session-config session-timeout 10 /session-timeout /session-config /web-app Podana wartość określa czas ważności sesji w minutach. Obowiązuje on dla wszyst- kich sesji, chyba że skorzystasz z możliwości określenia czasu życia sesji w kodzie: (cid:141) void setMaxInactiveInterval(int czas) — określa czas życia sesji w sekundach. Podanie wartości 0 i ujemnych powoduje, że sesja nigdy nie wygasa (do jej zakończenia jest więc konieczne wywołanie metody invalidate() lub zamknięcie okna przeglądarki przez użytkownika). Konfiguracja w kodzie Javy — można tego uniknąć Podczas tworzenia większości aplikacji programiści muszą zmierzyć się z problemem obsługi różnego rodzaju ustawień wpływających na działanie aplikacji. Problemem staje się lokalizacja tych ustawień. Z jednej strony nikt nie chce utrudniać sobie życia — w końcu nie ma nic prostszego, niż wczytać wartość umieszczoną w stałej/zmiennej. Z drugiej jednak strony zmiana takich ustawień wymagałaby rekompilacji całego pro- jektu, w najlepszym przypadku — jednej biblioteki. Z tego względu powszechnym standardem stało się umieszczanie różnego rodzaju ustawień w zewnętrznych źródłach danych — plikach binarnych, tekstowych, XML; 34 Część I ♦ Podstawy rzadziej w bazach danych. W przypadku aplikacji webowych JEE miejscem takim jest deskryptor wdrożenia — plik web.xml. Poza licznymi ustawieniami związanymi z funkcjonowaniem aplikacji jako takiej (część z nich już poznałeś), w pliku web.xml możesz także zdefiniować parametry dla poszczególnych serwletów, a także całej apli- kacji webowej. Parametry serwletów Parametry serwletów możesz określać za pomocą znacznika init-param w następu- jący sposób: servlet servlet-name ParameterServlet /servlet-name servlet-class pl.helion.jeeweb.ParameterServlet /servlet-class init-param param-name autor /param-name param-value Krzysztof Rychlicki-Kicior /param-value /init-param /servlet Po dwóch znanych już znacznikach (servlet-name i servlet-class) następuje dowol- na liczba znaczników init-param. Każdy taki znacznik zawiera dwa kolejne, określa- jące nazwę i wartość parametru. Parametry serwletów można też dodawać w środowi- sku Netbeans, podczas tworzenia serwletu (w ostatnim kroku kreatora). Pierwszy parametr utworzony, najwyższa pora, aby odczytać go we wnętrzu serwletu. Do zarządzania parametrami serwletów służy interfejs ServletConfig, który jest im- plementowany przez znane nam klasy GenericServlet i HttpServlet. Dwie metody tego interfejsu, które interesują nas w tej chwili najbardziej, to: (cid:141) String getInitParameter(String nazwa) — zwraca wartość parametru o podanej nazwie. (cid:141) String[] getInitParameterNames() — zwraca wszystkie nazwy parametrów danego serwletu. protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType( text/html;charset=UTF-8 ); PrintWriter out = response.getWriter(); try { out.println( Autorem serwletu jest + this.getInitParameter( autor )); } finally { out.close(); } } Dzięki umieszczeniu konfiguracji w pliku XML odnieśliśmy wymierną korzyść. Zmia- na wartości w pliku XML nie wymaga rekompilacji kodów źródłowych, a jedynie prze- ładowania aplikacji (w przypadku Tomcata istnieje także opcja automatycznego wy- krywania zmian i przeładowywania aplikacji). Rozdział 3. ♦ Serwlet — na dobry początek 35 Interfejs ServletConfig poza dwoma poznanymi metodami udostępnia metodę get (cid:180)ServletName(), zwracającą nazwę serwletu, a także metodę getServletContext(). Zwraca ona (a jakżeby inaczej) kontekst serwletów — jeden z najważniejszych obiek- tów w całym świecie aplikacji webowych JEE. Kontekst serwletów Kontekst serwletów to obiekt, który służy do komunikacji serwletów z kontenerem. Dzięki niemu możesz dynamicznie dodawać serwlety do aplikacji, uzyskiwać dostęp do zasobów znajdujących się w jej obrębie, zapisywać logi do serwerowego dzienni- ka, a co najważniejsze z obecnego punktu widzenia — możesz korzystać z parametrów aplikacji webowej (kontekstu). Od parametrów serwletów różni je zasięg oddziaływa- nia. Każdy parametr kontekstu jest widoczny we wszystkich serwletach i innych pli- kach. Parametry serwletu są określane w podobny sposób jak w przypadku serwletów: web-app context-param param-name tytul /param-name param-value Java EE 6. Tworzenie aplikacji webowych /param-value /context-param … /web-app Również sposób wykorzystywania parametrów kontekstu przypomina ten znany z serwletów: try { out.println( Wszystkie przykłady pochodzą z książki + this.getServletContext().getInitParameter( tytul )); } finally { out.close(); } Jedyną różnicę stanowi odwołanie się do obiektu kontekstu. Reszta pozostaje bez zmian — nawet nazwa metody. Ciekawostkę stanowi metoda wprowadzona w specyfikacji Java Servlets 3.0. Otóż aż do momentu wprowadzenia tej specyfikacji parametry, za- równo serwletów, jak i kontekstu, były wartościami tylko do odczytu. Jedyną możli- wością zmiany parametrów była edycja pliku web.xml. W wersji JavaServlet 3.0 API pojawiła się jednak innowacja — możliwość dynamicznego ustawiania parametrów kontekstu za pomocą metody setInitParameter(). Wynika to z wprowadzenia dużej elastyczności — klasa ServletContext w wersji 3.0 uzyskała wiele metod, takich jak addServlet(), czy addFilter(), które umożliwiają dynamiczne dodawanie różnych składników aplikacji, do tej pory deklarowanych jedynie w pliku web.xml. Nie należy jednak nadużywać tej metody. Kontekst serwletów pojawi się ponownie już niebawem, tymczasem nadszedł czas, aby zmierzyć się z przeciwnikiem o wiele ważniejszym od parametrów — mowa o atrybutach. 36 Część I ♦ Podstawy Trzech muszkieterów? Parametry, czy to serwletów, czy to aplikacji, mają swoje zastosowania i bywają nie- zwykle przydatne. Mimo to głównym środkiem komunikacji między serwletami, kon- tenerem, sesją, użytkownikiem i obiektem żądania — czyli z grubsza między wszyst- kimi elementami aplikacji — są atrybuty. Z technicznego punktu widzenia między parametrami i atrybutami występują dwie zasadnicze różnice: (cid:141) W przypadku parametrów zarówno klucz, jak i wartość są łańcuchami znaków, zaś w przypadku atrybutów — klucz jest łańcuchem, wartość może być obiektem. (cid:141) Parametry z założenia są tylko do odczytu (choć w świetle ostatniej wersji specyfikacji wygląda to inaczej…), natomiast atrybuty są przeznaczone zarówno do odczytu, jak i do zapisu. Niezwykłe znaczenie ma także wprowadzenie zasięgu atrybutów. Atrybut dodany w za- sięgu żądania (request) nie będzie widoczny w innych zasięgach. Tabela 3.1 przedsta- wia zestawienie parametrów i atrybutów w poszczególnych zakresach. Tabela 3.1. Możliwości zapisywania i odczytywania parametrów i atrybutów w poszczególnych zakresach Zakres Żądanie Serwlet Sesja Kontekst aplikacji Parametry Atrybuty Zapis nie nie brak tak (od wersji 3.0) Odczyt tak tak brak tak Zapis tak brak tak tak Odczyt tak brak tak tak Na podstawie powyższej tabeli wydać wyraźnie, że parametry pełnią jedynie funkcję ustawień, opcji konfiguracyjnych, które ułatwiają zmianę w działaniu aplikacji bez konieczności ponownej rekompilacji kodu. Atrybuty natomiast mają zastosowanie o wiele szersze — służą do wymiany informacji pomiędzy poszczególnymi elementa- mi aplikacji. W dalszej części rozdziału skupimy się tylko na atrybutach. Ich ogromna przydatność ma bowiem pewne ograniczenia. Jedno z nich jest związane z najważniejszą chyba ce- chą odróżniającą aplikacje webowe od aplikacji typu standalone — konieczność jed- noczesnej obsługi wielu użytkowników. Atrybuty a mnogość żądań Jedna aplikacja webowa może być używana nawet przez setki czy tysiące użytkowni- ków jednocześnie. Każde żądanie (HTTP request) jest obsługiwane przez kontener w osobnym wątku. Istotną kwestią jest więc zapewnienie integralności operacji wyko- Rozdział 3. ♦ Serwlet — na dobry początek 37 nywanych przez każdego z nich — nie może być tak, że operacje jednego użytkowni- ka wpłyną na efekt operacji innego. W przypadku parametrów problem ten raczej nie występuje. Co prawda, w wersji 3.0 pojawiła się możliwość modyfikowania parametrów kontekstu aplikacji, jednak możli- wość ta powinna być używana w bardzo sporadycznych sytuacjach, gdy obsługa wielu użytkowników nie powinna sprawiać problemów (np. z powodu wywoływania takiego kodu przez superadministratora witryny). Jeśli jednak zabezpieczenie jest konieczne, można zrealizować je w sposób analogiczny do tego, który zaprezentuję za chwilę. Zdecydowanie bardziej skomplikowana sytuacja występuje w przypadku atrybutów. Wszystkie trzy przypadki omówię w kolejnych podrozdziałach. Atrybuty żądania W przypadku atrybutów żądania sytuacja jest stosunkowo prosta. Żądanie jest realizo- wane przez jednego użytkownika; w dodatku pojedyncze żądanie nie wiąże się w ża- den sposób z innymi żądaniami (nawet tego samego użytkownika), dlatego problem jednoczesnego dostępu przez wielu użytkowników nie występuje. Pojawia się jednak inne pytanie — skoro obiekt żądania nie wchodzi w interakcje z innymi żądaniami, po co miałby korzystać z atrybutów? Takie rozwiązanie wynika ze stosowanych w praktyce mechanizmów obsługi stron. Serwlety same w sobie rzadko generują treść — na ogół wykonują one różnorodne operacje (np. pobranie danych z bazy, realizacja logiki biznesowej — choć w więk- szych aplikacjach i te zadania są delegowane), a następnie przekazują sterowanie do pliku JSP. W takiej sytuacji konieczne jest przekazanie informacji między serwletem a plikiem JSP. Voilà! — znaleźliśmy zastosowanie atrybutów żądania. Dokładne wy- jaśnienie i przykłady poznasz w rozdziale poświęconym JSP. Atrybuty sesji W nieco gorszej sytuacji są atrybuty sesji. Wiemy już, że jedna sesja jest powiązana z konkretnym użytkownikiem. Teoretycznie nie powinno więc być problemów. Ale użytkownicy bywają okrutni — wyobraź sobie, co mogłoby się stać, gdyby użytkow- nik uruchomił Twoją aplikację webową w dwóch zakładkach i próbował jednocześnie ładować różne (lub te same) serwlety? Odpowiedź jest prosta: mogłoby dojść do jednoczesnego dostępu do sesji. Odczyt da- nych nie stanowiłby problemu, ale atrybuty sesyjne mogą być przecież również zapi- sywane. Taka sytuacja to potencjalny problem. Jak więc mu zaradzić? Powiem krótko: należy skorzystać ze standardowego mechanizmu Javy, chroniącego dane przed zapisem przez wiele wątków jednocześnie — synchronizacji. Teraz musi- my określić, dostęp do czego dokładnie chcemy synchronizować. Na początek odrzućmy obiekt żądania (klasy HttpServletRequest). Jest to obiekt zwią- zany tylko z jednym, konkretnym żądaniem, więc zablokowanie dostępu do niego nie wpłynęłoby na inne obiekty żądań — nadal wszystkie one mogłyby korzystać bez 38 Część I ♦ Podstawy skrępowania z sesji. Nie ma sensu również blokada obiektu serwletu — dostęp do se- sji mają różne serwlety, więc zablokowanie jednego z nich nie powstrzyma innych od zapisu do sesji. Jedynym sensownym rozwiązaniem pozostaje zablokowanie obiektu sesji, do którego uzyskujemy dostęp za pomocą obiektu żądania. Poniższy kod, wsta- wiony we wszystkich serwletach, pozwoli na zliczenie wszystkich wywołań serwle- tów, które miały miejsce w aplikacji webowej dla danego użytkownika: HttpSession sesja = request.getSession(); synchronized(sesja) { if (sesja.isNew()) sesja.setAttribute( licznik , 1); else { int licznik = Integer.parseInt(sesja.getAttribute( licznik ).toString()); sesja.setAttribute( licznik , licznik + 1); } } W ten sposób, gdy jeden serwlet wejdzie w blok synchronizowany, uzyskujemy gwa- rancję, że żaden inny serwlet w tym momencie dostępu do sesji nie uzyska. Wszystkie inne serwlety będą musiały czekać, aż pierwszy serwlet zwolni blokadę. Atrybuty kontekstu serwletów Największe niebezpieczeństwo niesie za sobą korzystanie z atrybutów należących do kontekstu aplikacji. Każdy taki atrybut może być odczytany i zmodyfikowany w do- wolnym niemal miejscu aplikacji. Z tego względu każda próba korzystania z atrybu- tów (zwłaszcza zapisu) powinna być synchronizowana. Zasada działania jest taka sama, jak w przypadku sesji. W tym przypadku musimy jednak synchronizować obiekt kontekstu. Kod synchronizujący przedstawia się następująco: ServletContext sc = this.getServletContext(); synchronized(sc) { Object licznik = sc.getAttribute( licznik ); if (licznik == null) sc.setAttribute( licznik , 1); else { licznik = sc.getAttribute( licznik ); sc.setAttribute( licznik , Integer.parseInt(licznik.toString()) + 1); } } Powyższy kod realizuje funkcjonalność podobną do przykładu z sesją — tym razem zliczamy jednak wszystkie wywołania serwletów wykonane przez wszystkich użyt- kowników. Z obiektami żądań, sesji i kontekstu, jak również z ich atrybutami, wiążą się ważne klasy — słuchaczy zdarzeń. Choć istnieje możliwość tworzenia całych aplikacji we- bowych bez świadomości istnienia tych klas, zdarzają się sytuacje, w których znajo- mość tego typu mechanizmów jest niezbędna. Rozdział 3. ♦ Serwlet — na dobry początek 39 Słuchowisko Słuchacze zdarzeń to obiekty spotykane w Javie niezwykle często. Początkujący pro- gramiści Javy spotykają się z nimi np. podczas tworzenia prostych aplikacji graficz- nych. Słuchacz zdarzeń powiązany z przyciskiem pozwalał na wykonanie dowolnego kodu np. po jego kliknięciu. Pojęcie słuchacza zdarzeń nie ogranicza się oczywiście do tworzenia aplikacji z graficznym interfejsem — również aplikacje webowe dają słuchaczom zdarzeń spore pole do popisu. W poniższych podrozdziałach przedstawię interfejsy słuchaczy zdarzeń przeznaczone do użycia w aplikacjach webowych. Nie jest to może najciekawszy fragment niniej- szej książki, ale prędzej czy później znajdziesz się w sytuacji, w której będziesz mu- siał skorzystać z opisanych w następnych akapitach mechanizmów. ServletContextListener Jest to najrzadziej chyba wykorzystywany słuchacz zdarzeń. Zawiera dwie metody: contextInitialized() i contextDestroyed(), które są wywoływane w momencie utwo- rzenia/usunięcia kontekstu aplikacji, czyli — w momencie startu i zakończenia aplika- cji. Obydwie metody przyjmują parametr typu ServletContextEvent — umożliwia on pobranie kontekstu aplikacji za pomocą metody getServletContext(). ServletContextAttributeListener Drugim słuchaczem zdarzeń związanym z kontekstem aplikacji jest słuchacz obser- wujący kolekcję atrybutów kontekstu. Reaguje on na dodawanie (metoda attribute (cid:180)Added()), usuwanie (attributeRemoved()) i zamianę (attributeReplaced()) atrybu- tów. Wszystkie trzy metody przyjmują jeden parametr typu ServletContextAttribute (cid:180)Event — umożliwia on pobranie nazwy modyfikowanego atrybutu (getName()), jego wartości (getValue()). ServletRequestAttributeListener i ServletRequestListener Obydwa interfejsy pełnią analogiczne funkcje, co ich „kontekstowi” koledzy — na- wet nazwy metod są podobne (w przypadku pierwszego interfejsu — identyczne, w przypadku drugiego — requestInitialized() i requestDestroyed()). Jedyną real- ną zmianą jest wprowadzenie dodatkowej funkcjonalności do klas argumentów zdarzeń — ServletRequestAttributeEvent i ServletRequestEvent. Udostępniają one metodę getServletRequest(). Pozwala ona na skorzystanie z obiektu żądania, którego zda- rzenia dotyczą. 40 Część I ♦ Podstawy HttpSessionAtributteListener i HttpSessionListener Również słuchacze zdarzeń powiązani z sesjami zostały utworzone zgodnie z omówio- nymi powyżej zasadami. Słuchacz HttpSessionListener jest wykorzystywany przy tworzeniu (metoda sessionCreated()) i kończeniu sesji (sessionDestroyed()). Prze- kazywany argument — obiekt klasy HttpSessionEvent — udostępnia metodę getSes- sion(), która daje dostęp do utworzonej (zakończonej) sesji. W przypadku interfejsu HttpSessionAttributeListener mamy do dyspozycji te same trzy metody, co w po- przednich przypadkach. Typ zdarzenia to HttpSessionBindingEvent. Jego możliwości sprowadzają się do pobrania obiektu sesji i nazwy/wartości dodawanego/usuwanego/ zmienianego atrybutu. HttpSessionBindingListener Nareszcie coś ciekawego! Tytułowy interfejs odbiega nieco od schematu, z jakim mie- liśmy do czynienia przez ostatnie trzy podrozdziały. Wszystkie trzy interfejsy z czło- nem AttributeListener w nazwie odpowiadały za informowanie o zmianach zacho- dzących w kolekcji atrybutów. Dla odmiany interfejs HttpSessionBindingListener powinien być implementowany przez klasy, których obiekty będą umieszczane w se- sji! Jeśli więc tworzysz własne klasy do przechowywania danych
Pobierz darmowy fragment (pdf)

Gdzie kupić całą publikację:

Java EE 6. Programowanie aplikacji WWW
Autor:

Opinie na temat publikacji:


Inne popularne pozycje z tej kategorii:


Czytaj również:


Prowadzisz stronę lub blog? Wstaw link do fragmentu tej książki i współpracuj z Cyfroteką: