Aplikacje WWW 1 Plan wykładu 2 CGI, serwlety Java i szablony JSP dr inŝ. Mikołaj Morzy Instytut Informatyki Politechniki Poznańskiej Mikolaj.Morzy@put.poznan.pl Metody konstrukcji logiki prezentacji Programy CGI Serwlety Java implementacja korzystanie z nagłówków HTTP obsługa zmiennych Cookies obsługa sesji HTTPSession Szablony JSP cykl Ŝycia deklaracje dyrektywy skryptlety język EL Logika prezentacji I Implementacja logiki prezentacji 3 Przykład: serwlety vs. szablony 4 Zadania logiki prezentacji Technologie serwletów programy CGI serwlety Java Technologie szablonów JavaServer Pages PHP ASP.NET <% String imie = request.getparameter("imie"); %> <HTML> serwlet <BODY> import javax.servlet.http.*; <H2>Witaj <%=imie%></h2> import java.io.*; </BODY> szablon </HML> public class MyServlet1 extends HttpServlet { public void doget(httpservletrequest request, HttpServletResponse response) throws IOException { String imie = request.getparameter("imie"); response.setcontenttype("text/html"); PrintWriter out = response.getwriter(); out.println("<html><body>"); out.println("<h2>witaj "+imie+"</h2>"); out.println("</body></html>"); }}
Architektura CGI 5 Cechy programów CGI 6 Przeglądarka klient HTTP HTTP serwer HTTP program CGI logika biznesowa Dowolny język programowania Proces uruchamiany przez serwer HTTP w odpowiedzi na Ŝądanie klienta HTTP Parametry wejściowe zmienne środowiskowe wejście standardowe Dokument wynikowy wyjście standardowe Wydajność, bezpieczeństwo Wybrane zmienne środowiskowe CGI 7 Zmienne środowiskowe CGI - przykład 8 SERVER_SOFTWARE SERVER_NAME REQUEST_METHOD QUERY_STRING REMOTE_HOST REMOTE_ADDR HTTP_USER_AGENT show-cgi.bat @echo off echo Content-Type: text/html echo. echo SERVER_SOFTWARE: %SERVER_SOFTWARE% ^<BR^> echo SERVER_NAME: %SERVER_NAME% ^<BR^> echo REQUEST_METHOD: %REQUEST_METHOD% ^<BR^> echo QUERY_STRING: %QUERY_STRING% ^<BR^> echo REMOTE_HOST: %REMOTE_HOST% ^<BR^> echo REMOTE_ADDR: %REMOTE_ADDR% ^<BR^> echo HTTP_USER_AGENT: %HTTP_USER_AGENT% ^<BR^>
Przykładowy program CGI (1) 9 Przykładowy program CGI (2) 10 test-cgi.bat @echo off echo Content-type: text/html echo. echo ^<HTML^>^<BODY^> echo ^<H2^> echo Witaj echo %QUERY_STRING%! echo Oto lista moich plików: echo ^<PRE^> dir /b c:\pliki... HTTP/1.1 200 OK Date: Sat, 24 Jun 2006... Server: Apache/1.0.0 Content-Type: text/html Content-Length: 152 <HTML><BODY> <H2>Witaj Maciej! Oto lista moich plików: <PRE> demo.exe foto1.jpg... nph-test-cgi.bat @echo off echo HTTP/1.0 200 OK echo Content-type: text/html echo Expires: Thu, 25 Jun 2006 16:00:00 GMT echo. echo ^<HTML^>^<BODY^> echo ^<H2^> echo Witaj %QUERY_STRING%!... HTTP/1.0 200 OK Content-type: text/html Expires: Thu, 25 Jun 2006 16:00:00 GMT Content-Length: 152 <HTML><BODY> <H2> Witaj Marek!... Parametry Ŝądania HTTP 11 Architektura serwletów Java 12 Rozkaz GET zmienna QUERY_STRING Rozkaz POST standardowe wejście Konieczność programowego wyodrębniania parametrów z łańcucha znakowego Przeglądarka HTTP serwer HTTP serwer aplikacji Java EE serwlet Java logika biznesowa wylot=pozna%f1&przylot=new+york&godzina=11%3a00 klient HTTP wylot="poznań", przylot="new York", godzina="11:00"
Struktura serwletu Java 13 Przykładowy serwlet Java 14 Klasa dziedzicząca z HttpServlet Implementacja co najmniej jednej z metod: doget() dopost() init() destroy() import javax.servlet.http.*; import java.io.*; public class MyServlet1 extends HttpServlet { public void doget(httpservletrequest request, 1 HttpServletResponse response) throws IOException { 2 3 4 5 }} String imie = request.getparameter("imie"); response.setcontenttype("text/html"); PrintWriter out = response.getwriter(); out.println("<html><body>"); out.println("<h2>witaj "+imie+"</h2>"); out.println("</body></html>"); Cykl Ŝycia serwletu Java 15 Interfejs HttpServletRequest 16 Przeglądarka klient HTTP 1 serwer aplikacji Java EE 4 doget() init() 2 destroy() 3 n Cookie[] getcookies() String getheader(n) String getmethod() String getremoteuser() HttpSession getsession() String getparameter(n) String getremoteaddr() Ŝądanie HTTP MyServlet1 doget() init() destroy() request
HttpServletRequest a zmienne CGI 17 HttpServletRequest - przykład 18 SERVER_NAME REQUEST_METHOD QUERY_STRING REMOTE_HOST REMOTE_ADDR REMOTE_USER String getservername() String getmethod() String getquerystring() String getremotehost() String getremoteaddr() String getremoteuser() response.setcontenttype("text/html"); PrintWriter out = response.getwriter(); out.println("<html><body>"); out.println("server_name="+request.getservername()+"<br>"); out.println("request_method="+request.getmethod()+"<br>"); out.println("query_string="+request.getquerystring()+"<br>"); out.println("remote_host="+request.getremotehost()+"<br>"); out.println("remote_addr="+request.getremoteaddr()); out.println("</body></html>"); Odczyt parametrów Ŝądania HTTP 19 Serwlety Java - metoda dopost() 20 request.getparameter() request.getparameternames() request.getparametervalues() Metoda doget() odpowiada na Ŝądania typu GET Metoda dopost() odpowiada na Ŝądania typu POST Jednakowy dostęp do parametrów Ŝądania Identyczne lub róŝne implementacja float x = Float.parseFloat(request.getParameter("x")); float y = Float.parseFloat(request.getParameter("y")); float result = x * y; response.setcontenttype("text/html"); PrintWriter out = response.getwriter(); out.println("<html><body>"); out.println(x + " x " + y + " = " + result); out.println("</body></html>"); public class MyServlet extends HttpServlet { public void doget(httpservletrequest request, HttpServletResponse response) throws IOException {...} public void dopost(httpservletrequest request, HttpServletResponse response) throws IOException {...}}
Interfejs HttpServletResponse 21 Metoda senderror() - kody zwrotne 22 void addcookie(c) void addheader(n,v) void senderror(v) void sendredirect(url) void setheader(n,v) PrintWriter getwriter() ServletOutputStream getoutputstream() void flushbuffer() response odpowiedź HTTP SC_BAD_REQUEST SC_UNAUTHORIZED SC_FORBIDDEN SC_NOT_FOUND SC_GONE (400) Niewłaściwy format Ŝądania (401) Wymagana autoryzacja klienta (403) Odmowa dostępu (404) Dokument nie znaleziony (410) Dokument zmienił adres, a nowa lokalizacja nie jest znana SC_SERVICE_UNAVAILABLE (503) System jest chwilowo przeciąŝony lub niedostępny SC_NOT_MODIFIED (304) Dokument nie uległ modyfikacji od poprzedniego dostępu Metoda senderror() - przykład 23 Obsługa zmiennych Cookies 24 if (!request.getremoteaddr().equals("192.168.0.3")) response.senderror(httpservletresponse.sc_forbidden); else out.println("<h1>welcome!</h1>"); Zmienne Cookies reprezentowane w postaci obiektów klasy Cookie Wysyłanie zmiennych Cookies: response.addcookie() Odczyt zmiennych Cookies: request.getcookies()
Klasa Cookie 25 Wysyłanie zmiennych Cookies 26 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ą o nazwie n i wartości s Odczytuje/ustawia adres domenowy, dla którego przeznaczona jest zmienna Odczytuje/ustawia czas Ŝycia zmiennej, liczony w sekundach (-1 -> ulotne) Odczytuje/ustawia nazwę zmiennej Odczytuje/ustawia prefiks ścieŝki URL na serwerze, dla której przeznaczona jest zmienna Odczytuje/ustawia wartość zmiennej 1 Cookie c1 = new Cookie("Imie","Maciej"); 2 Cookie c2 = new Cookie("Miasto","Poznań"); 3 c1.setmaxage(24*60*60); 4 response.addcookie(c1); 5 response.addcookie(c2); nagłówek odpowiedzi HTTP HTTP/1.0 200 OK Set-Cookie: Imie=Maciej; Expires=Mon, 03-Jul-2006 17:48:36 GMT Set-Cookie: Miasto=Poznań... Odczytywanie zmiennych Cookies 27 Sesje HTTPSession 28 1 2 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>"); 3 Problem: protokół HTTP jest bezstanowy Emulacja sesji KaŜda sesja otrzymuje identyfikator Stan sesji przechowywany przez serwer aplikacji Stan sesji usuwany po wygaśnięciu czasu waŝności nagłówek Ŝądania HTTP GET /MyServlets/MyServlet2 HTTP/1.0 Cookie: Imie=Maciej; Miasto=Poznań...
Architektura HTTPSession 29 Interfejs HTTPSession 30 ID=324 klient HTTP ID=567 klient HTTP Ŝądanie HTTP serwlet Java serwer aplikacji HTTPSession tablica sesjii ID CZAS_DOSTĘPU STAN... 324 20:45 x: y: 567 20:20 x: 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 etykiecie 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 Wykorzystywanie HTTPSession 31 HTTPSession czy Cookies? 32 1 2 3 Pracownik p = new Pracownik(); p.imie = "Maciej"; p.miasto = "Poznań"; HttpSession sess = request.getsession(true); sess.setattribute("prac1", p); Oba mechanizmy pozwalają przechowywać stan sesji Cookies wymaga przesyłania obiektów stanu w nagłówkach HTTP HTTPSession obsługuje dowolne typy obiektów stanu Bezpieczeństwo 4 5 HttpSession sess = request.getsession(false); Pracownik e = (Pracownik) sess.getattribute("prac1"); out.println(e.imie + " " + e.miasto);
JSP - wprowadzenie 33 Przykład prostej strony 34 Technologia umoŝliwiająca łącznie statycznego kodu HTML lub XML z dynamicznym kodem Java Rozszerzenie technologii serwletów Podstawowe narzędzie tworzenia warstwy prezentacji w architekturze Java EE Historia wersja JSP 1.2 i Servlet 2.3 częścią J2EE 1.3 (1999) wersja JSP 2.0 i Servlet 2.4 częścią J2EE 1.4 wersja JSP 2.1 i Servlet 2.5 częścią Java EE 5 Platform <%@ page language="java" %> <html> <head> <title>eurokonwerter v.0.1</title> </head> <body> <jsp:include page="header.jsp"/> <%! double priceeur = 10, pricepln = 0; %> <%! Double ratiopln2eur = 4.75; %> <% pricepln = priceeur * ratiopln2eur; %> <p> Kwocie <%= priceeur %> euro odpowiada <%= pricepln %> zlotych </body> </html> dyrektywa akcja deklaracja skryptlet statyczne dane wyraŝenie 35 36 Schemat działania JSP Cykl Ŝycia JSP jspinit() załadowanie zasobów Ŝądanie odpowiedź _jspservice() przetwarzanie Ŝądań jspdestroy() zwolnienie zasobów
Dyrektywy 37 Deklaracje 38 Kontrolują sposób translacji JSP do serwletu <%@ include %>: włączenie zewnętrznego pliku file <%@ page %>: ustawienia strony import, contenttype, errorpage, iserrorpage, info, buffer, session, autoflush, extends, isthreadsafe, iselenabled <%@ taglib %>: wskazanie na bibliotekę znaczników prefix, uri Pozwalają na deklarowanie metod i składowych serwletu wynikowego Mogą zawierać inicjalizację Wprowadzane przez znaczniki <%! %> <%! int licznik = 0; %> <%! int a, b, c; %> <%! Array mojatablica = new Array(); %> <%! int ktoragodzina() { Calendar cal = new GregorianCalendar(); return cal.get(calendar.hour_of_day); } %> Skryptlety 39 Skryptlety i HTML 40 Znaczniki XML umoŝliwiające osadzanie kodu Java Mogą generować kod HTML lub XML za pomocą predefiniowanego obiektu out Wprowadzane przez znaczniki <% %> Instrukcje warunkowe: uwaga na nawiasy! <html> <body> <% Calendar today = new GregorianCalendar(); int now = today.get(calendar.hour_of_day); <% Calendar dzis = new GregorianCalendar(); int godzina = dzis.get(calendar.hour_of_day); out.println("<b>jest godzina " + godzina + "</B>"); %> if (now <= 15) { %> <b> jest jeszcze przed piętnastą </b> <% } else { %> <b> jest juŝ po piętnastej </b> <% } %> </body> </html>
WyraŜenia 41 Znaczniki JSP (akcje) 42 Znaczniki XML umoŝliwiające wartościowanie wyraŝenia Wartość konwertowana do łańcucha znaków i włączana do wynikowego kodu HTML lub XML Wprowadzane przez znaczniki <%= %> Znaczniki XML wywołujące akcje serwera aplikacji Dostępne akcje <jsp:include>: włączenie zewnętrznego kodu <jsp:forward>: przekazanie sterowania <jsp:param>: zdefiniowanie parametru <jsp:plugin>: obsługa apletów Java <jsp:fallback>: gdy klient nie obsługuje apletów <%! Calendar today = new GregorianCalendar(); %> <P>Dzisiejsza data to <%= today.get(calendar.day_of_month) %>, <%= today.get(calendar.month) %>, roku <%= today.get(calendar.year) %> </P> i znaczniki do obsługi komponentów JavaBean Obiekty predefiniowane 43 Obsługa wyjątków 44 Bogaty zestaw predefiniowanych obiektów config: dostęp do parametrów inicjalizacyjnych request: Ŝądanie otrzymane od klienta HTTP Strona obsługująca wyjątki wskazywana przez dyrektywę <%@ page errorpage="errorhandler.jsp" %> response: odpowiedź wysłana klientowi HTTP session: sesja HTTP application: kontekst aplikacji pagecontext: kontekst strony wraz ze zmiennymi out: strumień stanowiący odpowiedź dla klienta HTTP page: serwlet wynikowy dla dokumentu JSP musi zawierać dyrektywę <%@ page iserrorpage="true" %> najczęściej importuje zawartość pakietu java.io <%@ page import="java.io.*" %> Dostęp do wyjątku przez obiekt exception Specjalny wyjątek JspException
Wywołanie strony JSP z serwletu 45 Wywołanie strony JSP z serwletu - przykład 46 Wywołanie strony JSP z serwletu pobranie kontekstu serwletu pobranie zarządcy Ŝądań przekierowanie przez include() lub forward() Przekazanie danych z serwletu do strony JSP umieszczenie parametrów w adresie URL wykorzystanie obiektu request simpleservlet.java ServletContext ctx = this.getservletcontext(); RequestDispatcher dispatcher = ctx.getrequestdispatcher("/simplepage.jsp"); request.setattribute("name","james Bond"); dispatcher.forward(request,response); simplepage.jsp <%@page contenttype="text/html"%> <html> <body> <h1>jsp Page</h1> Hello <%= request.getattribute("name") %>! </body> </html> Język wyraŝeń EL - wprowadzenie 47 JSP EL - wyraŝenia 48 Niewygodna składnia wyraŝeń JSP <tag attribute="<%= request.getattribute("name") %>"> Język wyraŝeń (JSP Expression Language, JSP EL) wprowadzony w JSP 2.0 uproszczenie kodu: <tag attribute="${name}"> opcjonalność: <%@ page iselignored="true" %> dodatkowe obiekty predefiniowane zmienne: tablice, mapy, listy, własności ewaluacja wyraŝeń, warunków logicznych WyraŜenia JSP EL mogą się znaleźć: w statycznym tekście w atrybucie znacznika standardowego lub znacznika zdefiniowanego przez uŝytkownika WyraŜenia w notacji ${zmienna.pole} Automatyczna konwersja typu wynikowego wyraŝenia do oczekiwanego typu
JSP EL obiekty predefiniowane 49 JSP EL literały i operatory 50 Dodatkowe obiekty predefiniowane: pagecontext: pełen kontekst strony JSP param: wartość parametru paramvalues: tablica wartości parametru header: wartość nagłówka HTTP headervalues: tablica wartości nagłówka HTTP cookie: wartość ciasteczka initparam: wartość parametru inicjalizacyjnego pagescope, requestscope, sessionscope, applicationscope Literały logiczne: true i false liczby całkowite i zmiennoprzecinkowe łańcuchy znaków Operatory arytmetyczne: + - * / % mod div logiczne: and or not &&! porównania: ==!= => > <= < lt gt le ge eq ne empty, warunkowy A? B : C JSP EL - przykład simpleservlet.java ServletContext ctx = this.getservletcontext(); RequestDispatcher dispatcher = ctx.getrequestdispatcher("/simplepage.jsp?code=007"); request.setattribute("name","james Bond"); dispatcher.forward(request,response); simplepage.jsp <%@page contenttype="text/html"%> <html> <body> Hello ${name}! Your browser is ${header["user-agent"]}. Your secret code is ${param.code}. </body> </html> 51 Podsumowanie Dwa podejścia do konstrukcji logiki prezentacji Przykładowe technologie serwletów Zagadnienia implementacji serwletów Java Serwlety Java wymagają specjalizowanego serwera aplikacji 52
Materiały dodatkowe 53 "The Common Gateway Interface", http://hoohoo.ncsa.uiuc.edu/cgi/ "FastCGI Home", http://www.fastcgi.com "Java EE At a Glance", http://java.sun.com/javaee "Java EE 5 SDK", http://java.sun.com/javaee/5/docs/api/