JSP - Kolos
Transkrypt
JSP - Kolos
Marcin Paszkowski Przegląd technologii JSP Czego potrzebujemy? Do obsługi serwletów oraz JSP – używamy kontenera. Czym on jest? Zapewnia on prosty mechanizm komunikacji pomiędzy serwletami a serwerem www. Zadania które wykonuje za nas kontener to m.in.: 1. buduje gniazda serwera 2. nasłuchuje komunikacje na odpowiednim porcie 3. zapewnia interfejs API pomiędzy serwerem www a kodem naszej aplikacji internetowej 4. zapewnia on wczytywanie odpowiednich klas, ich inicjalizacje, wywołanie odpowiednich metod 5. obsługuje wielowątkowość (wciąż jednak programista musi zadbać o ich bezpieczeństwo, Np. ich synchronizacja) 6. wymusza na nas stosowanie deskryptora rozmieszczeń - w pliku XML – w których konfigurujemy mechanizmy zabezpieczeń – bez ingerencji w kodzie Javy. 7. Uruchamia strony JSP. Tomcat – to przykład takiego kontenera. Kiedy serwer www otrzymuje żądanie dotyczące serwletu – serwer nie przekazuje tego żądania do serwletu – ale właśnie do kontenera, w którym to serwlet jest umieszczony. Czym jest deskryptor rozmieszczenia? Określa on w jaki sposób należy wykonać serwlety tudzież strony JSP. Deskryptor rozmieszczenia to nic innego jak prosty dokument XML – określający odwzorowanie adresów URL na serwlety. Przykład deskryptora – zostanie zaprezentowany w przykładzie prostej aplikacji internetowej. Przykład wykorzystania modelu MVC – dla serwletów i stron JSP MVC – czyli model – widok - kontroler to przykład wzorca projektowego. Główna idea tegoż – to oddzielenie warstwy biznesowej od warstwy prezentacji. W przypadku tworzenia aplikacji internetowej – z wykorzystaniem szeroko rozumianej technologii Javy ( czyli m.in. JSP, serwletów ) model MVC mógłby wyglądać tak: serwlet KONTROLER Kod Javy JSP WIDOK MODEL 1 Kontroler – Pobiera z żądania dane wejściowe użytkownika. Nakazuje modelowi samoaktualizację i sprawia że stan zmienionego modelu jest dostępny dla widoku. Model – Przechowuje logikę biznesową, stan aplikacji. Model może np. współpracować z bazą danych. Widok – To warstwa prezentacji. Otrzymuje od kontrolera stan modelu. Przykład prostej aplikacji internetowej Poniższy przykład oparty jest na aplikacji opisanej w książce Bahama, Sierra i Batesa – „Head First Servlets and JSP”. W niniejszym przykładzie – korzystamy z kontenera Tomcat. Oto struktura katalogów naszej aplikacji: TOMCAT webapps projekt WEB-INF classes form.html wynik.jsp web.xml com example web model WyborPiwa.class EkspertPiwny.class TOMCAT – katalog domowy Tomcata ( Np. jakarta-tomcat-5.0.19 ) Webapps – katalog wymagany przez kontener odgórnie Projekt – nazwa naszej aplikacji ( każdy projekt w Tomcat musi mieć swój katalog ) Web.xml – nasz deskryptor rozmieszczenia – znajduje się w katalogu: WEB-INF. Jest to wymagane! 1. Tworzymy kod formularza w HTML (form.html): <html><body> <h1 align="center">strona wyboru piwa</h1> <fomr method="POST" action="WybierzPiwo.do"> Wybierz właściwości piwa <p> Kolor: <select name="kolor"> <option>jasny 2 <option>żółty <option>brązowy <option>ciemny </select> <br><br> <center> <input type="SUBMIT"> </center> </body></html> Wyjaśnienie: „WybierzPiwo.do” – jest to nazwa, którą wykorzystujemy do wywołania odpowiedniego serwletu. Jest to nazwa logiczna, która nie ma swojego odzwierciedlenia w strukturze plików. Jest ona znana klientom aplikacji. „kolor” – w nim przykazujemy informacje z formularza do konkretnego skryptu. 2. Tworzymy deskryptor rozmieszczenia (web.xml): <web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemalocation="http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" version="2.4"> <servlet> <servlet-name>R3 Piwo</servlet-name> <servlet-class>com.example.web.WyborPiwa</servlet-class> </servlet> <servlet-mapping> <servlet-name>R3 Piwo</servlet-name> <servlet-class>/WybierzPiwo.do</servlet-class> </servlet-mapping> </web-app> Wyjaśnienie: „R3 Piwo” – sztuczna nazwa wykorzystywana w ramach tego samego pliku – w tym przypadku Web.xml. „com.example.web.WyborPiwa” – nazwa pliku klasy serwletu. ( umieszczona ona jest w pakiecie ). „WybierzPiwo.do” – klient w ten sposób odwołuje się do naszego serwletu. ( końcówka do nie jest obowiązkowa – jednak przyjęło się ją nieformalnie stosować ). 3. Budowa klasy modelu ( EkspertPiwny.java ) – czyli Java w „czystej” postaci: package com.example.model; import java.util.*; public class ExpertPiwny { public ArrayList getMarki( String kolor ) { ArrayList<String> marki = new ArrayList<String>(); if( kolor.equals( "bursztynowy" ) ) 3 { marki.add( "Jack Amber" ); marki.add( "Red Moode" ); } else { } marki.add( "Jail Pale Ale" ); marki.add( "Gout Stout" ); return (marki); } } 4. Budowanie klasy serwletu – tworzenie kontrolera ( WyborPiwa.java ): package com.example.web; import import import import java.io.*; java.util.*; javax.servlet.*; javax.servlet.http.*; import model.ExpertPiwny; public class WyborPiwa extends HttpServlet { public void doPost( HttpServletRequest request, HttpServletResponse response ) throws IOException, ServletException { String c = request.getParameter( "kolor" ); ExpertPiwny be = new ExpertPiwny(); List wynik = be.getMarki( c ); request.setAttribute( "styles", wynik ); requestDispatcher view = request.getRequestDispatcher( "wynik.jsp" ); view.forward( Request, response ); } } Wyjaśnienie: „doPost” – skoro formularz wysyła żądanie używając atrybutu method=”POST”, analogicznie korzystamy z odpowiednika POST-a w serwecie – czyli metody doPost. „String c = Request.getParameter( ”kolor” )” – argument tej metody – kolor – odpowiada użytej przy tworzeniu formularza wartości atrybutu name znacznika <select>. „package”. „Request.setAttribute( „styles”, wynik )” - dodajemy do obiektu żądania, który będzie wykorzystywany przez stronę JSP. Będzie ona wykorzystywała atrybut styles. „requestDispatcher view = Request.getRequestDispatcher( ”Wynik.jsp” )” – tworzony jest egzemplarz klasy, przekazujący żądanie do właściwej strony JSP. 4 „view.foraward( Request, response )” – wymuszamy na kontenerze zaangażowania wskazanej strony JSP. 5. Budowanie widoku JSP (wynik.jsp) <%@ page import="java.util.*" %> <html> <body> <h1 align="center">JSP z rekomendacjami dotyczącymi piwa</h1> <p> <% List styles = (List)request.getAttribute("styles"); Iterator it = styles.iterator(); while( it.hasNext() ) { out.print( "<br>Sprobuj: " + it.next() ); } %> </body> </html> Wyjaśnienie: „List styles = (List)Request.getAttribute(”styles”)” – w tym miejscu pobieramy atrybut z obiektu żądania. Uruchamianie serwletów i JSP ( na przykładzie naszej aplikacji ) 1. Kompilacja pliku – „EkspertPiwny.java”: javac -classpath C:\jakarta-tomcat-5.0.19\common\lib\servlet-api.jar:classes:.-d src\com\example\model\EkspertPiwny.java Utworzony plik: EkspertPiwny.class – załadowany jest dzięki parametrowi –d do folderu classes. 2. Kompilacja pliku – „WyborPiwa.java”: javac -classpath C:\jakarta-tomcat-5.0.19\common\lib\servlet-api.jar:classes:.-d src\com\example\web\WyborPiwa.java Utworzony plik: WyborPiwa.class – załadowany jest dzięki parametrowi –d do folderu classes. 3. Uruchamiamy Tomcata poleceniem – startup.bat 4. Plik JSP – automatycznie jest kompilowany przez kontener po otrzymaniu pierwszego żadania dotyczącego naszej aplikacji. Zrzuty działającej aplikacji Po wpisaniu w okno przeglądarki polecenia: http://localhost:8080/projekt/form.html - odpalimy nasz program: 5 Widok po otwarciu pliku fomr.html Po wybraniu koloru – aplikacja powinna na zarekomendować konkretne piwo Więcej o technologii JSP Strona JSP jest tłumaczona na serwlet. Wykonuje to za nas kontener WWW. Na początku więc – kod strony JSP tłumaczony jest na postać kodu źródłowego klasy Java ( *.java ), po czym następuje kompilacja na postać serwletu. Dyrektywa page służy do importowania niezbędnych pakietów używanych na stronie JSP: Np. package pakiet; public class licznik { //ciało klasy public static int getLiczba() { //ciało metody } } Aby teraz wykorzystać klasę Javy w naszym pliku JSP, wykonujemy: <%@ page import="pakiet.*”%> <html><body> <% out.println( licznik.getLiczba() ); %> </body></html> Aby zaimportować wiele pakietów piszemy: <%@ page import="pakiet.*, java.util.*”%>. Znaczek <%@ - oznacza dyrektywę. W powyższym przykładowym kodzie JSP – zbędne jest użycie metody println: wystarczy napisać: <%= licznik.getLiczba() %> - a wynik i tak będzie wyświetlony na stronie. Są to tzw. wyrażenia – tłumaczone one są na argumenty wywołań out.print(). Skryptlet: <% %> 6 Dyrektywa <%@ %> Wyrażenie <%= %> Pomiędzy <%! i %> możemy deklarować w kodzie JSP zmienne jaki i metody które są umieszczane w wygenerowanej klasie serwletu. Np. <html><body> <%! int podwojenie() { liczba = liczba * 2; return liczba; } %> <%! int liczba = 1; %> Liczba wynosi: <%= podwojenie() %> </body></html> W kodzie JSP można umieszczać dwa rodzaje komentarzy: < !--komentarz HTML-- > i <%-- komentarz JSP --%> Krótki przegląd standardowej biblioteki znaczników (JSTL) JSTL – to stworzona przez kogoś i upakowana biblioteka znaczników, z których możemy w prosty sposób korzystać w naszych stronach JSP. Okazuje się że można również definiować swoje znaczniki. Przykład: Kod serwletu: ... String[] listaFilmow = { "Solaris", "Kroll", "Psy" }; request.setAttribute( "listaFilmow", listaFilmow ); ... Kod JSP: <table> <% String[] elementy = (String[])request.getAttribute( "listaFilmow" ); String zmienna = null; for( int i=0 ; i<elementy.length ; i++ ) { zmienna = elementy[ i ]; %> <tr><td><%= zmienna %></td></tr> <% } %> </table> Wykorzystując jednak bibliotekę znaczników nasz kod może wyglądać tak: Kod JSP z wykorzystaniem JSTL: <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <html><body> <strong>Lista filmów</strong> <br> <table> 7 <c:forEach var="film" items="${listaFilmow}" <tr> <td>${film}</td> </tr> </c:forEach> </table> </body></html> Opis niektórych znaczników z biblioteki JSTL: <c:forEach> Jest on jakby odpowiednikiem pętli for. Powtarza on się dla każdego elementu czy to tablicy, odpowiedniej kolekcji tudzież łańcucha w postaci separatora. Znacznik ten możemy zagnieżdżać. <c:if> Odpowiednik kluczowego słowa if – dostępnego w większości języków programowania. Znacznik <c:choose> oraz <c:when> i <c:otherwise> Jest to jakby odpowiednik instrukcji swich, z tym że wybór może być tylko jeden. Np. <c:choose> <c:when test=”${preferencje == ‘bialy’}”> Lubisz kolor biały! </c:when> <c:when test=”${preferencje == ‘czerwony’}”> Lubisz kolor biały! </c:when> <c:otherwise> Nie lubisz czerwonego i białego? </c:otherwise> </c:choose> <c:set> Znacznik ten służy np. do dodania nowego elementu dla klasy Map. (Nie możemy dodać elementów do list lub tablic). <c:import> Np. <c:import url=”http://www.buldog.pl/index.html”> - czyli dodaje do bieżącej strony zawartość pliku wskazanego za pomocą atrybutu url. Przy czym mammy możliwość dołączania zasobów spoza obszaru kontenera. Podsumowanie Referat ten nie miał na celu dokładnego opisania technologii JSP – jak i związanych z nim technologii pokrewnych. Ma on jedynie na celu zarysowanie – krótki i szybki wgląd na możliwości programowania serwletów i stron JSP. W niniejszym referacie oparłem się na książce „Head First Serwlet and JSP” i wszystkich zainteresowanych odsyłam do tej pozycji, zaznaczając jednak – że trzeba znać choćby podstawy języka Java – by przystąpić do lektury tegoż. W tejże pozycji możemy poznać szczegóły programowania serwletów, JSP, związaną z nimi podstawą języka EL, dokładnie zapoznać się z biblioteka JSTL oraz nauczyć się tworzyć własne znaczniki i wiele innych rzeczy. 8