Czym są serwlety Java? Serwlety Java. Zalety serwletów Java (w porównaniu z CGI)

Podobne dokumenty
JDBC (Java Database Connectivity vit )

Plan wykładu. Dostęp do bazy danych. Architektura JDBC. Dostęp do baz danych z aplikacji Java EE

1 Wprowadzenie do J2EE

Java Database Connectivity

CGI i serwlety. Plan wykładu. Wykład prowadzi Mikołaj Morzy. Przykład: serwlety vs. szablony. Implementacja logiki prezentacji

Serwlety Java: zagadnienia zaawansowane. Data Sources. Data Sources. Przykład pliku data-sources.xml

Elementy JEE. 1. Wprowadzenie. 2. Prerekwizyty. 3. Pierwszy servlet. obsługa parametrów żądań 4. JavaServer Pages.

Wykład dla studentów Informatyki Stosowanej UJ 2012/2013

Aplikacje internetowe i rozproszone - laboratorium

Wykorzystanie aplikacji Java Server Pages w środowisku J2EE

prepared by: Programowanie WWW Servlety

Aplikacje WWW - laboratorium

Java wybrane technologie spotkanie nr 5. Java Server Pages

Programowanie w Sieci Internet JSP ciąg dalszy. Kraków, 9 stycznia 2015 r. mgr Piotr Rytko Wydział Matematyki i Informatyki

Serwery aplikacji. dr Radosław Matusik. radmat

Serwery aplikacji. mgr Radosław Matusik. Wydział Matematyki i Informatyki Uniwersytetu Łódzkiego radmat radmat@math.uni.lodz.

Java wybrane technologie spotkanie nr 4. Serwlety c.d.

mgr inż. Michał Paluch

Dostęp do baz danych z aplikacji J2EE

Obsługa transakcji rozproszonych Java. Marek Wojciechowski, Maciej Zakrzewicz Instytut Informatyki, Politechnika Poznańska

Serwlety i JSP na platformie Java EE. Damian Makarow


Serwlety. Co to jest serwlet? Przykładowy kod serwletu. Po co są serwlety?

Komunikacja między serwletami

Aplikacje Internetowe, Servlety, JSP i JDBC

Serwery aplikacji. dr Radosław Matusik. radmat

Informatyka I. Standard JDBC Programowanie aplikacji bazodanowych w języku Java

Piotr Laskowski Krzysztof Stefański. Java Servlets

JAVA I BAZY DANYCH. MATERIAŁY:

Programowanie w Sieci Internet filtry oraz web.xml. Kraków, 11 stycznia 2013 r. mgr Piotr Rytko Wydział Matematyki i Informatyki

Wstęp Budowa Serwlety JSP Podsumowanie. Tomcat. Kotwasiński. 1 grudnia 2008

CGI, serwlety Java i szablony JSP. Przykład: serwlety vs. szablony. Implementacja logiki prezentacji

Java wybrane technologie spotkanie nr 3. Serwlety

Zaawansowane aplikacje internetowe - laboratorium Web Services (część 1).

Wzorce prezentacji internetowych

Projektowanie aplikacji J2EE w architekturze Model-View-Controller

Architektury Usług Internetowych. Laboratorium 1. Servlety

prepared by: Programowanie WWW Model-View-Controller

Architektura Model-View-Controller

Wprowadzenie do J2EE. Maciej Zakrzewicz.

Informatyka I. Programowanie aplikacji bazodanowych w języku Java. Standard JDBC.

Architektury Usług Internetowych. Laboratorium 1 Servlety

Java i jej wykorzystanie do tworzenia dynamicznych aplikacji Webowych

JavaServer Pages. Konrad Kurdej Karol Strzelecki

Aplikacje WWW. Wykład 5. Logika prezentacji - część I. wykład prowadzi: Maciej Zakrzewicz. Logika prezentacji I

Enterprise JavaBeans (EJB)

2) W wyświetlonym oknie należy zaznaczyć chęć utworzenia nowej aplikacji (wygląd okna może się różnić od powyższego); kliknąć OK

Wybrane działy Informatyki Stosowanej

Dariusz Brzeziński. Politechnika Poznańska, Instytut Informatyki

Programowanie w języku Java

Przegląd technologii JSP

Java Enterprise Edition spotkanie nr 4. Java Server Pages c.d.

Tworzenie witryn internetowych PHP/Java. (mgr inż. Marek Downar)

Analiza porównawcza technologii tworzenia aplikacji internetowych dla baz danych Oracle

Aplikacje WWW - laboratorium

Java EE: Serwlety i filtry serwletów

Czym jest Java? Rozumiana jako środowisko do uruchamiania programów Platforma software owa

Serwery aplikacji. mgr Radosław Matusik. Wydział Matematyki i Informatyki Uniwersytetu Łódzkiego radmat radmat@math.uni.lodz.

In»ynieria systemów informacyjnych - Adam Krechowicz

Wybrane działy Informatyki Stosowanej

Podstawowe wykorzystanie Hibernate

Przetwarzanie dokumentów XML i zaawansowane techniki WWW Wykład 09

Analiza porównawcza technologii tworzenia aplikacji internetowych dla baz danych Oracle

Wywoływanie metod zdalnych

Materiały oryginalne: ZAWWW-2st1.2-l11.tresc-1.0kolor.pdf. Materiały poprawione

Java wybrane technologie

Wybrane działy Informatyki Stosowanej

Serwlety i JSP. Autor: Marek Zawadka deekay@gazeta.pl

Programowanie obiektowe

Java Enterprise Edition spotkanie nr 3. Serwlety c.d.

Marcin Luckner Politechnika Warszawska Wydział Matematyki i Nauk Informacyjnych

Serwery aplikacji. dr Radosław Matusik. radmat

Przykłady tworzenia aplikacji komponentowych w technologii JavaServer Faces 2.1 na podstawie

Typy przetwarzania. Przetwarzanie zcentralizowane. Przetwarzanie rozproszone

Warstwa integracji. wg. D.Alur, J.Crupi, D. Malks, Core J2EE. Wzorce projektowe.

Zaawansowane aplikacje internetowe

Enterprise JavaBeans

Aplikacje Internetowe

1 90 min. Aplikacje WWW Harmonogram spotkań, semestr zimowy (studia stacjonarne)

Aplikacje internetowe - laboratorium

Programowanie w języku Java. Bazy danych SQLite w Javie

Wprowadzenie do JSP. Marcin Apostoluk, Tadeusz Pawlus, Wojciech Walczak. Technologie Biznesu Elektronicznego, 7 marzec 2006

PLAN WYNIKOWY PROGRAMOWANIE APLIKACJI INTERNETOWYCH. KL IV TI 6 godziny tygodniowo (6x15 tygodni =90 godzin ),

Wzorce logiki dziedziny

Metody dostępu do danych

Język JAVA podstawy. wykład 2, część 1. Jacek Rumiński. Politechnika Gdańska, Inżynieria Biomedyczna

PLAN WYNIKOWY PROGRAMOWANIE APLIKACJI INTERNETOWYCH. KL III TI 4 godziny tygodniowo (4x30 tygodni =120 godzin ),

Aplikacje RMI

Bazy danych wykład dwunasty

Wywoływanie metod zdalnych

Java rozszerzenie. dr. A. Dawid

Programowanie obiektowe. Literatura: Autor: dr inŝ. Zofia Kruczkiewicz

Aplikacje internetowe oparte na kluczowych technologiach Java Enterprise(Servlet,JSP,JDBC, )

Nowe mechanizmy w wersji 3 Java Card. Mateusz LESZEK (138775)

Programowanie komponentowe 5

Enterprise JavaBeans. 1. Architektura EJB: komponenty encyjne, komponenty sesyjne, komponenty sterowane komunikatami. 2. Kontenery EJB JBoss.

EJB 3.0 (Enterprise JavaBeans 3.0)

Uniwersytet Łódzki Wydział Matematyki i Informatyki, Katedra Analizy Nieliniowej. Wstęp. Programowanie w Javie 2. mgr inż.

Kurs WWW 1. Paweł Rajba

JDBC w LoXiMie. Interfejs Java Database Connectivity dla systemu LoXiM. Adam Michalik 2008

Transkrypt:

Czym są serwlety Java? 209 Serwlety Java Klasy Java uruchamiane po stronie serwera Służą do tworzenia aplikacji pracujących w trybie żądanie/odpowiedź W praktyce wykorzystywane w aplikacjach rozszerzających funkcjonalność serwerów HTTP (aplikacji webowych, aplikacji J2EE) Stanowiły odpowiedź na wady skryptów CGI Zastosowania: Dynamiczna generacja dokumentów w odpowiedzi na żądanie z przeglądarki Wstępne przetwarzanie żądań i przekierowywanie ich do odpowiednich stron-widoków (typowo JSP) funkcja kontrolera w modelu MVC (model-view-controller) Zalety serwletów Java (w porównaniu z CGI) Wydajność w porównaniu z CGI, gdzie obsługa każdego żądania wymaga utworzenia nowego procesu w systemie operacyjnym, serwlety Java korzystają z wielowątkowości i pozostają aktywne w pamięci Wygoda możliwość zastosowania umiejętności programowania w języku Java do konstrukcji aplikacji internetowych Funkcjonalność ogromne bogactwo bibliotek i rozwiązań dostępnych dla języka Java może być wykorzystane podczas tworzenia serwletów Java Przenaszalność kod i struktura serwletów Java są niezależne od platformy systemowej i mogą być uruchamiane w na każdym serwerze Java 210 Tworzenie serwletów Java Serwlet jest programem Java zapisanym w postaci klasy dziedziczonej z klasy javax.servlet.http.httpservlet Programista dostarcza własne implementacje metod: public void doget(httpservletrequest request, HttpServletResponse response) throws ServletException, IOException public void dopost(httpservletrequest request, HttpServletResponse response) throws ServletException, IOException public void init(servletconfig config) throws ServletException public void destroy() 211

Cykl życia serwletu (1/2) 212 Cykl życia serwletu (2/2) 213 serwer Java serwer Java serwlet serwer Java serwlet obsługa żądań (doget,dopost) serwlet ładowanie (init) przeglądarka przeglądarka przeglądarka usuwanie (destroy) Cykl życia serwletu jest kontrolowany przez kontener, w którym serwlet został osadzony (deployed) W momencie gdy przychodzi żądanie adresowane do serwletu, kontener wykonuje następujące akcje: Jeśli instancja serwletu jeszcze nie istnieje: Ładuje klasę serwletu do pamięci Tworzy instancje klasy serwletu Wywołuje metodę init() serwletu Wywołuje metodę service() przekazując jej obiekty HttpServletRequest i HttpServletResponse, reprezentujące żądanie i odpowiedź Odziedziczona implementacja metody service() wywołuje odpowiednie metody pomocnicze zależnie od typu żądania: doget(), dopost(),... Serwlet po zakończeniu obsługi żądania pozostaje aktywny w kontenerze Kolejne żądania realizowane są przez uruchomienie metody service() w osobnych wątkach Gdy kontener musi usunąć serwlet, najpierw wywołuje jego metodę destroy() Przykład prostego serwletu 214 Interfejs HttpServletRequest 215 import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class MyServlet extends HttpServlet { public void doget(httpservletrequest request, HttpServletResponse response) response.setcontenttype("text/html"); PrintWriter out = response.getwriter(); out.println("<h1>moj serwlet!</h1>"); Obiekt out reprezentuje wyjście na przeglądarkę Wysłanie kodu HTML na ekran przeglądarki PrintWriter HttpServlet HttpServletRequest, HttpServletResponse Typ programu: serwlet Będzie generowany kod HTML Klasa HttpServletRequest umożliwia dostęp do pól w treści żądania otrzymanego od przeglądarki Cookie[] getcookies() String getheader(n) String getmethod() String getremoteuser() HttpSession getsession() String getpathinfo() String getparameter(n) String getremoteaddr() Odczytuje tablicę wszystkich zmiennych Cookies przesłanych przez serwer WWW Odczytuje wartość pola n dostarczonego w nagłówku HTTP Odczytuje nazwę typu żądania przeglądarki: GET, POST, PUT Odczytuje nazwę, pod jaką zalogowany jest użytkownik przeglądarki, która przesłała żądanie Odczytuje lub tworzy obiekt aktualnej sesji Odczytuje pełną ścieżkę użytą przez przeglądarkę w adresie URL Odczytuje wartość przekazanego przez użytkownika parametru wywołania n Odczytuje adres IP przeglądarki

Pola w nagłówku żądania HTTP - Przykłady 216 Wykorzystanie HttpServletRequest 217 Accept wykaz formatów danych akceptowanych przez przeglądarkę Accept-Encoding wykaz formatów kompresji danych, akceptowanych przez przeglądarkę Accept-Language kod języka narodowego, w których przeglądarka chce otrzymać odpowiedź User-Agent nazwa programu przeglądarki Referer adres dokumentu, którego link spowodował wysłanie tego żądania Authorization dane autoryzujące użytkownika If-Modified-Since jeżeli dokument nie uległ zmianie od tego czasu, przeglądarka może otrzymać tylko odpowiedź "Not Modified 304" Cookie lista zmiennych Cookies out.println("<table border=1>"); out.println("<tr><td>user-agent</td><td>"+ request.getheader("user-agent")+"</td>"); out.println("<tr><td>accept-language</td><td>"+ request.getheader("accept-language")+"</td>"); out.println("<tr><td>user address</td><td>"+ request.getremoteaddr()+"</td>"); out.println("</table>"); Dostęp do parametrów wywołania serwletu Przeglądarka użytkownika może w URL żądania umieścić parametry wywołania serwletu, np.: 218 Przykład serwletu z parametrem (1/2) import java.io.*; import javax.servlet.*; import javax.servlet.http.*; 219 http://serwer/ścieżka/mój_serwlet?x=1&y=2&z=kowalski public class MyServlet extends HttpServlet { public void doget(httpservletrequest request, HttpServletResponse response) Programista uzyskuje dostęp do parametrów wywołania przy pomocy obiektu HttpServletRequest: int liczba1, liczba2, wynik; response.setcontenttype("text/html;charset=iso-8859-2"); PrintWriter out = response.getwriter(); nazwisko = request.getparameter("z"); liczba1 = Integer.parseInt(request.getParameter("x")); liczba2 = Integer.parseInt(request.getParameter("y")); wynik = liczba1*liczba2; out.println("<h1>kalkulator</h1>"); out.println(liczba1+" razy "+liczba2+" równa się "+wynik); Wielkość znaków jest istotna Przykład wywołania kalkulatora: http://.../myservlet MyServlet?x=2&y=6 Na ekranie przeglądarki zostanie wyświetlony wynik mnożenia.

Przykład serwletu z parametrem (2/2) 220 Odbieranie parametrów przekazanych metodami GET/POST 221 Formularz HTML wywołujący serwlet może przekazywać parametry wywołania serwletu przy użyciu jednej z metod: GET: łańcuch nazw i wartości wszystkich parametrów jest dołączany do adresu URL wołanego serwletu POST: łańcuch nazw i wartości wszystkich parametrów jest wysyłany za nagłówkiem HTTP żądania Do wyboru metody służy atrybut METHOD znacznika <FORM> Jeżeli parametry przekazane są metodą GET, to w serwlecie wywoływana jest metoda doget(); jeżeli zastosowano POST, to w serwlecie wywołana będzie metoda dopost() W celu stworzenia serwletu uniwersalnego, należy np. w implementacji metody dopost() umieścić wywołanie doget() Interfejs HttpServletResponse 222 getoutputstream() - przykład użycia 223 Klasa HttpServletResponse umożliwia dostęp do pól nagłówka odpowiedzi wysyłanej do przeglądarki import java.io.*; import javax.servlet.*; import javax.servlet.http.*; void addcookie(c) void addheader(n,v) void senderror(v) void sendredirect(url) void setheader(n,v) PrintWriter getwriter() ServletOutputStream getoutputstream() void flushbuffer() Umieszcza w nagłówku odpowiedzi zmienną Cookie c Umieszcza w nagłówku odpowiedzi nowe pole n o wartości v Wysyła nagłówek z kodem błędu v Wysyła nagłówek przekierowania na adres url Ustawia w nagłówku odpowiedzi pole n na wartość v Pobiera kanał komunikacyjny dla zapisu tekstowego do przeglądarki Pobiera kanał komunikacyjny dla zapisu binarnego do przeglądarki Wymusza wysłanie zawartości bufora wyjściowego do przeglądarki public class MyServlet extends HttpServlet { public void doget(httpservletrequest request, HttpServletResponse response) int value; FileInputStream fstream = new FileInputStream("/home/logo.jpg"); response.setcontenttype("image/jpeg"); OutputStream out = response.getoutputstream(); while ((value = fstream.read())!= -1) out.write(value); fstream.close(); Serwlet wysyła do przeglądarki obraz graficzny JPG, odczytany z pliku dyskowego.

Kody błędów umieszczane w nagłówku odpowiedzi HTTP 224 Wykorzystanie HttpServletResponse 225 Do ustawiania kodu statusu służy metoda senderror() Kodom statusu HTTP odpowiadają stałe w klasie HttpServletRequest, np.: SC_BAD_REQUEST SC_UNAUTHORIZED (400) Niewłaściwy format żądania (401) Wymagana autoryzacja klienta if (!request.getremoteaddr().equals("150.254.31.178")) response.senderror(httpservletresponse.sc_forbidden); else out.println("<h1>welcome!</h1>"); SC_FORBIDDEN SC_NOT_FOUND (403) Odmowa dostępu (404) Dokument nie znaleziony SC_GONE SC_SERVICE_UNAVAILABLE SC_NOT_MODIFIED (410) Dokument zmienił adres, a nowa lokalizacja nie jest znana (503) System jest chwilowo przeciążony lub niedostępny (304) Dokument nie uległ modyfikacji od poprzedniego dostępu Problem polskich znaków (1/2) 226 Problem polskich znaków (2/2) 227 Jeżeli serwlet będzie generować dokumenty zawierające znaki z polskich stron kodowych, to wywołanie metody setcontenttype należy zapisać w następujący sposób: response.setcontenttype("text/html;charset=windows-1250"); Niezależnie od ustawień kodowania znaków narodowych, wartości wprowadzane do pól formularza są reprezentowane przy użyciu kodów ISO-8859-1 W celu poprawnego przetwarzania wartości zawierających polskie znaki, programista musi przekodować otrzymane wartości tekstowe na WINDOWS-1250 lub ISO-8859-2: lub: response.setcontenttype("text/html;charset=iso-8859-2"); String par1_pl; par1 = new String( request.getparameter("par1").getbytes("iso8859_1"),"iso8859_2"); lub: String par1_pl; par1 = new String( request.getparameter("par1").getbytes("iso8859_1"),"windows-1250");

Definiowanie zmiennych Cookies Klasa javax.servlet.http.cookie służy do definiowania zmiennych Cookies, które będą wysyłane lub odbierane od przeglądarki 228 Wysyłanie zmiennych Cookies przy użyciu HttpServletResponse.addCookie import java.io.*; import javax.servlet.*; import javax.servlet.http.*; addcookie() 229 Cookie(n,s) String getdomain() void setdomain(s) String getmaxage() void setmaxage(v) String getname() void setname(s) String getpath() void setpath(s) String getvalue() void setvalue(s) Tworzy zmienną Cookie o nazwie n i wartości s Odczytuje/ustawia adres domenowy, dla którego przeznaczona jest zmienna Cookie Odczytuje/ustawia czas życia zmiennej Cookie, liczony w sekundach (-1 -> ulotne) Odczytuje/ustawia nazwę zmiennej Cookie Odczytuje/ustawia prefiks ścieżki URL na serwerze, dla której przeznaczona jest zmienna Cookie Odczytuje/ustawia wartość zmiennej Cookie public class MyServlet extends HttpServlet { public void doget(httpservletrequest request, HttpServletResponse response) response.setcontenttype("text/html; charset=iso-8859-2"); PrintWriter out = response.getwriter(); Cookie mycookie = new Cookie("cookie1","James Bond"); mycookie.setmaxage(24*60*60); response.addcookie(mycookie); out.println("<h1>wysłano Cookie</h1>"); Odczytywanie zmiennych Cookies przy użyciu HttpServletRequest.getCookies getcookies() 230 Współdzielenie zmiennych globalnych przez wątki jednego serwletu (1/2) 231 import java.io.*; import javax.servlet.*; import javax.servlet.http.*; import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class MyServlet extends HttpServlet { public void doget(httpservletrequest request, HttpServletResponse response) response.setcontenttype("text/html; charset=iso-8859-2"); PrintWriter out = response.getwriter(); out.println("<h1>odebrane Cookies</h1>"); Cookie[] allcookies = request.getcookies(); for (int i=0; i<allcookies.length; i++) out.println(allcookies[i].getname()+": "+ allcookies[i].getvalue()+"<br>"); public class MyServlet extends HttpServlet { String myglobal = null; public void doget(httpservletrequest request, HttpServletResponse response) response.setcontenttype("text/html; charset=iso-8859-2"); PrintWriter out = response.getwriter(); if (myglobal==null) { out.println("ustawiam myglobal"); myglobal = "xyz"; else { out.println("myglobal był już ustawiony na:"); out.println(myglobal);

Współdzielenie zmiennych globalnych przez wątki jednego serwletu (2/2) 232 Współdzielenie informacji przez komponenty aplikacji webowej 233 Komponenty aplikacji webowej (serwlety, JSP) mogą współdzielić informacje (obiekty) poprzez atrybuty czterech tzw. obiektów zasięgu (scope objects) Obiekty zasięgu: Web context (obiekt klasy ServletContext) Zasięg kontekstu aplikacji webowej Session (obiekt klasy HttpSession) Zasięg bieżącej sesji użytkownika Request (obiekt klasy HttpServletRequest) Zasięg obsługi bieżącego żądania Page (obiekt klasy JspContext) Zasięg strony, która utworzyła obiekt Składowanie/odczyt obiektów z obiektów zasięgu odbywa się za pomocą metod setattribute/getattribute z klas obiektów zasięgu Plik konfiguracyjny aplikacji webowej 234 Mapowanie serwletów do ścieżek URL 235 Konfiguracja aplikacji webowej jest realizowana poprzez plik web.xml (znajdujący się w podkatalogu WEB-INF drzewa katalogów aplikacji webowej) Przykłady ustawień w web.xml: Mapowanie serwletów do adresów URL Konfiguracja filtrów serwletów Definicje referencji do zasobów (źródeł danych, EJB) Role użytkowników Prawa dostępu do zasobów Czas trwania sesji (w minutach)... Domyślny URL lokalizujący serwlet: http://host/kontekst_aplikacji/servlets/klasaserwletu Zalecane jest mapowanie serwletu do adresów URL w pliku web.xml poprzez elementy <servlet> i <servlet-mapping> web.xml <web-app...> <servlet> <servlet-name>myservlet</servlet-name> <servlet-class>mypackage.myservlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>myservlet</servlet-name> <url-pattern>/myservlet</url-pattern> </servlet-mapping>... </web-app> Wywołanie: http://host/kontekst_aplikacji/myservlet

Adres URL z punktu widzenia serwletu Ogólna postać URL dla żądań HTTP: http://[host ]:[port ][request path ]?[query string ] Część request_path jest dalej dekomponowana na: Context path: połączenie / z wirtualnym katalogiem głównym aplikacji webowej (context root) Servlet path: fragment ścieżki stanowiący alias, który wywołał serwlet Path info: część request_path nienależąca ani do Context path ani do Servlet path Przykłady: Wzór URL /cennik/* /*.jsp Serwlet CennikServlet JSPServlet 236 Wywoływanie innych komponentów webowych z poziomu serwletu (1/2) Sposoby wywoływania innych zasobów webowych: Pośrednio Poprzez zaszycie adresu URL zasobu w generowanym dokumencie Bezpośrednio Poprzez włączenie (include) zawartości z innego zasobu Poprzez przekierowanie (forward) żądania do innego zasobu W celu bezpośredniego wywołania innego zasobu konieczne jest uzyskanie obiektu RequestDispatcher dla danego URL, a następnie skorzystanie z jego metody include() lub forward(), przekazując obiekty HttpServletRequest i HttpServletResponse 237 Request path /sklep/cennik/dvd.html /sklep/pomoc/waluty.jsp Servlet path /cennik / pomoc/waluty.jsp Path info /dvd.html null Wywoływanie innych komponentów webowych z poziomu serwletu (2/2) Włączenie zawartości... RequestDispatcher dispatcher = getservletcontext().getrequestdispatcher("/naglowek.html"); if (dispatcher!= null) dispatcher.include(request,response);... Przekierowanie żądania Serwlet dokonujący przekierowania nie może sam generować zawartości!... RequestDispatcher dispatcher = request.getrequestdispatcher("widok.jsp"); if (dispatcher!= null) dispatcher.forward(request,response);... Obiekt RequestDispatcher można uzyskać zarówno poprzez obiekt żądania jak i kontekst aplikacji webowej (servlet context) W przypadku skorzystania z pośrednictwa request, dopuszczalne są względne URL (bez / ) 238 Interfejs HttpSession Protokół HTTP jest bezstanowy - nie potrafi rozpoznać, że nowe żądanie pochodzi od użytkownika, który już wcześniej przesłał inne żądanie Interfejs javax.servlet.http.httpsession implementuje pojęcie sesji - umożliwia identyfikację użytkownika, który wielokrotnie odwołuje się do serwletu/serwletów Nieużywana sesja wygasa automatycznie Object getattribute(n) void setattribute(n,o) long getcreationtime() String getid() long getlastaccessedtime() void invalidate() Zapamiętuje na czas sesji obiekt pod podaną nazwą / odczytuje obiekt o podanej nazwie Odczytuje czas rozpoczęcia sesji, liczony w ms od 1.01.1970 Odczytuje jednoznaczny identyfikator sesji Odczytuje czas ostatniej operacji wykonanej w ramach sesji (1.01.1970) Zamyka sesję i usuwa wszystkie jej obiekty 239

Obsługa sesji przy użyciu HttpSession (1/2) Bieżącą sesję zwraca metoda getsession() obiektu HttpServletRequest Parametr mówi o tym, czy ma być utworzona nowa sesja gdy nie ma bieżącej import java.io.*; import javax.servlet.*; import javax.servlet.http.*; 240 Obsługa sesji przy użyciu HttpSession (2/2) import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class Sesja2 extends HttpServlet { 241 public class Sesja1 extends HttpServlet { public void doget(httpservletrequest request, HttpServletResponse response) response.setcontenttype("text/html"); PrintWriter out = response.getwriter(); out.println("<h1>rozpoczęcie sesji</h1>"); HttpSession myses = request.getsession(true); myses.setattribute("username", "James Bond"); public void doget(httpservletrequest request, HttpServletResponse response) response.setcontenttype("text/html"); PrintWriter out = response.getwriter(); out.println("<h1>stan sesji</h1>"); HttpSession myses = request.getsession(false); out.println((string) myses.getattribute("username")); Śledzenie sesji przez kontener 242 Zapisy do pliku logu serwera 243 W celu związania sesji z użytkownikiem, kontener musi przesyłać identyfikator sesji między klientem i serwerem Podstawowym i domyślnym sposobem przekazywania identyfikatora sesji jest zastosowanie cookie Sposobem wykorzystywanym gdy obsługa cookies może być wyłączona przez użytkownika jest zaszywanie identyfikatora sesji w każdym adresie URL wysyłanym do klienta import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class MyServlet extends HttpServlet { public void doget(httpservletrequest request, HttpServletResponse response) response.setcontenttype("text/html"); PrintWriter out = response.getwriter(); out.println("<a href=\""+ response.encodeurl(request.getcontextpath()+"/katalog") +"\">Powrót do katalogu</a>"; Zakodowanie identyfikatora sesji w adresie URL będzie miało miejsce tylko gdy w przeglądarce będą wyłączone cookies! if (request.getparameter("id")==null) { log("błąd parametru wywołania"); out.println("podaj parametr wywołania id"); else out.println("otrzymano:"+request.getparameter("id")); Plik logu serwera... [13/02/2002 18:37:14:849 CET] MyServlet: Błąd parametru wywołania

Odczyt parametrów inicjalizacyjnych 244 Filtry serwletów 245 import... public class MyServlet extends HttpServlet { String msg; public void doget(httpservletrequest request, HttpServletResponse response)... out.println(msg); public void init(servletconfig config) { super.init(config); msg = config.getinitparameter("welcome_message"); <web-app...> <servlet> <servlet-name>myservlet</servlet-name> <servlet-class>mypackage.myservlet</servlet-class> <init-param> <param-name>welcome_message</param-name> <param-value>witamy!</param-value> </init-param> </servlet>... </web-app> web.xml Filtr pozwala na przechwycenie i zmodyfikowanie zarówno żądania kierowanego do serwletu jak i odpowiedzi generowanej przez serwlet Filtr może też modyfikować nagłówki żądania i odpowiedzi Filtry służą do: tworzenia spójnego mechanizmu uwierzytelniania śledzenia użytkowników kompresowania danych "w locie" Filtr to klasa implementująca interfejs javax.servlet.filter void init(filterconfig) void dofilter(servletrequest, ServletResponse, FilterChain) void destroy() Konfiguracja: element <filter> i <filter-mapping> w pliku web.xml Można zdefiniować łańcuch filtrów Kolejność ich aplikowania zależna od kolejności mapowania w web.xml Zalety filtrów: Filtr i komponent, do którego jest on aplikowany są od siebie niezależne Ten sam filtr może być stosowany do serwletów, JSP, stron HTML Przykład filtra (1/3) 246 Przykład filtra (2/3) 247 MyFilter.java import javax.servlet.*; import javax.servlet.filter; import java.io.ioexception; public class MyFilter implements Filter { private FilterConfig fc; public void init(filterconfig filterconfig) throws ServletException { fc = filterconfig; public void destroy() { MyServlet.java import... public class MyServlet extends HttpServlet { public void doget(httpservletrequest request, HttpServletResponse response) response.setcontenttype("text/html; charset=windows-1250"); PrintWriter out = response.getwriter(); out.println("<html>"); out.println("<head><title>myservlet</title></head>"); out.println("<body>"); out.println("<p>witaj "+request.getattribute("user")+"!"); out.println("</body></html>"); out.close(); public void dofilter(servletrequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { request.setattribute("user","anonymous"); chain.dofilter(request, response);

Przykład filtra (3/3) 248 web.xml <web-app...> <filter> <filter-name>myfilter</filter-name> <filter-class>mypackage.myfilter</filter-class> </filter> <filter-mapping> <filter-name>myfilter</filter-name> <servlet-name>myservlet</servlet-name> </filter-mapping> </web-app> Tworzenie aplikacji JavaServer Pages request response MyFilter Myservlet Czym są aplikacje JavaServer Pages? 250 Architektura JSP 251 Podstawowa wada serwletów Java: brak możliwości oddzielenia kodu w języku Java generującego dynamiczną zawartość dokumentu od części statycznej (HTML) odpowiedzialnej za ogólny wygląd strony Technologia JavaServer Pages (JSP) jest rozszerzeniem architektury serwletów Java Aplikacje JavaServer Pages mają postać dokumentów HTML (XML) zawierających zagnieżdżony kod w języku Java W odpowiedzi na żądanie użytkownika, serwer WWW wykonuje zagnieżdżony kod i zwraca wygenerowany dokument HTML Typowy sposób przetwarzania dokumentów JSP polega na ich translacji do serwletów, które są następnie kompilowane i uruchamiane przez serwer WWW przeglądarka żądanie HTTP generacja + kompilacja dokument JSP serwer WWW serwlet uruchomienie Przy pierwszym żądaniu, na podstawie treści dokumentu JSP generowany jest kod źródłowy równoważnego serwletu. Serwlet ten jest następnie kompilowany i uruchamiany, po czym pozostaje w pamięci operacyjnej na rzecz obsługi ponownych żądań.

JSP - Przykład 252 Porównanie równoważnych: serwletu i JSP Serwlet 253 <HTML> <HEAD> <TITLE>JSP demo</title> </HEAD> <BODY> <%@ page language= java %> <%! int result; %> <% result = 2*2; %> <H1> Multiplication result: <%= result %> </H1> </BODY> </HTML> JSP <HTML> <HEAD> <TITLE>JSP demo</title> </HEAD> <BODY> <%@ page language= java %> <%! int result; %> <% result = 2*2; %> <H1> Multiplication result: <%= result %> </H1> </BODY> </HTML> import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class MyServlet extends HttpServlet { int result; public void doget( HttpServletRequest request, HttpServletResponse response) response.setcontenttype("text/html"); PrintWriter out = response.getwriter(); out.println("<html>"); out.println("<head>"); out.println("<title>jsp demo</title>"); out.println("</head>"); out.println("<body>"); result = 2*2; out.println(" <H1> Multiplication result:"); out.println(result); out.println("</h1>"); out.println("</body>"); out.println("</html>"); Komponenty dokumentu JSP 254 Generacja serwletu (1/2) 255 Dokument JSP: Serwlet Java: <HTML> <HEAD> <TITLE>JSP demo</title> </HEAD> <BODY> <%@ page language= java %> <%! int result; %> <% result = 2*2; %> <H1> Multiplication result: <%= result %> </H1> </BODY> </HTML> Dyrektywy (page - globalne właściwości dokumentu: język, deklaracje import; include; taglib) Deklaracje (globalnych zmiennych i metod) Kod Java (ang. Scriptlets) Wyrażenia (wyświetlane po wyznaczeniu ich wartości) <HTML> <HEAD> <TITLE>JSP demo</title> </HEAD> <BODY> <%@ page language= java %> <%! int result; %> <% result = 2*2; %> <H1> Multiplication result: <%= result %> </H1> </BODY> </HTML> import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class MyServlet extends HttpServlet{ int result; public void doget(httpservletrequest request, HttpServletResponse response) response.setcontenttype("text/html"); PrintWriter out = response.getwriter(); out.println("<html><head><title>jsp demo"); out.println("</title></head><body>"); result = 2*2; out.println("<h1> Multiplication result:"); out.println(result); out.println("</h1></body></html>");

Dokument JSP: <HTML> <HEAD> <TITLE>JSP demo</title> </HEAD> <BODY> <%@ page language= java %> <%! int result; %> <% result = 2*2; %> <H1> Multiplication result: <%= result %> </H1> </BODY> </HTML> Generacja serwletu (2/2) Serwlet Java: import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class MyServlet extends HttpServlet{ int result; public void doget(httpservletrequest request, HttpServletResponse response) response.setcontenttype("text/html"); PrintWriter out = response.getwriter(); out.println("<html><head><title>jsp demo"); out.println("</title></head><body>"); result = 2*2; out.println("<h1> Multiplication result:"); out.println(result); out.println("</h1></body></html>"); 256 Obiekty dostępne w dokumentach JSP (1/2) Programista JSP może korzystać z nastepujących obiektów, tworzonych dla niego automatycznie: request (javax.servlet.http.httpservletrequest) Umożliwia dostęp do pól w treści żądania otrzymanego od przeglądarki (jak w metodach doget()/dopost() serwletu) response (javax.servlet.http.httpservletresponse) Umożliwia dostęp do pól nagłówka odpowiedzi przesyłanej do przeglądarki (jak w metodach doget()/dopost() serwletu) page (javax.servlet.jsp.httpjsppage) Reprezentuje obiekt serwletu, który powstał na podstawie tego dokumentu (this) session (javax.servlet.http.httpsession) Reprezentuje obiekt sesji użytkownika (jak getsession() w serwlecie) 257 Obiekty dostępne w dokumentach JSP (2/2) Programista JSP może korzystać z nastepujących obiektów, tworzonych dla niego automatycznie: application (javax.servlet.servletcontext) Reprezentuje obiekt, który jest współdzielony przez wszystkie dokumenty JSP obsługiwane przez tę samą JVM out (javax.servlet.jsp.jspwriter) Reprezentuje kanał wyjściowy dla zapisu do przeglądarki (jak getwriter() w serwlecie) config (javax.servlet.servletconfig) Umożliwia dostęp do parametrów inicjalizacyjnych serwletu (jak w metodzie init() serwletu) 258 Problem polskich znaków Aby aplikacja JSP poprawnie wyświetlała zawarte w niej znaki narodowe, należy zastosować dyrektywę wskazującą zastosowany standard kodowania: <%@ page contenttype="text/html; charset=iso-8859-2" %> 259

Przekazywanie parametrów 260 Przekazywanie parametrów - Przykład 261 Aplikacji JSP mogą być przekazane parametry wejściowe Parametry mogą być umieszczone w adresie URL lub wysyłane przez formularz HTML Implementacja mechanizmu przekazywania parametrów jest taka sama jak w przypadku serwletów: dostęp do wszystkich parametrów wywołania jest możliwy poprzez obiekt request Aby odczytać wartość parametru należy wywołać metodę request.getparameter() <HTML> <HEAD> <TITLE>JSP demo</title> </HEAD> <BODY> <%@ page language= java %> <% int result; int term1, term2; %> <% term1 = Integer.parseInt( request.getparameter( par1 )); term2 = Integer.parseInt( request.getparameter( par2 )); result = term1 * term2; %> <H1> Multiplication result: <%= result %> </H1> </BODY> </HTML> Przekazywanie parametrów do JSP za pomocą formularzy HTML 262 Przykład zintegrowanej aplikacji JSP (1/2) 263 Technologia JSP pozwala na zintegrowanie formularza HTML z programem obsługi tego formularza Jeżeli znacznik <FORM>, definiujący formularz, nie określi wartości atrybutu ACTION, wtedy aplikacją obsługującą formularz będzie ta sama, która ten formularz wyświetliła formularz HTML ACTION serwlet dokument JSP z formularzem ACTION <HTML> <HEAD><TITLE>Kalkulator</TITLE></HEAD> <BODY> <%@ page contenttype="text/html; charset=iso-8859-2" %> <% int liczba1, liczba2; if (request.getparameter("par1")!=null){ liczba1 = Integer.parseInt(request.getParameter("par1")); liczba2 = Integer.parseInt(request.getParameter("par2")); %> <H1>Wynik mnożenia</h1> <%= liczba1 %> x <%= liczba2 %> = <%= liczba1*liczba2 %> <BR> <% %><BR> <H1>Wprowadź liczby do pomnożenia</h1> <FORM> Liczba1:<INPUT TYPE='text' NAME='par1'><BR> Liczba2:<INPUT TYPE='text' NAME='par2'><BR><BR> <INPUT TYPE='submit' VALUE='Pomnóż'> </FORM> </BODY> </HTML>

Przykład zintegrowanej aplikacji JSP (1/2) 264 265 Wykorzystywanie zewnętrznych klas Java Kod w języku Java zagnieżdżony w dokumencie JSP może osiągać duże rozmiary utrudniając tym samym pielęgnację aplikacji Zaleca się, aby programiści implementowali złożony kod w oddzielnej klasie/klasach Java, do której następnie w prosty sposób odwoływać się może dokument JSP; pozwala to na zmniejszenie rozmiaru dokumentów JSP Obiekty tworzone wewnątrz "<%" i "%>" posiadają zasięg ograniczony do jednego wywołania, natomiast zasięg obiektów tworzonych przy pomocy znacznika <jsp:usebean/> może być jawnie wyspecyfikowany przez programistę Omawiane klasy zewnętrzne są często nazywane JavaBeans Klasy zewnętrzne - przykład (1/2) 266 Klasy zewnętrzne - przykład (2/2) 267 public class TaxCalc { public double gettax(double income) { double tax; if (income < 2450) tax = 0.05 * income; else if (income < 6100) tax = (0.07*(income-2450)+123); else tax = (0.09*(income-6100)+378); return tax; <%@ page import="taxcalc" %> <HEAD> <TITLE>Podatnik JSP</TITLE> </HEAD> <BODY> <% TaxCalc tc = new TaxCalc(); double t, i; i = Double.parseDouble(request.getParameter("income")); t = tc.gettax(i); %> <H1> Podatek od <%= i %> USD wynosi: <%= t %> USD </H1> </BODY>

Korzystanie z klas zewnętrznych przy pomocy <jsp< jsp:usebean/> <HEAD> <TITLE>Podatnik JSP</TITLE> </HEAD> <BODY> <jsp:usebean id="tc" class="taxcalc"/> <% double t, i; %> pamiętaj o "/"! i = Double.parseDouble(request.getParameter("income")); t = tc.gettax(i); <H1> Podatek od <%= i %> USD wynosi: <%= t %> USD </H1> </BODY> 268 Zasięg obiektów tworzonych przy pomocy <jsp< jsp:usebean/> Zasięg obiektu utworzonego na podstawie klasy zewnętrznej można określić jawnie za pomocą atrybutu scope znacznika <jsp:usebean/> Dopuszczalne wartości atrybutu scope: page (zasięg ograniczony do bieżącego dokumentu JSP) request (zasięg ograniczony do obsługi bieżącego żądania) session (zasięg ograniczony do całej sesji użytkownika) application (współdzielenie przez wszystkie aplikacje pracujące na tej samej JVM) Korzystanie z obiektów o zasięgu większym niż bieżący dokument pozwala na: oszczędniejsze gospodarowanie zasobami współdzielenie obiektów przez dokumenty obsługujące to samo żądanie 269 Zasięg obiektów - przykład 270 JSP - pozostałe znaczniki standardowe 271 <BODY> <jsp:usebean id="username" class="longclass" scope="session"/> <% username.str = "James Bond"; %> Ustawiono username: <%= username.str %> </BODY> <BODY> <jsp:usebean id="username" class="longclass" scope="session"/> Odczytano username: <%= username.str %> </BODY> <jsp:include/> Umieszcza wewnątrz generowanej odpowiedzi zawartość innego dokumentu, np.: <jsp:include page="/hr/news.jsp" flush="true" /> (flush="true" jest wymagane ze względu na bug) <jsp:forward/> Powoduje natychmiastowe przekierowanie żądania pod inny adres, np.: <jsp:forward page="/hr/newmain.jsp"/> public class LongClass { public String str;

Dokumenty JSP XML 272 Przykład dokumentu JSP 273 Tradycyjne strony JSP nie są poprawnymi dokumentami JSP. Standard JSP 1.1 wprowadził składnię kompatybilną z XML. Strona JSP zbudowana zgodnie ze składnią XML nazywana jest dokumentem JSP Każdy dokument JSP posiada znacznik <jsp:root> który identyfikuje stronę jako dokument JSP podaje wersję JSP i podaje przestrzenie nazw dla składni XML Znaczniki dyrektyw, wyrażeń, skryptletów i akcji posiadają swoje odpowiedniki zgodne ze składnią XML third.jspx <?xml version = '1.0' encoding = 'windows-1250'?> <jsp:root xmlns:jsp="http://java.sun.com/jsp/page" version="1.2"> <jsp:directive.page contenttype="text/html"/> <jsp:usebean id="c" class="ploug.converter" scope="page"/> <jsp:declaration> double priceeur = 10, pricepln = 0; </jsp:declaration> <jsp:scriptlet> pricepln = c.convert(priceeur); </jsp:scriptlet> <jsp:text>kwocie </jsp:text> <jsp:expression>priceeur</jsp:expression> <jsp:text> euro odpowiada </jsp:text> <jsp:expression>pricepln</jsp:expression> <jsp:text> zlotych </jsp:text> </jsp:root> Biblioteki znaczników JSP 274 Wykorzystywanie bibliotek znaczników 275 Standard JSP 1.1 umożliwia pozwala programistom na rozszerzanie zbioru podstawowych znaczników JSP o znaczniki implementujące dodatkowe funkcje przydatne podczas konstrukcji aplikacji Znaczniki definiowane przez programistę są zapisywane w bibliotekach znaczników (Tag Libraries), a następnie wykorzystywane w taki sam sposób, jak znaczniki standardowe W porównaniu z klasami zewnętrznymi, biblioteki znaczników oferują podobną funkcjonalność, lecz są wygodniejsze i prostsze w użyciu Wielu producentów oferuje własne biblioteki znaczników Szczególne znaczenie ma standardowa biblioteka JSTL W celu poinformowania środowiska JSP o chęci wykorzystywania zewnętrznej biblioteki znaczników, należy umieścić wewnątrz dokumentu następującą deklarację: gdzie: uri - <%@ taglib uri="/tlt" prefix="tlt" %> ścieżka dostępu do pliku TLD definiującego bibliotekę znaczników prefix - wybrany przez użytkownika prefiks, który będzie używany w dokumencie do wyróżniania znaczników pochodzących z tej biblioteki

JavaServer Pages Standard Tag Library (JSTL) 276 JSP Expression Language (EL) 277 Znaczniki podstawowe (core tags): reprezentują instrukcje warunkowe, iteratory, oraz operacje na URL; znaczniki c:if, c:catch, c:choose, c:foreach, c:when, c:out, c:set, c:remove, itp. Znaczniki XML: umożliwiają pracę z dokumentami XML, parsowanie i transformację dokumentów; znaczniki x:parse, x:choose, x:if, x:otherwise, x:transform, x:param Znaczniki SQL: praca z bazą danych; znaczniki sql:query, sql:update, sql:transaction, sql:setdatasource, sql:driver, sql:param, sql:dateparam Znaczniki i18n: internacjonalizacja i transformacja danych Istotna właściwość JSP 2.0 Język wyrażeń ułatwiający dostęp do danych aplikacji składowanych w komponentach JavaBean Wyrażenia postaci ${expr Mogą występować w statycznym tekście i atrybutach znaczników (odpowiednie konwersje typów zostaną dokonane automatycznie) W kontenerach JSP 1.2 dostępne w połączeniu z JSTL ${100.0 == 100 -> true ${(10*10)ne 100 -> false ${3 div 4 -> 0.75 ${10 mod 4 -> 2 Obiekty predefiniowane JSP EL 278 JSTL Core + EL Przykład 279 pagecontext zawiera servletcontext, session, request, response param, paramvalues, header, headervalues, cookie, initparam ułatwiają dostęp do parametrów, nagłówków, itd. pagescope, requestscope, sessionscope, applicationscope umożliwiają dostęp do zmiennych o danym zasięgu <%@ taglib uri="http://java.sun.com/jstl/core" prefix="c"%> <%@ page contenttype="text/html;charset=windows-1250"%> <html> <head> <meta http-equiv="content-type" content="text/html; charset=windows-1250"> <title>powitanie</title> </head> <body> <c:out value="witaj ${param.nazwisko!"></c:out> <%-- Albo: <c:out value="witaj ${param['nazwisko']!"></c:out> --%> <c:if test="${!empty param.zadania"> <c:out value="masz ${param.zadania zadań do wykonania!"></c:out> </c:if> </body> </html> ${sessionscope.koszyk.liczbapozycji ${param['nazwisko'] ${param.nazwisko ${header["host"]

JSTL SQL Tag Library 280 Przykład zastosowania biblioteki JSTL SQL 281 Biblioteka JSTL SQL TagLib dostarcza znaczników służących do interakcji z relacyjną bazą danych źródło danych <sql:setdatasource var="name" scope="sc" datasource="expr"> <sql:setdatasource var="name" url="expr" user="expr" password="expr"> zapytanie <sql:query sql="expr" datasource="expr" var="expr"> <sql:param value="expr"/><sql:dateparam value="expr"/> </sql:query> dostęp do wyniku zapytania: javax.servlet.jsp.jstl.sql.result i własności rows, rowsbyindex, columnnames, rowcount modyfikacje <sql:update sql="expr" datasource="expr" var="expr"/> transakcje <sql:transaction isolation="isolevel">...</sql:transaction> <%@ taglib uri="http://java.sun.com/jstl/core" prefix="c"%> <%@ taglib uri="http://java.sun.com/jstl/sql" prefix="sql"%> <%@ page contenttype="text/html"%> <html> <body> <sql:setdatasource var="db" driver="oracle.jdbc.driver.oracledriver" datasource="jdbc/oracleds" url="jdbc:oracle:thin:@miner.cs.put.poznan.pl:1521:miner" user="scott" password="tiger" /> <sql:query var="employees">select * from emp</sql:query> <c:foreach var="columnname" items="${employees.columnnames"> <th><c:out value="${columnname"/></th> </c:foreach> <c:foreach var="row" items="${employees.rows"> <tr><c:foreach var="column" items="${row"> <td><c:out value="${column.value"/></td> </c:foreach></tr> </c:foreach> </body> </html> JSP Model 1 283 Architektura Model-View View-Controller dla internetowych aplikacji w języku Java 1 3 JSP 2 Klasa zewnętrzna (np. JavaBean) 2 1. Przeglądarka wysyła sparametryzowane żądanie uruchomienia aplikacji JSP 2. Aplikacja JSP przetwarza żądanie przy pomocy zewnętrznej klasy Java 3. Aplikacja JSP generuje wynikowy dokument HTML dla przeglądarki

Własności JSP Model 1 Aplikacja JSP odpowiada za pobieranie i przetwarzanie żądań użytkowników Istnieją mechanizmy separacji kodu prezentacji danych od kodu przetwarzania danych (klasy zewnętrzne, JavaBeans, Enterprise JavaBeans) Wygodna architektura dla prostych systemów aplikacyjnych Skomplikowane przetwarzanie otrzymywanych żądań wymaga intensywnego wykorzystywania scriptletów 284 Architektura Model-View View-Controller (MVC) Architektura MVC zakłada podział komponentów systemu aplikacyjnego na trzy kategorie: Model (komponenty modelu): komponenty reprezentujące dane, na których operują aplikacje; komponenty modelu oferują także metody dostępu do danych View (komponenty prezentacji): komponenty reprezentujące wizualizację (prezentację) danych dla użytkownika; komponenty prezentacji pobierają dane od komponentów modelu, a następnie wyświetlają je na ekranie użytkownika Controller (komponenty sterujące): komponenty przechwytujące żądania użytkowników i odwzorowujące je w wywołania metod komponentów modelu; następnie komponenty sterujące przekazują sterowanie do komponentów prezentacji 285 JSP Model 2 286 Własności JSP Model 2 287 5 1 JSP (View) Serwlet (Controller) 3 2 4 Klasa zewnętrzna 4 (Model) Realizuje architekturę Model-View-Controller Wykorzystuje zarówno serwlety Java, jak i aplikacje JSP Serwlet Java jest odpowiedzialny za analizę żądania, tworzenie wymaganych obiektów oraz za przekazanie dalszej obsługi żądania do stosownej aplikacji JSP Aplikacja JSP odpowiada wyłącznie za pobieranie danych z obiektów zewnętrznych oraz za ich wizualizację 1. Przeglądarka wysyła sparametryzowane żądanie uruchomienia serwletu 2. Serwlet analizuje żądanie, tworzy wymagane obiekty klas zewnętrznych 3. Serwlet przekazuje sterowanie do odpowiedniej aplikacji JSP 4. Aplikacja JSP przetwarza żądanie przy pomocy zewnętrznej klasy Java 5. Aplikacja JSP generuje wynikowy dokument HTML dla przeglądarki

Środowiska realizacji JSP Model 2 288 Apache Struts bezpłatne środowisko open-source, rozwijane przez Apache Software Foundation; wysoce konfigurowalne, zawierające wiele składników: serwlet Controller, pomocnicze klasy Java, biblioteki znaczników, obsługę wielojęzycznych aplikacji, itd.; odpowiednie dla dużych aplikacji J2EE J2EE BluePrints Web Application Framework (WAF) środowisko obejmujące serwlet Controller, kilka klas Java i znaczników, obsługę wielojęzycznych aplikacji; odpowiedznie dla niewielkich aplikacji J2EE JavaServer Faces (JSF) opracowywana, obszerna architektura obejmująca zbiór interfejsów dla obsługi żądań HTTP, stanowe komponenty wizualne HTML Dostęp do baz danych z aplikacji J2EE Technologie dostępu do baz danych z aplikacji J2EE JDBC Podstawowy interfejs dostępu do baz danych Ręczne kodowanie w JDBC uciążliwe i podatne na błędy SQLJ Naturalne zagnieżdżanie poleceń SQL w kodzie Java Odporna na błędy alternatywa dla bezpośredniego korzystania z JDBC Martwy standard Encyjne EJB Nienaturalne, złożone, dyskusyjna efektywność Trwają prace nad przebudowaną wersją 3.0 specyfikacji Biblioteka znaczników JSTL SQL Wygodna w prostych aplikacjach opartych na JSP Miesza logikę biznesową z logiką prezentacji, narusza model MVC Technologie odwzorowania obiektowo-relacyjnego Efektywnie mapują świat obiektów na świat relacyjnej bazy danych Najczęściej działają w warstwie webowej aplikacji 290 Czym jest JDBC? JDBC jest standardowym interfejsem do współpracy aplikacji Java z relacyjną bazą danych JDBC definiuje standardowe interfejsy interfejsy są implementowane przez sterowniki JDBC standard dopuszcza rozszerzenia producentów Zaprojektowany na podstawie X/Open SQL Call Level Interface (podobny do ODBC) Interfejs dla dynamicznych instrukcji SQL Zgodny ze standardem SQL 92 Opracowany przez Sun Microsystems Powszechnie wspierany przez producentów systemów baz danych i narzędzi programistycznych 291

Architektura JDBC 292 Typy sterowników JDBC 293 Menedżer sterowników JDBC JDBC Pure Java driver Warstwa pośrednia Program Java JDBC API JDBC Partial Java driver Biblioteka klienta BD BD BD JDBC-ODBC Bridge driver * Sterownik ODBC Biblioteka klienta * sun.jdbc.odbc.jdbcodbcdriver Typ I Most JDBC-ODBC umożliwia połączenie z każdą bazą danych, dla której istnieje sterownik ODBC Typ II Sterownik napisany częściowo w Javie, wykorzystujący biblioteki klienta bazy danych efektywne rozwiązanie wymaga preinstalowanego oprogramowania klienta bazy danych Typ III Uniwersalny sterownik w czystej Javie, z obsługą specyficznych baz danych w warstwie pośredniej najbardziej elastyczna architektura Typ IV Sterownik w czystej Javie, komunikujący się bezpośrednio z serwerem bazy danych nie wymaga bibliotek klienta bazy danych odpowiedni dla dostępu do bazy danych z apletów JDBC Thin (typ IV) Sterowniki JDBC Oracle oracle.jdbc.oracledriver w 100% napisany w czystej Javie może być pobrany przez sieć wraz z apletem Java JDBC OCI (typ II) wykonuje wywołania OCI do fabrycznego sterownika, preinstalowanego po stronie klienta wykorzystywany wyłącznie w aplikacjach języka Java Server-side internal driver wykorzystywany przez aplikacje Java uruchamiane wewnątrz serwera Oracle (np. Java Stored Procedures) Server-side Thin driver wykorzystywany przez aplikacje Java uruchamiane wewnątrz serwera Oracle do nawiązywania połączeń z innymi serwerami 294 Podstawowe klasy JDBC (pakiet java.sql sql) DriverManager Connection Statement PreparedStatement CollableStatement ResultSet DatabaseMetaData ResultSetMetaData SQLException 295

Rejestrowanie sterowników JDBC (1/2) 296 Rejestrowanie sterowników JDBC (2/2) 297 Sterowniki JDBC muszą się rejestrować w menedżerze sterowników (DriverManager) Sterowniki rejestrują się automatycznie podczas ich ładowania (w przypadku większości JVM) try { // Oracle JDBC driver (Thin + OCI) Class.forName("oracle.jdbc.OracleDriver"); // IBM DB2 Universal Database app driver Class.forName("COM.ibm.db2.jdbc.app.DB2Driver"); // JDBC-ODBC bridge driver Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); catch (ClassNotFoundException e) {... W przypadku niektórych JVM załadowanie klasy nie rejestruje automatycznie sterownika (!) JDK 1.1.x na niektórych platformach (AIX, OS/2) Class.forName("oracle.jdbc.OracleDriver").newInstance(); Maszyny wirtualne Java firmy Microsoft try { DriverManager.registerDriver( new oracle.jdbc.oracledriver()); catch (SQLException e) {... Nawiązywanie połączenia z bazą danych Menedżer sterowników zarządza sterownikami JDBC i służy do otwarcia połączenia z bazą danych Baza danych jest wskazywana przez podanie JDBC URL, identyfikującego sterownik JDBC i bazę danych: jdbc:<subprotocol>:<connectstring> Na podstawie JDBC URL menedżer sterowników (DriverManager) wybiera odpowiedni sterownik JDBC spośród zarejestrowanych sterowników 298 JDBC-ODBC Bridge Oracle OCI Oracle Thin IBM DB2 app IBM DB2 net Formaty JDBC URL jdbc:odbc:<odbc_data_source> jdbc:oracle:oci:@<service_name> jdbc:oracle:thin:@<host>:<port>:<sid> jdbc:db2:<db_name> jdbc:db2://<host>:<port>/<db_name> 299 IBM AS/400 native jdbc:db2:<db_name> IBM AS/400 toolbox jdbc:as400://<system> MySQL jdbc:mysql://<host>:<port>/<db_name>

Wyjątek SQLException 300 Polecenia SQL w JDBC 301 Wywołania JDBC mogą generować wyjątek java.sql.sqlexception Metody zawierające wywołania JDBC muszą obsługiwać ten wyjątek lub deklarować możliwość jego generowania Wyjątek SQLException niesie następujące informacje: kod "SQL state" (zgodny ze specyfikacją XOPEN SQL) tekstowy komunikat o błędzie numeryczny kod błędu (specyficzny dla danego DBMS) try { conn = DriverManager.getConnection("jdbc:odbc:Finance", "scott","tiger"); catch (SQLException e) { System.err.println("Error: " + e); String sqlstate = e.getsqlstate(); String message = e.getmessage(); int errorcode = e.geterrorcode();... Polecenie Statement wykonywanie zapytań lub operacji DML/DDL Polecenie PreparedStatement (wywiedzione z Statement) wykonywanie poleceń prekompilowanych możliwość zaszycia zmiennych przydatne gdy to samo polecenie jest wykonywane kilkukrotnie dla różnych wartości Polecenie CallableStatement (wywiedzione z PreparedStatement) wywoływanie procedur i funkcji składowanych w bazie danych zachowana możliwość zaszywania zmiennych Klasa Statement 302 Przetwarzanie zbiorów wynikowych 303 Wykonywanie zapytań (metoda executequery() zwracająca zbiór wynikowy ResultSet) Obiekt ResultSet przechowuje tabelę danych wynikowych zwróconych przez zapytanie SQL Obsługa kursorów kursor startuje od pozycji przed pierwszym rekordem zbioru wynikowego metoda next() przesuwa kursor na następny rekord (zwraca true, gdy znaleziono kolejny rekord) od JDBC 2.0 są przewijalne i modyfikowalne zbiory wynikowe Dane odczytuje się przy pomocy metod getxxx() np. getint(), getstring(), które odwzorowują wyniki w równoważne typy języka Java Dostęp do pól bieżącego rekordu odbywa się przez numer na liście wyrażeń w zapytaniu lub nazwę atrybutu try { Statement stmt = conn.createstatement(); ResultSet rset = stmt.executequery ("SELECT ename, sal FROM emp");... catch (SQLException e) { Wykonywanie poleceń DML i DDL (metoda executeupdate()) try { Statement stmt = conn.createstatement(); stmt.executeupdate ("DELETE FROM emp WHERE empno = 3981"); catch (SQLException e) {

Przetwarzanie zbiorów wynikowych - Przykłady 304 import java.sql.*; JDBC kompletny przykład 305 try { ResultSet rset = stmt.executequery( "SELECT ename, sal FROM emp"); while (rset.next()) { String ename = rset.getstring(1); int sal = rset.getint(2); catch (SQLException e) { try { ResultSet rset = stmt.executequery( "SELECT ename, sal FROM emp"); while (rset.next()) { String ename = rset.getstring("ename"); int sal = rset.getint("sal"); catch (SQLException e) { public class MyDemo { public static void main(string[] args) throws ClassNotFoundException, SQLException { Connection conn; Statement stmt; ResultSet rset; DriverManager.registerDriver( new oracle.jdbc.driver.oracledriver()); conn = DriverManager.getConnection( "jdbc:oracle:thin:@srv1:1521:orcl","scott","tiger"); stmt = conn.createstatement(); rset = stmt.executequery("select ename,sal from emp"); while (rset.next()) { System.out.print(rset.getString("ename")+" "); System.out.println(rset.getString("sal")); rset.close(); stmt.close(); conn.close(); Konwersje typów między SQL i Java 306 Klasa PreparedStatement 307 Dla każdego typu SQL istnieje jeden lub więcej typów Java, do których możliwa jest konwersja: CHAR -> String, int, double, float, java.math.bigdecimal,... NUMBER -> int, double, float, java.math.bigdecimal,... DATE -> Date, Time, Timestamp, String... Konwersja z SQL do Java może wiązać się z utratą precyzji Producenci systemów baz danych mogą dostarczać typy Java pozwalające na uniknięcie utraty precyzji przy konwersji z SQL (np. Oracle) Specyficzne typy Java do obsługi typów Oracle SQL: CHAR -> oracle.sql.char NUMBER -> oracle.sql.number DATE -> oracle.sql.date... Do konwersji do typów oracle.sql.* służą odpowiednie metody getxxx() np. getchar() Zalecane, gdy istnieje potrzeba wielokrotnego wykonania tego samego polecenia, lecz z różnymi parametrami: Parametry wstawia się za pomocą znaku? try { Connection conn = DriverManager.getConnection( ); PreparedStatement pstmt = conn.preparestatement("update emp SET sal =?"); catch (SQLException e) {

Wiązanie zmiennych i wykonywanie polecenia PreparedStatement 308 Transakcje 309 Przed wywołaniem polecenia PreparedStatement należy związać parametry z konkretnymi wartościami Parametry wiąże się metodami setxxx() klasy PreparedStatement try { PreparedStatement pstmt = conn.preparestatement("update emp SET sal =?"); pstmt.setint(1, 1000); pstmt.executeupdate(); pstmt.setint(1, 1200); pstmt.executeupdate(); catch (SQLException e) { Przetwarzanie transakcyjne zależy od właściwości autocommit obiektu Connection domyślnie true, co oznacza oddzielną transakcję dla każdego polecenia SQL (każda instrukcja jest automatycznie zatwierdzana) do zmiany trybu służy metoda setautocommit() gdy autocommit == false: commit() - zatwierdzenie transakcji rollback() - wycofanie transakcji Connection conn = DriverManager.getConnection( ); conn.setautocommit(false); // zmiana trybu... // polecenia SQL conn.commit(); // zatwierdzenie... // polecenia SQL conn.rollback(); // wycofanie transakcji Źródła danych (DataSources( DataSources) 310 Korzystanie ze źródeł danych Przykład 311 Obiekt DataSource reprezentuje źródło danych (np. DBMS) Od JDBC 2.0 DataSource w zakresie uzyskiwania połączenia z bazą danych jest alternatywą dla DriverManager Źródło DataSource może wspierać: transakcje rozproszone obsługę pul połączeń DataSource może zostać zarejestrowane w JNDI Aplikacja łącząc się z bazą danych: wyszukuje źródło danych w JNDI przez jego logiczną nazwę poprzez obiekt DataSource uzyskuje obiekt Connection Połączenie uzyskane poprzez DataSource może brać udział w transakcjach rozproszonych i/lub funkcjonować w ramach puli połączeń zależnie od właściwości źródła Definicja źródła danych serwer aplikacji tworzy źródło danych i rejestruje je w JNDI w oparciu o zawartość pliku konfiguracyjnego data-sources.xml <data-source class="com.evermind.sql.drivermanagerdatasource" name="oracleds" location="jdbc/oraclecoreds" xa-location="jdbc/xa/oraclexads" ejb-location="jdbc/oracleds" connection-driver="oracle.jdbc.driver.oracledriver" username="scott" password="tiger" url="jdbc:oracle:thin:@localhost:5521:oracle" inactivity-timeout="30" /> Otwarcie połączenia z bazą danych Context ctx = new InitialContext(); DataSource ds = (DataSource)ctx.lookup("jdbc/OracleDS"); Connection conn = ds.getconnection(); Przykład dla OC4J