Wykład 09
Transkrypt
Wykład 09
Plan Przetwarzanie dokumentów XML i zaawansowane techniki WWW Wykład 09 T. Romańczukiewicz Jagiellonian University 2009/2010 T. Romańczukiewicz XML 09 Plan Plan 1 Serwlety T. Romańczukiewicz XML 09 Serwlety Przypomnienie Serwlety - wstep ˛ Wstep ˛ Możliwości serwletów Dziele Plan 1 Serwlety Przypomnienie Serwlety - wstep ˛ Wstep ˛ Możliwości serwletów Dzielenie zasobów Instalacja w Tomcacie Podsumowanie T. Romańczukiewicz XML 09 Serwlety Przypomnienie Serwlety - wstep ˛ Wstep ˛ Możliwości serwletów Dziele XML, poprawnie sformuowanie Sposoby opisu XML DTD XML Schema XPATH Sposoby prezentacji CSS XSLT DOM SAX JAXB Serwlety T. Romańczukiewicz XML 09 Serwlety Przypomnienie Serwlety - wstep ˛ Wstep ˛ Możliwości serwletów Dziele Serwlet Serwlet Serwlety sa˛ małymi programami wykonywanymi w kontenerze serletów. Kontener serwletów działa podobnie jak serwer www, tzn. obsługuje zapytania klientów oraz generuje odpowiedzi. Kontener serwletów może być samodzielna˛ usługa, ˛ lecz cz˛eściej pracuje jako moduł serwera www Rozszerzaja˛ możliwośći serwera. Serwlety nie maja˛ interfejsu użytkownika, komunikuja˛ sie˛ z przegladark ˛ a˛ za pomoca˛ protokołu HTTP. Otrzymuja˛ one od serwera komplet informacji zebranych z interakcyjnych elementów strony (zwykle z pól formularza) i po ich przetworzeniu dostarczaja˛ gotowa˛ strone˛ WWW - przesyłana˛ przez serwer do użytkownika. Moga˛ korzystać ze standardowych klas Javy (z VM), klas wchodzacych ˛ w skład Servlet API: javax.servlet.* i javax.servlet.http.* oraz ewentualnie z dodatkowych bibliotek zainstalowanych na serwerze. T. Romańczukiewicz XML 09 Serwlety Przypomnienie Serwlety - wstep ˛ Wstep ˛ Możliwości serwletów Dziele Najcz˛estsze zastosowania przetwarzanie formularzy forwarding (przekierowanie do innego servletu) wyświetlania wyników zapytań do baz danych (strony JSP) Miejsce serwletów w aplikacjach J2EE serwlety to rozszerzenie serwera WWW blisko interfejsu użytkownika: zorientowane na żadanie/odpowiedź ˛ (request/response) serwlety działaja˛ w odpowiedzi na żadania klienta sa˛ interfejsem do serwera aplikacyjnego/bazy danych/EJB pełnia˛ role˛ kontrolera w schemacie Model-View-Controller, za widok odpowiedzialne sa˛ strony JSP (czyli kod Javy imieszczony w pliku html), model to EJB w serwletach zaleca sie˛ umieszczanie tylko lekkich funkcji biznesowych, ale w małych aplikacjach cała logika może być w serwletach i JSP T. Romańczukiewicz XML 09 Serwlety Przypomnienie Serwlety - wstep ˛ Wstep ˛ Możliwości serwletów Dziele Servlety a skrypty CGI Tradycyjnie funkcjonalność do stron WWW dodawana jest przy wykorzystaniu skryptów Common Gateway Interface. Interfejs CGI (niezależny od jezyka) ˛ pozwala na otwieranie nowego procesu na serwerze, który pobiera informacje o zapytaniu poprzez zmienne środowiskowe Wynik wypisywany jest do standardowego strumienia Każde zapytanie jest obsługiwane przez osobna˛ instancje˛ programu lub skryptu CGI Zalety serwletów Serwlety nie działaja˛ w osobnym procesie - nie sa˛ zatem tworzone procesy dla każdego zapytania Serwlet pozostaje w pamieci ˛ pomiedzy ˛ zapytaniami. CGI musi być każdorazowa ładowane do pamieci, ˛ cz˛esto razem z interpreterem Jest tylko jedna instancja serwletu obsługujaca ˛ wszystkie zapytania Bezpieczeństwo: serwlety można uruchamiać przy pomocy restrykcyjnej maszyny Sandbox T. Romańczukiewicz XML 09 Serwlety Przypomnienie Serwlety - wstep ˛ Wstep ˛ Możliwości serwletów Dziele Przykład Listing 1: Przykład kodu serwletu 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 import import import import import import java.io.IOException; java.io.PrintWriter; javax.servlet.ServletException; javax.servlet.http.HttpServlet; javax.servlet.http.HttpServletRequest; javax.servlet.http.HttpServletResponse; public class SimpleServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { PrintWriter out; response.setContentType("text/html"); out = response.getWriter(); out.println("<HTML><HEAD><TITLE>"); out.println("Hello world servlet"); out.println("</TITLE></HEAD><BODY>"); out.println("<H1>" + title + "</H1>"); out.println("<P>This is output from SimpleServlet."); out.println("</BODY></HTML>"); out.close(); } } T. Romańczukiewicz XML 09 Serwlety Przypomnienie Serwlety - wstep ˛ Wstep ˛ Możliwości serwletów Dziele Komunikacja z klientem przedefiniowanie metod doGet, doPost, doPut, doDelete. Te metody sa˛ wywoływane przez metode˛ service zdefiniowana˛ w Servlet przy każdym żadaniu ˛ do serwera dotyczacym ˛ serwletu. dane od klienta (przegladarki) ˛ sa˛ w obiekcie HttpServletRequest. Ważne metody obiektu request: getParameter - zwraca parametr, np. z formularza getCookies - daje ciasteczka getSession - podaje obiekt sesji getReader (dla danych tekstowych) getInputStream (dla danych binarnych) dane do klienta symbolizuje obiekt HttpServletResponse Ważne metody obiektu response: getWriter (dane tekstowe) getOutputStream (dane binarne) T. Romańczukiewicz XML 09 Serwlety Przypomnienie Serwlety - wstep ˛ Wstep ˛ Możliwości serwletów Dziele Przykład Listing 2: Przykład komunikacji - html 1 2 3 4 5 6 7 8 <html> <head><title>Formularz</title></head> <body> <form action="/trom/test" method="post"> Podaj tekst: <input type="text" name="tekst" value=""> </form> </body> </html> Listing 3: Przykład komunikacji 1 2 3 4 5 6 7 8 9 10 11 import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class TestServlet extends HttpServlet { public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { PrintWriter out; String tekst; T. Romańczukiewicz XML 09 Serwlety Przypomnienie Serwlety - wstep ˛ Wstep ˛ Możliwości serwletów Dziele Przykład Listing 4: Przykład komunikacji cd 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 response.setContentType("text/html"); out = response.getWriter(); out.println("<HTML><HEAD><TITLE>Wyniki z formularza"); out.println("</TITLE></HEAD><BODY>"); tekst = request.getParameter("tekst"); if (tekst != null) out.println("Z formularza otrzymalem: " + tekst); else out.println("Brak danych z formularza"); out.println("</BODY></HTML>"); out.close(); } public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { PrintWriter out; String tekst; response.setContentType("text/html"); out = response.getWriter(); out.println("<HTML><HEAD><TITLE>Uwaga</TITLE>"); out.println("</HEAD><BODY>"); out.println("Ten serwlet nie obsluguje metody GET!"); out.println("</BODY></HTML>"); out.close(); } } T. Romańczukiewicz XML 09 Serwlety Przypomnienie Serwlety - wstep ˛ Wstep ˛ Możliwości serwletów Dziele Serwlet to instancja klasy, która implementuje interfejs javax.servlet.Servlet Wiekszość ˛ serwletów rozszerza jedna˛ ze standardowych implementacji tego interfejsu: javax.servlet.GenericServlet i javax.servlet.http.HttpServlet Serwers aplikacji ładuje klase˛ serwletu i wywołuje bezargumentowy konstruktor Nastepnie ˛ wywoływana jest metoda serwletu init(ServletConfig config) Uwaga: serwlety korzystajace ˛ z javax.servlet.GenericServlet i javax.servlet.http.HttpServlet powinny wywoływać super.init(config) na poczatku ˛ metody init Metoda init wywoływana jest raz podczas cyklu życia serwletu. jeżeli coś pójdzie nie tak to należy rzucić wyjatek ˛ UnavailableException Metoda serviceServletRequest req, ServletResponse res) jest wywoływana po zakończeniu init dla każdego zapytania servletu. Może sie˛ zdarzyć, że metoda ta bedzie ˛ wywoływana wielokrotnie w tym samym czasie trzeba zapewnić wykluczanie recznie, ˛ np. używajac ˛ zmiennych/metod synchronized Na końcu cyklu życia serwletu wywoływana jest metoda destroy() Uwaga! Jeżeli metoda do[GetPost]| wykonuje sie˛ długo, to trzeba zadbać o jej zakończenie. Jeżeli serwlet uruchamiał watki, ˛ to też trzeba je przerwać. T. Romańczukiewicz XML 09 Serwlety Przypomnienie Serwlety - wstep ˛ Wstep ˛ Możliwości serwletów Dziele Protokół HTTP, zapytanie-odpowiedź Zapytanie HTTP składa sie˛ z metody zapytania, URI, nagłówka i ciała (pustego badź ˛ nie) Odpowiedź zawiera kod resultatu, nagłówek i ciało Metoda service() wysyła zapytanie do różnych metod Javy dla różnych zapytań HTTP Rozpoznawane sa˛ metody standardu HTTP/1.1: GET, HEAD, PUT, POST, DELETE, OPTIONS i TRACE Odpowiednia metoda XXX zapytania HTTP jest przekazywana do doXXX(HttpServletRequest req, HttpServletResponse res) W praktyce wykorzystuje sie˛ metody doGet, doPut, doPost, doDelete subclass of HttpServlet overrides one or more of these methods to provide a meaningful implementation. T. Romańczukiewicz XML 09 Serwlety Przypomnienie Serwlety - wstep ˛ Wstep ˛ Możliwości serwletów Dziele Utrzymywanie stanu (session tracking) To jedna z najważniejszych zalet serwletów. Nie ma tego w CGI. Schemat: HttpSession session = request.getSession(true); Klasa ref_obiektu1 = new Klasa(); (czytanie/pisanie) (pisanie) session.putAttribute("dluga.nazwa_atr", ref_obiektu1); (pisanie) Klasa ref_obiektu2 = (Klasa)session.getAttribute("dluga.nazwa_atr"); (czytanie) Cechy: Wkładanie i wyjmowanie obiektów z sesji nie ma nic wspólnego z interfejsem serializable. Obiekty nie sa˛ nigdzie składowane, tylko istnieja˛ w pamieci ˛ kontenera. Metody operuja˛ na referencjach. Po odczytaniu referencji metoda˛ getAttribute operujemy już na oryginalnym (jedynym!) obiekcie. Po odczytaniu atrybutu trzeba sprawdzić czy jest równy null, jeżeli tak to trzeba utworzyć nowy obiekt (uwaga na wielowatkowość). ˛ Sesje działaja˛ standardowo na ciasteczkach. W ciasteczku jest tylko id sesji, reszta siedzi w pamieci ˛ kontenera. Jeżeli przegladarka ˛ nie obsługuje ciasteczek to trzeba używać metody encodeURL(). Gdy serwlet ma wyświetlić link do drugiego serwletu to w metodzie doGet() trzeba umieścić: T. Romańczukiewicz XML 09 Serwlety Przypomnienie Serwlety - wstep ˛ Wstep ˛ Możliwości serwletów Dziele Użycie sesji Listing 5: Przykład użycia sesji 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class DodajProdukt extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { HttpSession session = request.getSession(true); Koszyk koszyk = (Koszyk) session.getAttribute("pl.zakupy.koszyk"); if (koszyk == null) { koszyk = new Koszyk(); session.setAttribute("pl.zakupy.koszyk", koszyk); } koszyk.dodaj(request.getParameter("produkt")); RequestDispatcher dispatcher = getServletContext().getRequestDispatcher("/wyswietl_koszyk.jsp"); if (dispatcher != null) dispatcher.forward(request, response); } } Po modyfikacji koszyka nie trzeba go specjalnie zapisywać do sesji. W skrypcie /wyswietl_koszyk.jsp wyświetlana jest zawartość koszyka. T. Romańczukiewicz XML 09 Serwlety Przypomnienie Serwlety - wstep ˛ Wstep ˛ Możliwości serwletów Dziele Użycie sesji jest wskazane, jednak można też używać cookies: Listing 6: Ciasteczka 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { response.setContentType("text/html"); PrintWriter out = response.getWriter(); / / p r i n t out cookies Cookie[] cookies = request.getCookies(); for (int i = 0; i < cookies.length; i++) { Cookie c = cookies[i]; String name = c.getName(); String value = c.getValue(); out.println(name + " = " + value); } / / set a cookie String name = request.getParameter("cookieName"); if (name != null && name.length() > 0) { String value = request.getParameter("cookieValue"); Cookie c = new Cookie(name, value); response.addCookie(c); } } T. Romańczukiewicz XML 09 Serwlety Przypomnienie Serwlety - wstep ˛ Wstep ˛ Możliwości serwletów Dziele Dzielenie zasobów miedzy ˛ serwlety (ServletContext) ServletContext context = getServletContext(); Klasa ref_obiektu1 = new Klasa(); (czytanie/pisanie) (pisanie) context.setAttribute("dluga.nazwa_atr", ref_obiektu1); Klasa ref_obiektu2 (pisanie) = context.getAttribute("dluga.nazwa_atr"); (czytanie) Przechowywanie podobne jak w sesji, ale te same obiekty sa˛ dostepne ˛ dla wszystkich serwletów na serwerze (w kontenerze). Uwaga na nazwy atrybutów, żeby dwie różne aplikacje nie korzystały z tego samego atrybutu. Listing 7: Przykład użycia kontekstu 1 2 3 4 5 6 7 8 9 10 11 12 13 14 public class WyswietlDane extends HttpServlet { public synchronized void init() throws ServletExcpetion { BazaDanych bd = (BazaDanych) getServletContext().getAttribute("pl.sklep.bd.baza"); if (bd == null) { bd = new BazaDanych("http://pulsar", "scott", "tiger"); getServletContext().setAttribute("pl.sklep.bd.baza", bd); } } ... } T. Romańczukiewicz XML 09 Serwlety Przypomnienie Serwlety - wstep ˛ Wstep ˛ Możliwości serwletów Dziele Serwlety maja˛ dostep ˛ do innych serwletów w tym samym kontekście (zazwyczaj katalogu), reprezentowanym poprzez javax.servlet.ServletContext. ServletContext jest dostepny ˛ poprzez metode˛ getServletContext obiektu ServletConfig Liste˛ dostepnych ˛ servletów można uzyskać poprzez metode˛ getServletNames Po otrzymaniu referencji do innego serwletu można wywoływac jego metody. Należy jednak zrzutować dany obiket na typ żadanej klasy (ClassLoader) Przykład Servlet FooServlet chce wywołać metode˛ public T. Romańczukiewicz void bar() XML 09 serwletu BarServlet Serwlety Przypomnienie Serwlety - wstep ˛ Wstep ˛ Możliwości serwletów Dziele Listing 8: FooServlet.java 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 public class FooServlet extends HttpServlet { protected void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { ... ServletContext context = getServletConfig().getServletContext(); BarInterface bar = (BarInterface)context.getServlet("BarServlet"); bar.bar(); .. } ... } \begin{lstlisting} Listing 9: BarInterface 1 2 3 4 public interface BarInterface { public void bar(); } T. Romańczukiewicz XML 09 Serwlety Przypomnienie Serwlety - wstep ˛ Wstep ˛ Możliwości serwletów Dziele Listing 10: BarServlet.java 1 2 3 4 5 6 7 8 public class BarServlet extends HttpServlet implements BarInterface { public void bar() { System.err.println(""bar() called""); } ... } T. Romańczukiewicz XML 09 Serwlety Przypomnienie Serwlety - wstep ˛ Wstep ˛ Możliwości serwletów Dziele Instalacja serwletu w Tomcacie Zakładamy, że Tomcat już działa (np. zintegrowany z Apachem) i korzysta z katalogu #TOMCAT_HOME. Uwaga: pozostałe ścieżki i nazwy sa˛ b. ważne. Kompilujemy serwlet korzystajac ˛ z biblioteki servlet.jar: javac -classpath #TOMCAT_HOME/lib/servlet.jar Test.java Plik Test.class kopiujemy do katalogu #TOMCAT_HOME/webapps/testkatalog/WEB-INF/classes Tworzymy plik #TOMCAT_HOME/webapps/testkatalog/WEB-INF/web.xml zawierajacy ˛ informacje o serwlecie Listing 11: web.xml 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN" "http://java.sun.com/j2ee/dtds/web-app_2_2.dtd"> <web-app> <servlet> <servlet-name> test_serw <servlet-class> Test </servlet> </servlet-name> </servlet-class> <servlet-mapping> <servlet-name> test_serw </servlet-name> <url-pattern> /test </url-pattern> </servlet-mapping> </web-app> T. Romańczukiewicz XML 09 Serwlety Przypomnienie Serwlety - wstep ˛ Wstep ˛ Możliwości serwletów Dziele Serwlet można uruchomić poprzez http://localhost:8180/testkatalog/test Port obsługujacy ˛ Tomcata można odczytać np z pliku #TOMCAT_HOME/conf/server.xml jako atrybut znacznika <Connector port="8180"... >. Inne popularne porty to 8080, 8009 T. Romańczukiewicz XML 09 Serwlety Przypomnienie Serwlety - wstep ˛ Wstep ˛ Możliwości serwletów Dziele Podsumowanie Serwlety - niewielkie programy javowe (podobnie jak aplety) ale wykonujace ˛ sie˛ po stronie serwera Sa˛ alternatywa˛ dla CGI; tak samo można używać do obsługi formularzy, przysłania danych itp. Serwlety korzystaja˛ z protokołu zapytań HTTP Request (get, post itp) Pozostaja˛ w pamieci ˛ przez cały czas, nie ma potrzeby ładowania ich przy każdym zapytaniu - metoda init() działa tylko raz Moga˛ obsługiwać sesje, ciasteczka Moga˛ sie˛ ze soba˛ komunikować T. Romańczukiewicz XML 09