JAVA : APLIKACJE WEBOWE I JAVA EE WPROWADZENIE

Wielkość: px
Rozpocząć pokaz od strony:

Download "JAVA : APLIKACJE WEBOWE I JAVA EE WPROWADZENIE"

Transkrypt

1 JAVA : APLIKACJE WEBOWE I JAVA EE WPROWADZENIE Wszystko w poprzednich książkach, które mówiło o rozwoju systemu, programowaniu i Javie, było skierowane do aplikacji działających na jednym komputerze - zwanych także aplikacjami komputerowymi. W poniższych książkach zajmę się tworzeniem aplikacji, które działają na wielu komputerach i wymieniają dane przez sieć, którą często jest Internet, i w rzeczywistości takie programy są najczęściej spotykane w praktyce - przynajmniej jeśli spojrzysz na programy stosowany w firmach lub instytucjach publicznych. Oprócz uruchamiania programów w sieci, charakteryzują się tym, że mają wielu współbieżnych użytkowników i zazwyczaj są włączeni do rozwiązania informatycznego, które obejmuje kilka programów, które współpracują ze sobą w celu rozwiązania pożądanych zadań. Opracowywanie takich programów wymaga nowych rozwiązań technicznych, az drugiej strony stawiają nowe wymagania dla samego procesu rozwoju systemu, ale na szczęście wszystko, co do tej pory zostało powiedziane, jest nadal aktualne, ale konieczne jest rozszerzenie go o nowe koncepcje. W literaturze takie programy są ogólnie nazywane aplikacjami korporacyjnymi i bez precyzyjnego zdefiniowania, czym są, obejmują programy dla dużych firm i organizacji, ale być może powinieneś pomyśleć o tym w ten sposób, że program nie jest po prostu program, ale rozwiązanie sytuacji w pracy lub zadania w większej firmie. Zacznę od spojrzenia na rozwój aplikacji internetowych, które są aplikacjami działającymi przez Internet, i chociaż nie jest to jedyny rodzaj aplikacji korporacyjnych, a może nawet nie jest już tak ostry, czym są aplikacje internetowe, a które nie, przynajmniej mówi się o niektórych technologiach i aplikacjach, które są opracowywane i uruchamiane w sposób inny niż tradycyjne programy biurowe, a ponadto są to programy, które wszystkie spotykają się, czy to w pracy, czy prywatnie. Aplikacje internetowe istnieją od wielu lat i, w wyniku długiego rozwoju, są coraz szerzej rozpowszechniane od prostych statycznych stron internetowych do rzeczywistych aplikacji, takich jak sklepy internetowe i aplikacje, takie jak programy biurowe Google, ale wiele się dzieje, zasada jest nadal taka sama w przypadku serwera i klienta: Klient jest często zwykłą stacją roboczą z przeglądarką. Przeglądarka to program podobny do każdego innego programu na PC, ale za pomocą przeglądarki użytkownik może wprowadzić żądanie do serwera internetowego, wpisując adres internetowy w pasku adresu przeglądarki. Serwer WWW to także program działający gdzieś na komputerze. Jest to program, który stale działa i nasłuchuje żądania. Żądanie oznacza, że przeglądarka klienta chce, aby dokument HTML został odesłany, a serwer internetowy załaduje dokument i odeśle go z powrotem do przeglądarki klienta. Gdy klient otrzyma dokument, przeglądarka go wyrenderuje i wyświetli na ekranie. Oznacza to, że przeglądarka interpretuje kod HTML i na podstawie tego kodu określa sposób wyświetlania dokumentu na ekranie. Jest to przynajmniej podstawowa zasada i jak działa na początku w sieci WWW, ale dziś jest o wiele więcej. Żądanie dotyczące nie tylko odesłania dokumentu HTML z powrotem, ale często wraz z żądaniem wysyłane są dane (mogą to być dane dotyczące przedmiotów, które mają zostać dodane do koszyka), a także może być informacją dla serwera o znalezieniu określonych danych ( na przykład od kryteriów wyszukiwania do towarów). Oznacza to, że serwer musi wykonywać wiele innych czynności, na przykład zapisywać dane w bazach danych, pobierać dane z bazy danych i dynamicznie budować odpowiedź, która ma zostać wysłana do klienta. Innymi słowy, na podstawie żądań klienta serwer sieciowy musi wykonywać oprogramowanie, programy, które są zasadniczo rozwijane i uruchamiane jak każdy inny program, ale tylko programy działające na komputerze obsługującym serwer WWW. Aplikacja internetowa charakteryzuje się tym, że kod programu jest wykonywany na serwerze, który

2 następnie przesyła wynik z powrotem do klienta w postaci dynamicznie generowanego dokumentu HTML. Jednak program po stronie klienta może również zawierać kod wykonywany przez przeglądarkę. Istnieje kilka opcji, ale najważniejszą jest JavaScript, czyli kod skryptu (który jest tylko tekstem) wysyłany jako część dokumentu HTML. Oczywiście wymaga to, aby przeglądarka mogła interpretować i wykonywać kod JavaScript, ale wszystkie nowoczesne przeglądarki potrafią. Inną opcją jest wysłanie rzeczywistego przetłumaczonego kodu do przeglądarki, na przykład aplet Java, który jest napisany i przetłumaczony dokładnie w taki sam sposób, jak na przykład program Swing. Można myśleć o aplecie Java jako aplikacji Java, która działa w oknie przeglądarki. Oczywiście wymaga przeglądarki do obsługi wykonywania apletu Java i zwykle wymaga zainstalowania wtyczki (rozszerzenia) dla przeglądarki. Ponieważ aplet Java jest tłumaczony na kod binarny oraz pobierany i uruchamiany na maszynie klienta, technologia ta wiąże się z ryzykiem bezpieczeństwa, z którego wielu nie jest zadowolonych. Dlatego aplikacja internetowa może zawierać zarówno kod wykonywany po stronie serwera, jak i kod wykonywany po stronie klienta, ale taki, że największą część kodu stanowi kod serwera. Jedne są zatem nazywane aplikacjami internetowymi dla aplikacji klient-serwer. Jak opisano powyżej, aplikacja internetowa opiera się na ruchu sieciowym i za każdym razem, gdy użytkownik zgłasza żądanie, przed otrzymaniem odpowiedzi występuje opóźnienie. Dlatego aplikacje internetowe działają inaczej niż tradycyjne aplikacje komputerowe. Niemniej jednak wiele zadań, które wcześniej były rozwiązywane przez programy uruchomione na konkretnej maszynie klienckiej, przejmowane są przez aplikacje internetowe. Jest tego kilka przyczyn. Najważniejszą rzeczą jest oczywista zaleta, że możesz uzyskać dostęp do danych bez względu na to, gdzie się znajdujesz, i nie trzeba instalować programu na komputerze użytkownika. Potem jest opóźnienie, które zbliża się w innym kierunku, ale nie oznacza to tego samego co wcześniej, a między innymi dlatego, że dziś mamy znacznie wyższą stawkę w Internecie niż wcześniej, ale także dlatego, że przywykliśmy do tego że aplikacje internetowe działają w ten sposób. Wreszcie, technicznie rzecz biorąc, podjęto szereg środków, aby zapewnić, że opóźnienie nie będzie odczuwane tak bardzo, przede wszystkim poprzez zapewnienie, że nie zostanie wysłanych więcej danych, niż to konieczne. Można powiedzieć, że zawsze celem było wyświetlenie użytkownikowi aplikacji internetowej, ponieważ był to zwykły program instalowany na komputerze użytkownika. Celem tej książki jest pokazanie, jak tworzyć aplikacje internetowe w Javie. Wymaga to jednak skromnej znajomości HTML, której nie chcę dotykać, ale chociaż nie powinno być na miejscu, prawdopodobnie i tak będziesz w stanie śledzić rozwój przykładów, ponieważ używam go stosunkowo mało, a także narzędzia programistyczne (NetBeans) zapewniają doskonałą pomoc. Na koniec należy wspomnieć, że aplikacje internetowe nie są rozwiązaniem wszystkiego i nadal istnieją programy, które należy rozwijać jako klasyczne aplikacje komputerowe, przede wszystkim dlatego, że nie mogą żyć z powyższym opóźnieniem. Teraz wspólna aplikacja na PC może również komunikować się z serwerem przez Internet, a zatem być częścią aplikacji korporacyjnej, ale wymaga innej technologii, do której powrócę w kolejnych książkach. Należy również wspomnieć, że komputery podręczne, takie jak telefony komórkowe, odgrywają dziś bardzo ważną rolę i ponownie ustanawiają nowe wymagania dla programisty. 1.1 NARZĘDZIE ROZWOJU Aby tworzyć i testować aplikacje internetowe, musisz mieć serwer WWW. Istnieje wiele opcji, ale w tym przypadku potrzebuję serwera WWW obsługującego aplikacje internetowe opracowane w Javie. Do tej pory wszystkie programy zostały napisane przy użyciu NetBeans, a po pobraniu produktu możesz wybrać z kilku pakietów:

3 Do tej pory korzystałem z pierwszego, ale teraz potrzebuję Java EE, czyli Java Enterprise Edition. Rozszerza się o Javę EE, która zawiera wiele narzędzi programistycznych dla aplikacji korporacyjnych, w tym aplikacji internetowych i HTML5, które obsługują tworzenie aplikacji internetowych korzystających z HTML5. Wreszcie, uwzględniono dwa serwery WWW. Różnica polega na tym, że ten ostatni jest wspólnym serwerem WWW, który obsługuje aplikacje Java i jest wystarczający ze względu na tę książkę, ale nie jest serwerem aplikacji. To jest serwer GlassFish i ponieważ jest to konieczne w przypadku poniższych książek, będę go używać wszędzie. Oba serwery są uwzględnione, ale możesz zdecydować, czy chcesz zainstalować oba (nie musisz instalować Tomcat, chyba że chcesz z nim eksperymentować). Gdy pobierasz pakiet NetBeans za pomocą Java EE, dostajesz samorozpakowujący się skrypt i ogólnie łatwo jest zainstalować Java EE i GlassFish, ale książka zawiera dodatek, który pokazuje, jak to zrobić. 2. SERVLET Podstawową koncepcją aplikacji internetowej Java jest serwlet, który jest klasą Java, która ma metody, które mogą generować odpowiedź dla klienta w postaci HTML. Ponieważ jest to zwykła klasa Java, której metody są wykonywane na serwerze, może wykonywać wszystko, co dana klasa może, i może na przykład odczytywać dane w bazie danych. A zatem serwlet może dynamicznie generować dokument HTML, którego treść zależy od sytuacji. W rzeczywistości rzadko zdarza się, że patrzysz na te serwlety, ponieważ zwykle tworzysz dynamiczne strony internetowe, takie jak strony JSP lub Facelets (wyjaśnione później), ale w obu przypadkach strony są tłumaczone na serwlety, więc w tej sekcji o tym, czym jest serwlet, ale także sposób pisania serwletu za pomocą NetBeans. Po otwarciu NetBeans wybieram Plik Nowy projekt:

4 ale tym razem Kategoriami musi być Java Web, podczas gdy Projekty powinny być aplikacją Web. Po kliknięciu przycisku Dalej pojawi się zwykłe okno, w którym należy wprowadzić nazwę projektu i wybrać folder, w którym projekt ma zostać utworzony. Nazwałem projekt TimeServer. Po kliknięciu przycisku Dalej pojawi się okno wyboru serwera, na którym aplikacja ma być hostowana: Prawdopodobnie jest już dostępny dla serwera GlassFish, więc nie trzeba nic robić i wystarczy kliknąć Zakończ. Następnie utworzono projekt aplikacji internetowej (patrz poniżej) z folderami dla różnych typów plików, z których może składać się projekt, ale na razie istnieje tylko jeden plik o nazwie index.html, który jest plikiem wspólny dokument HTML, który można postrzegać jako stronę główną aplikacji:

5 Za chwilę dodam kilka zmian, ale jest to w pełni funkcjonalny dokument HTML, a próba uruchomienia projektu NetBeans otwiera przeglądarkę i wyświetla następującą stronę: W odniesieniu do okna przeglądarki należy pamiętać, że pasek tytułu wyświetla tekst z elementu tytułu dokumentu, a zawartość samej strony to tekst z części ciała dokumentu. Na koniec zwróć uwagę na pasek adresu: localhost: 8080 / TimeServer localhost to nazwa komputera lokalnego, a zatem fizycznego serwera, na którym jest zainstalowany serwer WWW. Jak wspomniano, serwer WWW to program działający nieprzerwanie, a taki program jest nie z tego świata znany pod nazwą serwera (który w rzeczywistości jest adresem internetowym) i numerem portu. Serwer WWW można skonfigurować tak, aby używał określonego numeru portu, a GlassFish używa go jako domyślnego portu W takim przypadku wywoływana jest aplikacja TimeServer, a ponieważ nie określono inaczej, serwer będzie używał strony głównej aplikacji (wyślij stronę główną jako odpowiedź), czyli index.html. Obecnie aplikacja nie ma serwletów, a teraz dodam serwlet. Dzieje się tak, klikając prawym przyciskiem myszy <Pakiet domyślny> i wybierając Nowy Servlet W poniższym oknie wywołałem serwlet dla TimeServlet (okno pokazuje ostrzeżenie, które możesz zignorować w tym miejscu), a kiedy klikniesz Dalej, pojawi się okno, jak pokazano poniżej:

6 Należy tutaj zauważyć, że zmieniłem zarówno nazwę serwletu, jak i wzorce adresów URL. Nie jest to konieczne i najczęściej robi się, aby pokazać, że jest dozwolone. Następnie kliknij Finsh, a NetBeans tworzy serwlet (w którym usunąłem niektóre komentarze): import java.io.ioexception; import java.io.printwriter; import javax.servlet.servletexception; import javax.servlet.annotation.webservlet; import javax.servlet.http.httpservlet; import javax.servlet.http.httpservletrequest; import = "Time", urlpatterns = "/Time") public class TimeServlet extends HttpServlet /** * Processes requests for both HTTP <code>get</code> and <code>post</code> * methods. request servlet request response servlet response ServletException if a servlet-specific error occurs IOException if an I/O error occurs */ protected void processrequest(httpservletrequest request, HttpServletResponse response) throws ServletException, IOException response.setcontenttype("text/html;charset=utf-8"); try (PrintWriter out = response.getwriter()) /* TODO output your page here. You may use following sample code. */ out.println("<!doctype html>"); out.println("<html>"); out.println("<head>"); out.println("<title>servlet TimeServlet</title>"); out.println("</head>");

7 out.println("<body>"); out.println( "<h1>servlet TimeServlet at " + request.getcontextpath() + "</h1>"); out.println("</body>"); out.println("</html>"); /** * Handles the HTTP <code>get</code> method. request servlet request response servlet response ServletException if a servlet-specific error occurs IOException if an I/O error occurs protected void doget(httpservletrequest request, HttpServletResponse response) throws ServletException, IOException processrequest(request, response); /** * Handles the HTTP <code>post</code> method. request servlet request response servlet response ServletException if a servlet-specific error occurs IOException if an I/O error occurs protected void dopost(httpservletrequest request, HttpServletResponse response) throws ServletException, IOException

8 processrequest(request, response); /** * Returns a short description of the servlet. a String containing servlet description public String getservletinfo() return "Short description"; Komentarze wyjaśniają w pewnym stopniu, co robią poszczególne metody, ale za chwilę wyjaśnię trochę więcej. Należy jednak pamiętać, że w definicji klasy znajduje się (name = "Time", urlpatterns = "/ Time") co mówi mi, że jest to serwlet, jego nazwa i adres URL, a tutaj należy szczególnie zauważyć, że są to nazwy, które wybrałem podczas tworzenia przedmiotowego serwletu. Początkowo powrócę do strony index.html (strony głównej), którą zmieniłem na następujące: <!DOCTYPE html> <html> <head> <title>todo supply a title</title> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> </head> <body> <h1>a simple html document</h1> <h2><a href="time">what time is it?</a></h2> </body>

9 </html> Powinieneś zauważyć element h2, który zawiera link, który odnosi się do mojego serwletu. Jeśli teraz uruchomisz aplikację, otworzy się przeglądarka: To nie jest takie dziwne, ale klikając na link pojawi się kolejne okno: Musisz zaznaczyć pasek adresu, który informuje, że jest to wynik serwletu, który się pojawi. Spojrzę teraz trochę bliżej na kod klasy serwletu. Po pierwsze, zauważ, że klasa dziedziczy HttpServlet, która jest klasą bazową serwletu. Jeśli weźmiesz pod uwagę metodę processrequest (), jasne jest, że tworzy ona dokument HTML. Metoda ma dwa parametry, które reprezentują odpowiednio żądanie (z przeglądarki) i odpowiedź. Komunikacja między klientem a serwerem odbywa się po protokole HTTP, który jest prostym protokołem tekstowym. Gdy przeglądarka wykonuje żądanie, można to zrobić na dwa sposoby, jak nazywają się GET i POST, a główną różnicą jest sposób, w jaki przeglądarka wysyła dane wraz z żądaniem. Gdy przeglądarka wysyła żądanie do serwletu, wykonywana jest jedna z metod doget () i dopost (), a obie metody mają dwa parametry, które są odniesieniami do obiektów reprezentujących odpowiednio żądanie i odpowiedź. W tym przypadku nic innego się nie dzieje, niż obiekty te są wysyłane do metody processrequest (). Inicjuje obiekt odpowiedzi na dokument HTML, po czym określa odwołanie do autora obiektu. Odniesienie służy do drukowania tekstu dokumentu, który w tym przypadku stanowi dokument HTML. Kiedy blok try wychodzi poza zakres, odwołanie jest usuwane, co oznacza, że dokument zostaje zakończony, a odpowiedź jest wysyłana do klienta. Teraz zmienię metodę processrequest() w następujący sposób: protected void processrequest(httpservletrequest request, HttpServletResponse response) throws ServletException, IOException response.setcontenttype("text/html;charset=utf-8"); try (PrintWriter out = response.getwriter())

10 out.println("<!doctype html>"); out.println("<html>"); out.println("<head>"); out.println("<title>servlet TimeServlet</title>"); out.println("</head>"); out.println("<body>"); out.println("<h1>the time is: " + gettime() + "</h1>"); out.println("</body>"); out.println("</html>"); private String gettime() Calendar date = Calendar.getInstance(); return String.format("%d. %s %d %02d:%02d:%02d", date.get(calendar.date), getmonth(date.get(calendar.month)), date.get(calendar.year), date.get(calendar.hour), date.get(calendar.minute), date.get(calendar.second)); private String getmonth(int n) switch (n) case 0: return "January"; case 1: return "February"; case 2: return "March"; case 3: return "April"; case 4: return "May"; case 5: return "June"; case 6: return "July"; case 7: return "August";

11 case 8: return "September"; case 9: return "October"; case 10: return "November"; case 11: return "December"; return ""; W rzeczywistości tylko jedna instrukcja została zmieniona, ale teraz wywołuje metodę gettime (), która zwraca ciąg z bieżącą datą i godziną. Celem wszystkich jest pokazanie, że serwlet może zawierać cały kod Java, który może być potrzebny, ponieważ serwlet jest po prostu klasą Java. Kolejnym celem jest to, że mój serwlet jest teraz dynamiczny, tak więc HTML wysyłany do przeglądarki zależy od tego, kiedy aplikacja jest wykonywana. Poniżej znajduje się przykład po kliknięciu linku na stronie głównej: Pamiętaj, że nie musisz otwierać strony, klikając link na stronie głównej, ale możesz także bezpośrednio otworzyć stronę - i uzyskać serwlet, który ją tworzy - wpisując adres bezpośrednio w przeglądarce. Po napisaniu aplikacji internetowej jak wyżej, musi ona być hostowana na serwerze aplikacji, zanim będzie można ją otworzyć w przeglądarce. Zadanie to nazywa się wdrożeniem, było wcześniej i może być skomplikowane, ale jeśli aplikacja jest rozwijana przy użyciu NetBeans, chodzi o samą siebie w ramach procesu kompilacji bez potrzeby robienia czegokolwiek. Jeśli przyjrzysz się projektowi, zobaczysz, że pod folderem dist znajduje się plik o (w tym przypadku) nazwie TimeServer.war i jest to pakiet zawierający pliki wymagane przez proces wdrażania. Później powrócę do procesu wdrażania, ponieważ bardziej złożone aplikacje mogą wymagać więcej działań, a zwłaszcza jeśli aplikacja ma być hostowana na serwerze na innym komputerze. Jeśli otworzysz przeglądarkę i wprowadzisz pole adresu localhost: 8080 / TimeServer otworzy się strona główna aplikacji. Odpowiada to wysłaniu żądania do lokalnego serwera GlassFish z prośbą o wykonanie aplikacji TimerServer, a GlassFish wysłał następnie w odpowiedzi strony początkowe aplikacji, które są index.html. ĆWICZENIE 1 W taki sam sposób jak powyżej napisz aplikację internetową, która korzysta z serwletu. Aplikacja musi zaczynać się od strony (mieć stronę główną), jak pokazano poniżej:

12 Jeśli klikniesz link, wynikiem może być: która pokazuje imię i panowanie przypadkowego duńskiego króla. Jeśli klikniesz link ponownie, będziesz mieć imię i panowanie innego losowego króla. Zacznij od utworzenia nowego projektu aplikacji sieci Web i dostosuj index.html strony głównej, aby wyświetlić pierwszą stronę. Następnie dodaj serwlet, którego odpowiedzią jest druga strona. Ten serwlet potrzebuje listy z królami. Możesz go znaleźć w pliku królów, który jest plikiem tekstowym, i możesz umieścić zawartość pliku jako tablicę statyczną w swojej klasie serwletu. 2.1 ZMIANA ADRESU 1 Jako kolejny przykład serwletu pokażę aplikację internetową, w której użytkownik musi wypełnić formularz, który może być poruszoną wiadomością. Wprowadzone informacje są następnie wysyłane do serwera, na którym są sprawdzane i jeśli można je zaakceptować, pojawi się potwierdzenie, że wiadomość została otrzymana. W przeciwnym razie użytkownik zostanie poproszony o ponowne wprowadzenie wiadomości. Po kliknięciu przycisku Prześlij dane formularza są wysyłane do serwera, który może na przykład odpowiedzieć za pomocą następującego komunikatu:

13 ponieważ użytkownik nie podał całego adresu. Następnie będziesz musiał kliknąć link i będziesz mógł ponownie wypełnić formularz. Jeśli wypełnisz wszystkie pola, jak pokazano poniżej, pole adresu nie jest wypełnione, a data jest wpisana w formularzu DD-MM-RRRR (to znaczy łącznik między polami), a następnie kliknij Prześlij, w odpowiedzi otrzymasz paragon (patrz poniżej). Jest to oczywiście bardzo prosta aplikacja, ale jest to aplikacja, która wysyła dane od klienta do serwera, na którym są przetwarzane, po czym klient otrzymuje odpowiedź i pod wieloma względami jest to zasada wielu aplikacji internetowych.

14 Podstawą jest projekt NetBean o nazwie ChangeAddress1, który jako pierwszy projekt w tym rozdziale jest projektem aplikacji sieci Web. NetBeans tworzy stronę główną o nazwie index.html, którą zmodyfikowałem w następujący sposób: <!DOCTYPE html> <html> <head> <title>changeaddress</title> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> </head> <body> <h1>change address</h1> <form method="post" action="addressservlet"> <table> <tr> <td><label>enter first name: </label></td> <td><input type="text" id="fname" name="fname"/></td> </tr> <tr> <td><label>enter last name: </label></td> <td><input type="text" id="lname" name="lname"/></td> </tr> <tr>

15 <td><label>enter address: </label></td> <td><input type="text" id="addr" name="addr"/></td> </tr> <tr> <td><label>enter zip code and city: </label></td> <td><input type="text" id="post" name="post"/></td> </tr> <tr> <td><label>enter mail address: </label></td> <td><input type="text" id="mail" name="mail"/></td> </tr> <tr> <td><label>enter date for new address: </label></td> <td><input type="text" id="date" name="date"/></td> </tr> <tr> <td></td> <td><input type="reset" value="reset"/> <input type="submit" value="submit"/></td> </tr> </table> </form> </body> </html> To ta strona pokazuje formularz. Formularz jest zdefiniowany w HTML za pomocą elementu formularza. W takim przypadku pola formularza są umieszczane w tabeli, a pola mają być ładnie umieszczone pod sobą w dwóch kolumnach. Tabela ma 7 wierszy, a pierwsze 6 wierszy ma etykietę i element wejściowy. Etykieta pokazuje tekst, natomiast element wejściowy, który w tym przypadku ma typ tekstu, jest polem wejściowym. Każde pole wejściowe ma nazwę, a zatem identyfikator zdefiniowany odpowiednio przez identyfikator i atrybut nazwy. W tym przypadku potrzebny jest tylko ostatni, ale jest nieco inny, gdy element jest identyfikowany przez identyfikator lub nazwę, ale gdy wartości elementów są wysyłane do serwera jako część formularza, to atrybut nazwy, który Jest używane. Jeśli jednak odwołujesz się do elementu z arkusza stylów, używany jest atrybut id. Dlatego dobrym pomysłem może być wskazanie obu. Ostatni wiersz w tabeli ma również dwa komponenty wejściowe, ale mają różne typy. Oba komponenty są renderowane przez przeglądarkę jako przycisk, a

16 atrybut wartości określa tekst wyświetlany na przycisku. Pierwszy składnik wyczyści pola wprowadzania formularza, a drugi (prześlij komponent) przesyła formularz na serwer. Jeśli weźmiesz pod uwagę element formularza, ma on dwa atrybuty. akcja wskazuje, na którą stronę na serwerze należy wysłać żądanie. W tym przypadku jest to AdresServlet, który jest serwletem. Druga metoda wskazuje, jaki to rodzaj żądania, a tutaj jest POST. Oznacza to, że elementy formularza są wysyłane wraz z żądaniem jako para klucz / wartość, gdzie klucz jest wartością atrybutu name, a wartość jest wartością atrybutu value, który dla pola wejściowego jest wprowadzonym tekstem. Jak wspomniano, AddressServlet odnosi się do serwletu. Został on utworzony w taki sam sposób jak w poprzednim przykładzie i nazwałem go AddressServlet, a na ekranie Konfiguruj wdrożenie serwletu nie zmieniłem tym razem wartości dla nazwy serwletu i wzorców adresów URL, ale utworzyłem pakiet dla serwletu. Wypełniony kod pokazano poniżej, w którym usunąłem wszystkie komentarze oraz ostatnią metodę getservletinfo(): package changeaddress.servlets; import java.io.ioexception; import java.io.printwriter; import javax.servlet.servletexception; import javax.servlet.annotation.webservlet; import javax.servlet.http.httpservlet; import javax.servlet.http.httpservletrequest; import javax.servlet.http.httpservletresponse; import java.util.*; import java.text.*; import = "AddressServlet", urlpatterns = "/AddressServlet") public class AddressServlet extends HttpServlet protected void processrequest(httpservletrequest request, HttpServletResponse response) throws ServletException, IOException response.setcontenttype("text/html;charset=utf-8"); request.setcharacterencoding("utf-8"); try (PrintWriter out = response.getwriter()) out.println("<!doctype html>");

17 out.println("<html>"); out.println("<head>"); out.println("<title>addressservlet</title>"); out.println("</head>"); out.println("<body>"); String fname = request.getparameter("fname"); String ename = request.getparameter("lname"); String addr = request.getparameter("addr"); String post = request.getparameter("post"); String mail = request.getparameter("mail"); String date = request.getparameter("date"); if (fname.length() == 0 ename.length() == 0) out.println("<h3>you must enter your name</h3><br>"); out.println("<a href=\"index.html\">try again </a>"); else if (addr.length() == 0 post.length() == 0) out.println("<h3>you must enter the address</h3><br>"); out.println("<a href=\"index.html\">try again </a>"); else if (mail.length() > 0 &&!ismail(mail)) out.println("<h3>you must enter a legal mail address</h3><br>"); out.println("<a href=\"index.html\">try again </a>"); else try SimpleDateFormat formatter = new SimpleDateFormat("dd-mm-yyyy"); Date dato = formatter.parse(date); out.println("<h1>thank you for your inquiry</h1>");

18 out.println("<h3>we have registered</h3>"); out.println(fname + " " + ename + "<br>"); out.println(addr + "<br>"); out.println(post + "<br>"); out.println(mail + "<br>"); out.println("new address is valid from: " + date); catch (Exception ex) out.println("<h3>you must enter a date on the form DD-MM-YYYY</h3><br>"); out.println("<a href=\"index.html\">try again </a>"); out.println("</body>"); out.println("</html>"); private boolean ismail(string mail) return protected void doget(httpservletrequest request, HttpServletResponse response) throws ServletException, IOException processrequest(request, protected void dopost(httpservletrequest request, HttpServletResponse response) throws ServletException, IOException

19 processrequest(request, response); Zasadniczo nie zawiera niczego nowego w pierwszym przykładzie, a prawie metoda processrequest () jest również generowana przez NetBeans. Zauważ, że dodałem metodę ismail (), która jest metodą wcześniejszą do sprawdzania adresu przy użyciu wyrażenia regularnego (nie pokazałem kodu). Metoda processrequest () działa w zasadzie w taki sam sposób jak w pierwszym przykładzie i dynamicznie tworzy kod HTML, który ma zostać wysłany jako odpowiedź. Najpierw zwróć uwagę na oświadczenie request.setcharacterencoding ( UTF-8 ); Konieczne jest prawidłowe dekodowanie liter duńskich. Następnie powinieneś zauważyć, jak uchwycić wartości formularza, na przykład: String fname = request.getparameter("fname"); określa wartość wprowadzoną jako imię. Reszta jest w zasadzie tuż przy drodze i polega na sprawdzeniu poprawności pól wysłanych z formularza oraz, w przypadku błędów, wysłaniu komunikatu błędu w odpowiedzi. Zatem odpowiedź serwera jest dynamiczna, ponieważ zależy od wysłanych danych. Oczywiste jest, że serwlet może zrobić jeszcze wiele innych rzeczy i może na przykład zapisać przesłane dane w bazie danych. Samo byłoby pytanie o dodanie kodu Java. ĆWICZENIE 2 Musisz napisać aplikację internetową podobną do przykładu ChangeAddress1. Aplikacja powinna tym razem wyświetlić stronę z formularzem elektronicznej księgi gości. Po uruchomieniu aplikacja musi wyświetlić następującą stronę:

20 gdzie gość może wpisać swoje imię i skąd pochodzić (na przykład nazwę miasta). Ponadto możesz wprowadzić adres oraz tekst informujący o wizycie. Należy podać imię i nazwisko oraz skąd pochodzić, ale nie trzeba podawać adresu , ale jeśli tak, to powinien to być legalny adres. Tekst można również pominąć. Po wypełnieniu formularza i kliknięciu przycisku Prześlij formularz należy przesłać do serwletu. Jeśli formularz nie jest poprawnie wypełniony, musisz otrzymać komunikat o błędzie: musisz ponownie otworzyć formularz, aby móc ponownie wejść. Jeśli formularz jest poprawnie wypełniony, użytkownik musi otrzymać następujący efekt:

21 3 PARAMETRY I SESJE I WIĘCEJ Patrząc na powyższe przykłady, jasne jest, że można sięgać daleko w odniesieniu do samego rozwoju dynamicznych stron internetowych i aplikacji internetowych za pomocą dokumentów HTML i serwletów, ale jasne jest również, że w przypadku złożonej witryny napisanie serwlet i spraw, aby wszystko wyglądało naprawdę. Jest to coś, co JSP i JSF muszą rozwiązać, ale zanim pokażę, co to jest, pokażę kilka przykładów serwletów. Nie tyle serwletów, co więcej, aby wprowadzić kilka podstawowych koncepcji dotyczących aplikacji internetowych. 3.1 PARAMETRY DO SERWETÓW Zacznę od utworzenia nowej aplikacji internetowej, którą nazwałem Parametry, a rezultatem jest ponownie aplikacja ze stroną główną o nazwie index.html. Najpierw pokażę, jak przenieść parametry do serwletu podczas inicjalizacji. Dodałem serwlet o nazwie Init1Servlet iw oknie konfiguracji zdefiniowałem następujące elementy (zwróć uwagę na pole wyboru Dodaj informacje do deskryptora wdrażania (web.xml)):

22 Po utworzeniu odpowiedniego serwletu NetBeans utworzył dokument XML w folderze WEB-INF: <?xml version="1.0" encoding="utf-8"?> <servlet> <servlet-name>init1</servlet-name> <servlet-class>parameters.servlets.init1servlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>init1</servlet-name> <url-pattern>/init1</url-pattern> </servlet-mapping> <session-config> <session-timeout> 30 </session-timeout> </session-config> </web-app> Jest to plik konfiguracyjny używany w związku z wdrażaniem aplikacji. Należy zauważyć, że nazwa mojego serwletu to Init1, jak wybrano w powyższym oknie i że jest to nazwa odnosząca się do parametrów parameters.servlets.init1servlet. Należy również pamiętać, że serwlet w aplikacji ma adres (URL) / Init1. Następnie rozwinąłem dokument XML, jak pokazano poniżej: <?xml version="1.0" encoding="utf-8"?> <web-app version="3.1" xmlns=" xmlns:xsi=" xsi:schemalocation=" <web-app version="3.1" xmlns=" xmlns:xsi=" xsi:schemalocation=" <servlet> <servlet-name>init1</servlet-name> <servlet-class>parameters.servlets.init1servlet</servlet-class> <init-param> <param-name>owner</param-name> <param-value>torus data</param-value>

23 </init-param> </servlet> <servlet-mapping> <servlet-name>init1</servlet-name> <url-pattern>/init1</url-pattern> </servlet-mapping> <session-config> <session-timeout> 30 </session-timeout> </session-config> </web-app> Oznacza to, że zdefiniowałem parę klucz / wartość z właścicielem nazwy i wartością danych Torus. Następnie zmieniłem kod dla Init1Servlet na następujący, w którym pokazałem tylko pierwszą część klasy: public class Init1Servlet extends HttpServlet protected void processrequest(httpservletrequest request, HttpServletResponse response) throws ServletException, IOException response.setcontenttype("text/html;charset=utf-8"); try (PrintWriter out = response.getwriter()) out.println("<!doctype html>"); out.println("<html>"); out.println("<head>"); out.println("<title>servlet InitServlet1</title>"); out.println("</head>"); out.println("<body>"); out.println("<h1>greetings from " + getservletconfig().getinitparameter("owner") + " 1</h1>"); out.println("</body>"); out.println("</html>");

24 Należy tutaj zauważyć, że klasa nie jest dekorowana Powodem jest to, że serwlet jest tym razem zdefiniowany w pliku konfiguracyjnym. Użycie adnotacji jest alternatywą dla pliku konfiguracyjnego, która ułatwia napisanie serwletu (nie trzeba utrzymywać pliku konfiguracyjnego xml), ale odwrotnie, zmiany wymagają, aby kod mógł zostać ponownie przetłumaczony, podczas gdy plik konfiguracyjny może być utrzymywane bez potrzeby modyfikowania kodu serwletu. Należy również zauważyć, że w processrequest () zmieniłem tylko jeden wiersz (trzecia ostatnia instrukcja) i że pobiera parametr zdefiniowany w dokumencie XML. Następnie zmieniłem stronę początkową na następującą: <!DOCTYPE html> <html> <head> <title>parameters</title> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> </head> <body> <h1>parameters to servlets</h1> <p><a href="init1">init1</a></p> </body> </html> po uruchomieniu aplikacji i kliknięciu linku pojawi się okno W tym miejscu należy zwrócić uwagę na sposób przesyłania parametrów do serwletu za pomocą pliku konfiguracyjnego XML. Jeśli spojrzysz na powyższe okno konfiguracji serwletu NetBean, dolną opcją jest określenie parametrów inicjalizacji serwletu. Można tego użyć zamiast ręcznej edycji dokumentu XML, jak pokazano powyżej. Dodałem kolejny serwlet, tym razem o nazwie Init2Servlet, i skonfigurowałem wdrożenie w następujący sposób:

25 Ważne jest to, że nie ma zaznaczenia w polu Dodaj informacje do deskryptora wdrażania (web.xml) i dodano parametr inicjalizacji. Oznacza to, że plik web.xml nie jest aktualizowany, ale jeśli spojrzysz na kod, definicja klasy jest = "Init2", urlpatterns = "/Init2", initparams=@webinitparam(name="owner", value="torus data") ) public class Init2Servlet extends HttpServlet Jest używany podczas wdrażania jako alternatywa dla pliku web.xml i można zobaczyć, jak zdefiniowano nazwę i adres URL. Na koniec dodałem parametr. Kod dla processrequest () jest w zasadzie taki sam, a po dodaniu kolejnego linku na stronie startowej możesz wysłać zapytanie do nowego serwletu, a wynik jest następujący: 3.2 SESJE Gdy zażądasz strony internetowej z przeglądarki, a serwer odpowie z odpowiedzią, zostanie to zrobione zgodnie z protokołem HTTP. Protokół ten jest w zasadzie bezstanowy, co oznacza, że po odpowiedzi serwera z odpowiedzią serwer zapomniał wszystko o żądaniu, a następnym razem, gdy otrzymane zostanie żądanie dotyczące tej samej strony, serwer uzna go za nowy żądanie. Ten model

26 źle pasuje do nowoczesnych aplikacji internetowych i możesz między innymi rozwiązać problem, korzystając z koncepcji sesji. Gdy użytkownik otworzy przeglądarkę i wyśle żądanie na nową stronę, serwer zbada, czy uwzględniono identyfikator sesji. Nie ma znaczenia, czy jest to żądanie nowej strony wpisane w pasku adresu przeglądarki, a serwer wygeneruje identyfikator sesji i odeśle ją z odpowiedzią do klienta. Jeśli klient następnie prześle lub, na przykład, kliknie link prowadzący do strony w tej samej aplikacji internetowej, przeglądarka wyśle identyfikator sesji z, a serwer uwzględni go w swojej odpowiedzi. W ten sposób wprowadzono termin zwany sesją, który istnieje tak długo, jak długo serwer odnosi się do stron w tej samej aplikacji internetowej. Można to wykorzystać do zdefiniowania danych, które będą istnieć przez całą sesję. Gdy serwer tworzy identyfikator sesji, tworzy również obiekt sesji, a ten obiekt zawiera kolekcję obiektów Object. Serwer może więc tworzyć i zapisywać obiekty w tej kolekcji, a obiekty te żyją tak długo, jak żyje obiekt sesji, dlatego mogą być używane przez wszystkie strony w tej sesji. Należy zauważyć, że obiekty są znane tylko po stronie serwera i nie są wysyłane do klienta. Jedynym wysłanym do klienta jest identyfikator sesji, który jest wysyłany tam i z powrotem dla każdej pary żądania / odpowiedzi. Poszczególne obiekty sesji działają na serwerze, dopóki nie zostaną jawnie usunięte lub dopóki nie zostaną usunięte z powodu przekroczenia limitu czasu (na przykład może to być 30 minut). Oznacza to, z drugiej strony, że serwer może mieć wiele obiektów sesji, które nie są już używane, a tym samym zajmować miejsce, a częściowo, że obiekty sesji (takie jak koszyk) mogą zniknąć, jeśli przestaniesz działać. Aby zilustrować użycie sesji, stworzyłem aplikację internetową o nazwie Sesje. Do tej aplikacji dodam trzy serwlety. Podczas dodawania serwletu do aplikacji internetowej nie należy go umieszczać w domyślnym pakiecie projektu (co zostało zrobione powyżej w pierwszym przykładzie). Zazwyczaj tworzę pakiet o nazwie projectname.servlets (w tym przypadku session.servlets) i umieszczam tam moje serwlety. W tym przypadku utworzyłem również pakiet o nazwie session.data i dodałem następującą klasę, która może reprezentować osobę o nazwisku i tytule pracy: package sessions.data; public class Person private String name; private String title; public Person(String name, String title) this.name = name; this.title = title; public String getname() return name; public String gettitle()

27 return title; Należy zauważyć, że jest to dość powszechna klasa modeli. W następnym kroku dodałem następujący = "CreateServlet", urlpatterns = "/CreateServlet") public class CreateServlet extends HttpServlet protected void processrequest(httpservletrequest request, HttpServletResponse response) throws ServletException, IOException response.setcontenttype("text/html;charset=utf-8"); request.setcharacterencoding("utf-8"); try (PrintWriter out = response.getwriter()) String name = request.getparameter("name"); String title = request.getparameter("title"); if (name!= null && title!= null) sessions.data.person pers = new sessions.data.person(name.trim(), title.trim()); HttpSession session = request.getsession(true); session.setattribute("person", pers); out.println("<!doctype html>"); out.println("<html>"); out.println("<head>"); out.println("<title>servlet SaveServlet</title>"); out.println("</head>"); out.println("<body>"); out.println("<h3>your session object is now updated</h3>"); out.println("<h3>session id: " + request.getsession().getid() + "</h3>"); out.println("<a href=\"index.html\">go to start</a>");

28 out.println("</body>"); out.println("</html>"); Metoda processrequest () rozpoczyna się od określenia wartości dwóch pól formularza na stronie, która wysłała żądanie do tego serwletu. Czy to możliwe, a oba różnią się od null, służą do tworzenia obiektu Person. Następnie dodaje się odwołanie do obiektu sesji: HttpSession session = request.getsession (true); Oznacza to, że obiekt musi zostać utworzony, jeśli jeszcze nie istnieje. W następnym kroku obiekt Osoba jest dodawany do kolekcji obiektu sesji z kluczową osobą. Na koniec zwracana jest odpowiedź, która zawiera identyfikator obiektu sesji. Kod strony początkowej jest następujący: <!DOCTYPE html> <html> <head> <title>servlettest</title> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> </head> <body> <h3>start page</h3> <form method="post" action="createservlet"> <table> <tr> <td>enter name</td> <td><input type="text" name="name" id="name" /></td> </tr> <tr> <td>enter job title </td> <td><input type="text" name="title" id="title" /></td> </tr> <tr> <td colspan="2"><input type="submit" value="ok" /></td>

29 </tr> </table> </form> <ol> <li><a href="nameservlet">show name</a></li> <li><a href="titleservlet">show title</a></li> </ol> </body> </html> Po uruchomieniu aplikacji pojawi się następujące okno: Jeśli wpiszesz tutaj nazwę i stanowisko i klikniesz OK, otrzymasz następujące wyniki: Informuje, że obiekt sesji jest aktualizowany, a także identyfikator sesji. Należy zauważyć, że jest on reprezentowany jako duża liczba szesnastkowa, której na ogół nie można użyć do niczego, ale w tym przypadku można go użyć, aby zobaczyć, kiedy rozpoczyna się nowa sesja. W kolejnym kroku dodano serwlet, który pokazuje nazwisko osoby, która została utworzona:

30 @WebServlet(name = "NameServlet", urlpatterns = "/NameServlet") public class NameServlet extends HttpServlet protected void processrequest(httpservletrequest request, HttpServletResponse response) throws ServletException, IOException response.setcontenttype("text/html;charset=utf-8"); try (PrintWriter out = response.getwriter()) String name = null; try name = ((sessions.data.person) request.getsession().getattribute("person")).getname(); catch (Exception ex) name = ex.tostring(); out.println("<!doctype html>"); out.println("<html>"); out.println("<head>"); out.println("<title>nameservlet</title>"); out.println("</head>"); out.println("<body>"); out.println("<h1>name</h1>"); out.println("<h3>" + name + "</h3>"); out.println("<a href=\"index.html\">go to start</a>"); out.println("</body>"); out.println("</html>"); Nie ma wiele do wyjaśnienia, ale powinieneś zauważyć, jak odwoływać się do obiektu sesji i obiektu przechowywanego pod nazwą person. Rezultatem jest Object, a zatem konieczny jest typ rzutowania. Podobnie został stworzony serwlet o nazwie TitleServlet, który wysyła odpowiedź z tytułem obiektu Person. Jeśli na stronie początkowej wpisz:

31 i klikając OK, a następnie ze strony początkowej klikając link Pokaż nazwę, pojawi się okno: 3.3 PRZEKIEROWANIE Jeśli wyślesz żądanie do serwletu, może on wykonać przetwarzanie danych, a następnie wysłać żądanie do innego serwletu (lub innej strony internetowej). Można to zrobić jako przekierowanie lub przekazanie dalej. W pierwszym przypadku serwer wstawia kod do nagłówka HTTP wraz z nowym adresem URL (w polu Lokalizacja) i wysyła odpowiedź do przeglądarki. Następnie wykona żądanie nowego adresu URL. W drugim przypadku serwer po prostu wyśle to samo żądanie na inny adres URL, w tym wszystkie atrybuty par klucz / wartość z pól formularza. Zatem przekazywanie nie obejmuje przeglądarki, a pasek adresu w przeglądarce nie zmienia się, ponieważ wszystko dzieje się po stronie serwera. Pokażę ci, jak wykonać odpowiednio przekierowanie i przekazanie dalej. Punktem wyjścia jest następujący dokument HTML o nazwie index.html i jest to strona początkowa aplikacji Calculations: <!DOCTYPE html> <html> <head> <title>calculations</title> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0">

32 </head> <body> <h2>calculations</h2> <form method="post" action="mathservlet"> <table> <tr> <td>a: </td> <td><input type="text" name="numbera" style="width: 80px; height:20px; padding:0"/></td> </tr> <tr> <td>b: </td> <td><input type="text" name="numberb" style="width: 80px; height:20px; padding:0"/></td> </tr> <tr> <td colspan="2"> <select name="operation" style="width: 120px; height:30px; padding:0"> <option value="add">addition</option> <option value="sub">subtraction</option> <option value="mul">multiplikation</option> <option value="div">division</option> </select> </td> </tr> </table> <input type="submit" value="calculate" style="width: 120px; height:35px; padding:0"/> </form> </body> </html>

33 Jeśli uruchomisz aplikację, otrzymasz stronę, jak pokazano poniżej. Tutaj możesz wprowadzić dwie liczby, a także listę, na której możesz wybrać jedno z czterech obliczeń. Po kliknięciu przycisku formularz zostanie przesłany do serwletu MathServlet. Ten serwlet podejmuje jedynie decyzję, która operacja ma zostać wykonana, a następnie przekazuje to żądanie do jednego z czterech dodatkowych serwletów (AddServlet, SubServlet, MulServlet i DivServlet), ale w dwóch pierwszych przypadkach następuje przekierowanie, podczas gdy w pozostałych dwóch przypadkach dzieje się tak jak do przodu. Cztery serwlety do obliczeń wysyłają odpowiedź w postaci prostej strony przedstawiającej wynik. Zasadniczo wszystkie są takie same, a przykładowo procesrequest () dla AddServlet pokazano poniżej: protected void processrequest(httpservletrequest request, HttpServletResponse response) throws ServletException, IOException response.setcontenttype("text/html;charset=utf-8"); try (PrintWriter out = response.getwriter()) out.println("<!doctype html>"); out.println("<html>"); out.println("<head>"); out.println("<title>servlet AddServlet</title>"); out.println("</head>"); out.println("<body>"); try String a = request.getparameter("numbera"); String b = request.getparameter("numberb"); double s = Double.parseDouble(a) + Double.parseDouble(b); out.println("<p>" + a + " + " + b + " = " + s + "</p>"); catch (Exception ex) out.println("<p>illegal arguments</p>"); out.println("<a href=\"index.html\">back to start</a>"); out.println("</body>"); out.println("</html>");

34 Najciekawsze jest MathServlet: protected void processrequest(httpservletrequest request, HttpServletResponse response) throws ServletException, IOException String opr = request.getparameter("operation"); if (opr.equals("add") opr.equals("sub")) String a = request.getparameter("numbera"); String b = request.getparameter("numberb"); String site = opr.equals("add")? "AddServlet" : "SubServlet"; site += "?numbera=" + a + "&numberb=" + b; response.sendredirect(site); else if (opr.equals("mul") opr.equals("div")) ServletContext context = getservletconfig().getservletcontext(); RequestDispatcher dispatcher = opr.equals("mul")? context.getrequestdispatcher("/mulservlet") : context.getrequestdispatcher("/divservlet"); dispatcher.forward(request, response); else response.sendredirect("index.html");

35 Zaczyna się od określenia wartości listy i stąd pole wyboru formularza zwane operacją. Jeśli jest to add lub sub, należy dokonać przekierowania do AddServlet lub SubServlet. Powoduje to jednak problem, ponieważ przeglądarka przekierowuje do tego serwletu jako GET, co oznacza, że pola formularza nie są wysyłane. Dlatego muszę dodać je ręcznie jako parametry do adresu URL, co następuje przez zainicjowanie zmiennej, która może na przykład mieć wartość AddServlet? Numbera = 33 i numberb = 51 Po wprowadzeniu tego adresu następuje przekierowanie za pomocą metody sendredirect (), która odpowiada powyższemu adresowi zwróconemu do przeglądarki, który następnie wykonuje HTTP GET na ten adres. Jeśli operacja nie polega na dodawaniu lub dodawaniu, określa się obiekt ServletContext, który jest używany do utworzenia obiektu RequestDispatcher dla MulServlet lub DivServlet. Ten obiekt ma metodę forward(), która służy do przekazania żądania do tego serwletu. Kiedy tak się dzieje, żądanie jest przekazywane, w tym wszystkie formy pól i bez angażowania przeglądarki. Zachęcamy do przetestowania aplikacji i, w tym samym kontekście, zanotowania, co dzieje się z paskiem adresu przeglądarki. 3.4 CIASTECZKA Jako ostatnia rzecz w serwletach pokażę, jak utworzyć i używać ciasteczka. Plik cookie to tekst przesyłany w obie strony między serwerem a przeglądarką i może być używany w taki sam sposób jak zmienne sesyjne w celu zachowania informacji o stanie. Poniżej znajduje się serwlet, który tworzy = "SetServlet", urlpatterns = "/SetServlet") public class SetServlet extends HttpServlet private static java.util.random rand = new java.util.random(); protected void processrequest(httpservletrequest request, HttpServletResponse response) throws ServletException, IOException response.setcontenttype("text/html;charset=utf-8"); try (PrintWriter out = response.getwriter()) Cookie cookie = new Cookie("randomvalue" + rand.nextint(10),"" + rand.nextint(integer.max_value)); cookie.sethttponly(true); cookie.setmaxage(30); response.addcookie(cookie); out.println("<!doctype html>"); out.println("<html>"); out.println("<head>");

36 out.println("<title>servlet SetServlet</title>"); out.println("</head>"); out.println("<body>"); out.println("<h1>cookie created </h1>"); out.println("<a href=\"getservlet\">show cookie</a>"); out.println("</body>"); out.println("</html>"); Plik cookie jest reprezentowany przez obiekt Cookie. W tym przypadku tworzony jest plik cookie o nazwie randomvalue plus cyfra (np. RandomValue5) i przypisywana mu jest losowa wartość. Następnie jest definiowany jako tymczasowy plik cookie znany przeglądarce i ostatecznie definiowany jako mający 30 sekundowy limit czasu. Jeśli liczba jest ujemna, oznacza to, że jest usuwana podczas bieżącej sesji. Poniżej znajduje się inny serwlet, który czyta plik = "GetServlet", urlpatterns = "/GetServlet") public class GetServlet extends HttpServlet protected void processrequest(httpservletrequest request, HttpServletResponse response) throws ServletException, IOException response.setcontenttype("text/html;charset=utf-8"); try (PrintWriter out = response.getwriter()) out.println("<!doctype html>"); out.println("<html>"); out.println("<head>"); out.println("<title>servlet GetServlet</title>"); out.println("</head>"); out.println("<body>"); out.println("<h1>servlet GetServlet at " + request.getcontextpath() + "</h1>"); out.println("<table><tr><td>name</td><td>value</td></tr>"); Cookie[] cookies = request.getcookies(); for(cookie c: cookies) out.println("<tr><td>");

37 out.println(c.getname()); out.println("</td><td>"); out.println(c.getvalue()); out.println("</td></tr>"); out.println("</table>"); out.println("<p><a href=\"index.html\">set cookie</a></p>"); out.println("</body>"); out.println("</html>"); Nie ma wiele do wyjaśnienia, ale powinieneś zauważyć, jak przesuwać wszystkie pliki cookie w bieżącej sesji. Wreszcie jest strona początkowa: <!DOCTYPE html> <html> <head> <title>cookies</title> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> </head> <body> <h1>cookies</h1> <p><a href="setservlet">set cookie</a></p> </body> </html> Jeśli uruchomisz program, przekonasz się, że powstaje więcej plików cookie, ale plik cookie zmienia wartość, jeśli utworzysz plik cookie o nazwie, która już istnieje. Przekonasz się również, że poszczególne pliki cookie mogą zniknąć, ponieważ upływa 30 sekund. ĆWICZENIE 3 Musisz napisać aplikację internetową, która może symulować bardzo prosty koszyk. Celem jest przede wszystkim pokazanie przykładu użycia zmiennej sesji. Zacznij od nowego projektu aplikacji sieci Web, który możesz nazwać Zakupy. Strona główna index.html powinien być prostym formularzem z pojedynczym polem wprowadzania:

38 Jeśli wpiszesz produkt (tekst) i naciśniesz przycisk, tekst musi zostać wysłany do serwletu, który zapisuje go w ArrayList <String>, czyli w elemencie sesji, po czym użytkownik jest odsyłany z powrotem do strony głównej. Jeśli klikniesz dolny link, musisz poprosić o serwlet, który dynamicznie tworzy stronę, która pokazuje zawartość koszyka - jeśli coś jest w koszyku. W przeciwnym razie musisz tylko wiedzieć, że kosz jest pusty. Strona z koszykiem musi również zawierać link, który usuwa zawartość koszyka. Możesz rozwiązać ten problem, odsyłając do serwletu, który usuwa zawartość obiektu sesji. Poniżej znajduje się przykład tego, jak koszyk towarów może wyglądać po dodaniu 2 produktów do koszyka: 4 JAVABEANS W dalszej części często będę odwoływał się do Java Bean, a zatem niewiele o tym, co to jest (w rzeczywistości wspomniałem o Java Bean w poprzedniej książce). W rzeczywistości jest to zwykła klasa, ale musi spełniać bardzo niewiele decyzji: 1. Java Bean musi być serializowalna.

39 2. Java Bean musi mieć domyślny konstruktor. 3. Wszystkie zmienne instancji muszą być prywatne. 4. Zmienne instancji mogą mieć metody get- i set, i muszą stosować się do nazw konwencji, aby w przypadku metody getname () odpowiednia metoda set musiała nazywać się setname ( ). Poza tym Java Bean może być wszystkim, podobnie jak inne klasy może mieć różne inne metody i tak dalej. Na przykład poniżej pokazano Java Bean: package dateserver; import java.util.*; public class DateBean implements java.io.serializable private String date; private String time; public DateBean() Calendar dt = Calendar.getInstance(); date = String.format("%02d-%02d-%04d", dt.get(calendar.date), dt.get(calendar.month) + 1, dt.get(calendar.year)); time = String.format("%02d:%02d:%02d", dt.get(calendar.hour_of_day), dt.get(calendar.minute), dt.get(calendar.second)); public String getdate() return date; public String gettime() return time; public void setdate(string date) try

40 StringTokenizer tk = new StringTokenizer(date, "-"); if (tk.counttokens()!= 3) throw new Exception("Illegal date"); int day = value(tk.nexttoken(), 1, 31); int month = value(tk.nexttoken(), 1, 12); int year = value(tk.nexttoken(), 1900, 2100); if ((month == 4 month == 6 month == 9 month == 11) && day == 31) throw new Exception("Illegal value"); else if (month == 2 && day > (leapyear(year)? 29 : 28)) throw new Exception("Illegal value"); this.date = String.format("%02d-%02d-%04d", day, month, year); catch (Exception ex) this.date = ex.tostring(); public void settime(string time) try StringTokenizer tk = new StringTokenizer(time, ":"); if (tk.counttokens()!= 3) throw new Exception("Illegal time"); int tim = value(tk.nexttoken(), 0, 23); int min = value(tk.nexttoken(), 0, 59); int sek = value(tk.nexttoken(), 0, 59); this.time = String.format("%02d:%02d:%02d", tim, min, sek); catch (Exception ex) this.time = ex.getmessage();

41 public String tostring() return date + " " + time; private int value(string text, int a, int b) throws Exception int t = Integer.parseInt(text); if (a <= t && t <= b) return t; throw new Exception("Illegal value"); private boolean leapyear(int aar) if (aar % 100 == 0) return aar % 400 == 0; return aar % 4 == 0; Ten przykład został wybrany, ponieważ chcę go później zastosować, ale chcę też pokazać, że fasola jest zwykłą klasą, na którą mogą składać się wszystkie klasy. Jest to fasola, która reprezentuje datę i godzinę. 5 JSP Powyżej przedstawiłem serwlety i pokazałem, jak można ich używać (i których używa się) do pisania dynamicznych stron internetowych, ale jasne jest również, że tworzenie i tworzenie złożonych aplikacji internetowych przy użyciu serwletów jest dużym i trudnym zadaniem. Dlatego wprowadzono strony JSP, które można krótko scharakteryzować jako dokumenty będące mieszanką kodu HTML i Java. Kod Java zostanie następnie wykonany na serwerze, zanim dokument zostanie wysłany do przeglądarki klienta. Można to najlepiej wyjaśnić na przykładzie. Mam w NetBeans nową aplikację internetową, którą nazwałem DateServer, a wynik jest taki jak przed aplikacją ze stroną główną o nazwie index.html. Następnie kliknąłem prawym przyciskiem myszy folder Strony internetowe i wybrałem Nowy, a następnie JSP i dodałem nową stronę JSP, którą nazwałem startem, w wyniku czego do projektu dodano plik o nazwie start.jsp, którego zawartość jest prawie wstępny komentarz: page contenttype = "text / html" pageencoding = "UTF-8"%>

42 <! DOCTYPE html> <html> <head> <meta http-equiv = "Content-Type" content = "text / html; charset = UTF-8"> <title> Strona JSP </title> </head> <body> <h1> Witaj świecie! </h1> </body> </html> Jak widać, wygląda jak zwykły dokument HTML i istnieją tylko dwie różnice, czyli pierwsza linia, a więc rozszerzenie jsp. To ostatnie jest ważne, ponieważ informuje serwer WWW, że dokument ma zostać przetłumaczony przed wysłaniem do przeglądarki. Jeśli klikniesz prawym przyciskiem myszy nazwę na karcie Projekty i wybierzesz Uruchom plik, dokument zostanie automatycznie przetłumaczony i otwarty w przeglądarce. Obecnie nie ma Java, ale jako następny krok kliknąłem prawym przyciskiem myszy folder Source Packages i dodałem klasę o nazwie DateBean. Kod to fasola Java, jak pokazałem w poprzednim rozdziale. Tej fasoli Java można następnie użyć na stronie JSP w następujący sposób: page contenttype = "text / html" pageencoding = "UTF-8"%> <! DOCTYPE html> <html> <head> <meta http-equiv = "Content-Type" content = "text / html; charset = UTF-8"> <title> Strona JSP </title> </head> <body> <jsp: usebean id = "datebean" scope = "page" class = "dateserver.datebean" /> <h1> Witaj świecie! </h1> <h3> Dane to: $ datebean.date </h3> <h3> Czas to: $ datebean.time </h3> </body> </html>

43 Kod jest rozszerzany o element jsp: bean i, jak widać, definiuje odwołanie do klasy dateserver.datebean i wywołuje to odwołanie dla datebean. Na koniec określa zakres, który informuje, gdzie można użyć obiektu DateBean. Ponadto zdefiniowano dwa wiersze wstawiające odpowiednie wartości komponentu bean na stronie. Na przykład wstawki $ datebean.date data właściwości w kodzie HTML. Powinieneś zanotować odwołanie i wpisać datę, która jest nazwą właściwości, co oznacza, że jest to metoda getdate(), która jest wykonywana i że wstawiana jest jej wartość zwracana. Jeśli otworzysz stronę JSP w przeglądarce, wynikiem będzie i widać, że instancja klasy bean jest tworzona i wartości obiektu (bieżąca data i godzina są wstawiane do dokumentu). W szczególności, jeśli klikniesz F5 (odświeżenie przeglądarki), przeglądarka zaktualizuje zegar, a następnie obiekt zostanie przywrócony. Możesz używać innych publicznych metod w komponencie bean Java w ten sam sposób, ale w tym przypadku nie ma innych. W odniesieniu do wartości zakresu atrybutu istnieją cztery opcje: 1. strona, która jest domyślna i wskazuje, że z obiektu bean można korzystać wyłącznie z bieżącej strony 2. żądanie wskazujące, że obiekt bean może być używany ze wszystkich stron JSP, które dotyczą tego samego żądania 3. sesja, co oznacza, że obiekt bean może być używany ze wszystkich stron JSP dotyczących tej samej sesji - jednak strona, która tworzy obiekt, musi mieć dyrektywę strony z session = true 4. aplikacja wskazująca, że z obiektu bean można korzystać ze wszystkich stron JSP w aplikacji Po otrzymaniu żądania strony JSP strona jest automatycznie tłumaczona na serwlet, jeśli jeszcze nie jest. Tutaj serwer internetowy automatycznie sprawdzi, czy strona JSP jest nowsza niż jakikolwiek serwlet, a strona zostanie ponownie przetłumaczona. Oznacza to, że strona JSP zostanie przetłumaczona na serwlet tylko w razie potrzeby. Możesz także wstawić kod Java do strony JSP za pomocą tak zwanych skryptu. Rozszerzyłem stronę w następujący sposób: <%@page import="java.util.*"%> <%@page contenttype="text/html" pageencoding="utf-8"%> <!DOCTYPE html> <%! Calendar date = null; String text = null;

44 String gettime(calendar dt) return String.format("%02d-%02d-%04d %02d:%02d:%02d", dt.get(calendar.date), dt.get(calendar.month) + 1, dt.get(calendar.year), dt.get(calendar.hour_of_day), dt.get(calendar.minute), dt.get(calendar.second)); %> <% date = Calendar.getInstance(); text = gettime(date); %> <html> <head> <meta http-equiv="content-type" content="text/html; charset=utf-8"> <title>jsp Page</title> </head> <body> <jsp:usebean id="datebean" scope="page" class="dateserver.datebean"/> <h1>hello World!</h1> <h2 style="color:red">the current time: <%=text%></h2> <h3>the date is: $datebean.date</h3> <h3>the time is: $datebean.time</h3> </body> </html> Najpierw do instrukcji importu została wstawiona dyrektywa strony, co oznacza, że można odwoływać się do klas w pakiecie java.util. Następnie definiowane są dwa bloki skryptowe. Pierwszy zaczyna się od <%! i zawiera instrukcje, które są zmiennymi i metodą. Jest to kod przesyłany bezpośrednio do serwletu strony i odpowiada definiowaniu zmiennych instancji i metod w serwlecie. Drugi blok zaczyna się od <% i zawiera kod, który jest wykonywany przy każdym ładowaniu strony. W takim przypadku inicjowane są dwie zmienne zdefiniowane w pierwszym bloku. Wreszcie za pomocą skryptów możesz wstawiać wartości do kodu HTML, takie jak <% = tex%> który wstawia wartość tekstu zmiennej. Wynik wykonania strony może wyglądać następująco:

45 Dołączanie kodu Java na stronie JSP w ten sposób (przy użyciu skryptów) ma swoje zastosowanie, ale jest ogólnie uważane za złe programowanie. Powodem jest to, że strony JSP są bardzo trudne w utrzymaniu. Dlatego zaleca się używanie fasoli Java w jak największym stopniu. Teraz zrobię ostatnie rozszerzenie strony: <%@page import="java.util.*"%> <%@page contenttype="text/html" pageencoding="utf-8"%> <!DOCTYPE html> <%! Calendar dato = null; String tekst = null; String gettime(calendar dt) return String.format("%02d-%02d-%04d %02d:%02d:%02d", dt.get(calendar.date), dt.get(calendar.month) + 1, dt.get(calendar.year), dt.get(calendar.hour_of_day), dt.get(calendar.minute), dt.get(calendar.second)); %> <% dato = Calendar.getInstance(); tekst = gettime(dato); %> <html> <head> <meta http-equiv="content-type" content="text/html; charset=utf-8"> <title>jsp Page</title> </head> <body>

46 <jsp:usebean id="datebean" scope="page" class="dateserver.datebean"/> <jsp:setproperty name="datebean" property="*"/> <h1>hello World!</h1> <h2 style="color:red">the current time: <%=tekst%></h2> <h3>the date is: $datebean.date</h3> <h3>the time is: $datebean.time</h3> <form method="post"> <table> <tr> <td>date</td> <td><input type="text" id="date" name="date" style="width:120px"/></td> </tr> <tr> <td>time </td> <td><input type="text" name="time" style="width:120px"/></td> </tr> </table> <input type="submit" value="update"/> </form> </body> </html> gdzie został dodany formularz. Zauważ, że element formularza nie definiuje żadnej akcji. Oznacza to, że strona przesłana wykonuje żądanie do siebie. Formularz definiuje dwa komponenty wejściowe. Ważne jest, aby miały te same atrybuty nazw, które są nazwami dwóch właściwości w DateBean. Ponadto zwróć uwagę na oświadczenie: <jsp: setproperty name = "datebean" property = "*" /> Stwierdza, że podczas wykonywania przesyłania wszystkie metody ustawione w klasie DateBean muszą zostać wykonane i zaktualizowane o wartości odpowiednich pól wejściowych. Jeśli otworzysz stronę, wynik może wyglądać tak, jak pokazano poniżej, gdzie wpisałem wartości w dwóch polach wejściowych:

47 Po kliknięciu przycisku pojawi się okno pokazujące, że bieżący obiekt komponentu bean został zaktualizowany: Jak widać z powyższego, na stronie JSP można łatwo połączyć komponenty wejściowe z właściwościami w komponencie bean Java. Powyżej są wszystkie pola, które są powiązane, ale możesz to zrobić indywidualnie i na przykład. pisać <jsp: setproperty name = "datebean" property = "date" />

48 jeśli nie chcesz, aby wszystkie pola były aktualizowane. Inną sprawą jest obsługa wyjątków, do czego chcę wrócić później, ale w tym przypadku rozwiązano w ten sposób, że do pól przypisano dane wyjątki, co oczywiście nie jest rozwiązaniem, które można zastosować w praktyce. W ostatnim komentarzu nowa aplikacja internetowa zaczyna tworzyć stronę główną, która jest dokumentem HTML, a powyżej nie jest do niczego używana. Z kilku powodów zaleca się uruchomienie aplikacji internetowej z dokumentem HTML, w takim przypadku stronę główną można zmodyfikować w następujący sposób: <!DOCTYPE html> <html> <head> <title>todo supply a title</title> <meta charset="utf-8"> <meta name = "viewport" content = "width = device-width, initial-scale = 1.0"> <script> window.location = "start.jsp"; </script> </head> <body> </body> </html> W rezultacie strona główna wysyła żądanie do pliku start.jsp. Odbywa się to za pomocą JavaScript, który jest kodem wykonywanym po stronie klienta i powinieneś po prostu zaakceptować składnię. Jednak nie jest wymagane, aby strona główna tam była, a jeśli chcesz, możesz ją usunąć i zamiast tego pozwolić, aby strona JSP była stroną początkową. 5.1 OBLICZENIA We wstępnym przykładzie JSP pokazałem, jak łatwo jest powiązać na przykład pola wejściowe na stronie JSP z właściwościami w komponencie bean Java. Jest to również motyw w poniższym przykładzie (zwanym BeanFields), ale pokażę również, jak na stronie JSP przy użyciu innych metod z komponentu bean Java i jak obsługiwać metody, w tym metody set, co powoduje wyjątek. Projekt jest znowu projektem aplikacji internetowej, ale tym razem usunąłem stronę główną index.html. Dodałem jednak stronę JSP o nazwie index.jsp. Aby aplikacja mogła używać tej strony jako strony początkowej, może być konieczne dodanie pliku konfiguracyjnego web.xml. Jeśli nie, kliknij prawym przyciskiem myszy folder WEB-INF i wybierz Standardowy deskryptor wdrażania (web.xml). Zawartość pliku musi być następująca: <?xml version="1.0" encoding="utf-8"?> <web-app xmlns=" >

49 <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> <session-config> <session-timeout> 30 </session-timeout> </session-config> </web-app> Po otwarciu aplikacji w przeglądarce pojawia się okno: Jeśli wprowadzisz liczby całkowite w dwóch górnych polach i klikniesz górny przycisk OK, wynik może wyglądać tak, jak pokazano poniżej. Oznacza to, że wykonano pewne obliczenia dla dwóch liczb, a wyniki pojawiają się w pięciu wierszach wyników. Następnie w dolnym polu wejściowym wprowadź 107 (która jest liczbą pierwszą) i kliknij dolny przycisk OK, nic się nie dzieje, z wyjątkiem tego, że wszystkie pola zachowują swoje wartości, ale widać, że okno jest aktualizowane i że Zatwierdź. Jeśli teraz wpiszesz 108 i klikniesz OK, zobaczysz poniższe okno. Wynika to z faktu, że 108 nie jest liczbą pierwszą, a aplikacja zgłosiła wyjątek. Po kliknięciu opcji Powtórz powracasz do głównego okna i zauważ, że wszystkie wartości nadal tam są. W szczególności należy zauważyć, że dolne pole wejściowe nadal ma wartość 107. Na koniec są dwa łącza. Po kliknięciu jednego z nich dolne pole wejściowe zostanie zaktualizowane odpowiednio o następną lub poprzednią liczbę pierwszą. To była funkcjonalność, a program powinien pokazać, jak używać ziaren Java do oddzielania kodu HTML interfejsu użytkownika od kodu Java, zaimplementowanego w ziarenach Java i innych klasach. Jeden uważa to za ważne i dostajesz aplikację internetową, która jest o wiele łatwiejsza w utrzymaniu.

50 Program korzysta z dwóch komponentów Java Beanfield, które znajdują się w pakiecie beanfields.beans. Pierwszy reprezentuje dwa górne pola wejściowe i jest następujący: package beanfields.beans; import java.io.*; public class MathBean implements Serializable private long arga; private long argb; public MathBean()

51 public long getarga() return arga; public long getargb() return argb; public void setarga(long arga) this.arga = arga; public void setargb(long argb) this.argb = argb; public long add() return arga + argb; public long subtract() return arga argb; public long multiply()

52 return arga * argb; public long divide() if (argb == 0) return 0; return arga / argb; public long modulus() if (argb == 0) return 0; return arga % argb; Klasa wypełnia niektóre wiersze, ale jest banalna. Należy zauważyć, że klasa została napisana zgodnie z wymaganiami komponentu bean Java, a tutaj należy szczególnie zwrócić uwagę na nazwy dwóch zmiennych oraz metody get i set zgodne ze standardem komponentu bean Java. Zauważ również, że klasa ma inne metody (5 metod obliczeniowych). W tym miejscu należy szczególnie zwrócić uwagę na dwóch ostatnich, którzy zwracają 0, jeśli obliczenie nie jest możliwe. W rzeczywistości powinni zrobić wyjątek, ale ponieważ strona JSP zawsze korzysta ze zwracanej wartości funkcji, nie można użyć tego rozwiązania. Druga Java beans jest następująca: package beanfields.beans; import java.io.*; public class PrimeBean implements Serializable private static final long max = L; private long prime = 2; public PrimeBean()

53 public long getprime() return prime; public void setprime(long n) throws Exception if (!isprime(n)) throw new Exception("Illegal prime"); prime = n; public boolean next() if (prime < max) if (prime == 2) prime = 3; else for (prime += 2;!isPrime(prime); prime += 2); return true; return false; public boolean prev() if (prime > 2) if (prime == 3) prime = 2; else for (prime -= 2;!isPrime(prime); prime -= 2); return true; return false;

54 public static boolean isprime(long n) if (n == 2 n == 3 n == 5 n == 7) return true; if (n < 11 n % 2 == 0) return false; for (long t = 3, m = (long)math.sqrt(n) + 1; t <= m; t += 2) if (n % t == 0) return false; return true; Tutaj jest także trochę kodu, a celem jest między innymi pokazanie, że komponent bean Java może zawierać złożony kod podobny do każdej innej klasy. Jest tylko jedna właściwość, która musi reprezentować liczbę pierwszą. Dlatego jego metoda set może wywołać wyjątek, jeśli spróbujesz przypisać jej wartość inną niż pierwotna. Oprócz tej właściwości istnieją dwie metody, które przypisują wartość odpowiednio do następnej i poprzedniej liczby pierwszej - jeśli to możliwe. Program ma inną klasę Java, która jest serwletem i nazywa się PrimesServlet. Klasa znajduje się w pakiecie beanfields.servlets, a processrequest() = "Primes", urlpatterns = "/Primes") public class PrimeServlet extends HttpServlet protected void processrequest(httpservletrequest request, HttpServletResponse response) throws ServletException, IOException PrimeBean bean = (PrimeBean)request.getSession().getAttribute("prim"); String arg = request.getparameter("arg"); if (arg.equals("next")) bean.next(); else bean.prev(); response.sendredirect("index.jsp"); To bardzo prosty serwlet. Zaczyna się od określenia odwołania do obiektu sesji, który jest PrimeBean, a następnie wykonuje next () lub prev () w zależności od wartości parametru. Na koniec następuje przekierowanie na stronę początkową. To był kod Java, a tam są dwie strony JSP. Pierwszy to index.jsp, na który należy zwrócić uwagę: <%@page contenttype="text/html" session="true" pageencoding="utf-8"%> <%@page errorpage="error.jsp" %> <!DOCTYPE html> <html>

55 <head> <meta http-equiv="content-type" content="text/html; charset=utf-8"> <title>jsp Page</title> </head> <body> <h1>calculations</h1> <jsp:usebean id="math" scope="session" class="beanfields.beans.mathbean"/> <jsp:usebean id="prim" scope="session" class="beanfi <jsp:setproperty name="math" property="*"/> <jsp:setproperty name="prim" property="prime"/> <form name="form1" method="post"> <table> <tr> <td>a: </td> <td><input type="text" name="arga" value="$math.arga" style="width: 120px"/></td> </tr> <tr> <td>b: </td> <td><input type="text" name="argb" value="$math.argb" style="width: 120px"/></td> </tr> <tr> <td colspan="2" style="text-align: right"> <input type="submit" value="ok"/></td> </tr> </table> </form> <table> <tr> <td>sum</td><td>$math.add()</td> </tr> <tr>

56 <td>difference </td><td>$math.subtract()</td> </tr> <tr> <td>product</td><td>$math.multiply()</td> </tr> <tr> <td>quotient</td><td>$math.divide()</td> </tr> <tr> <td>modulus</td><td>$math.modulus()</td> </tr> </table> <form name="form2" method="post"> <input type="text" name="prime" value="$prim.prime"/> <input type="submit" value="ok"/> </form> <p><a href="primes?arg=next">next prime</a></p> <p><a href="primes?arg=prev">previous prime</a></p> </body> </html> Strona zaczyna się od dwóch dyrektyw. Pierwszy jest dodawany przez NetBeans, ale należy pamiętać, że dodałem atrybut: session = "true" co oznacza, że dowolne komponenty bean Java mogą być tworzone jako obiekty sesji. Następna dyrektywa odnosi się do strony błędów JSP i wskazuje stronę, do której nastąpi automatyczne przekierowanie w przypadku wyjątku. Tutaj możesz następnie dokonać odpowiedniej obsługi błędów. W sekcji body pierwszą rzeczą jest utworzenie dwóch obiektów bean Java. W tym miejscu należy szczególnie zauważyć, że ich zakres obejmuje sesję, co oznacza, że są to obiekty, których wartość jest zachowywana w kontekście przesłania strony, i ważną częścią wyjaśnienia jest to, że wartości strony są zachowywane po przesłaniu, jednak rzeczywiste rozumowanie to dwa linki na końcu strony. Po zadeklarowaniu dwóch ziaren są zdefiniowane do aktualizacji o wartości pól wejściowych. Oznacza to, że należy wykonać metody ustawione dla klas. Należy zauważyć, że za pomocą * można wskazać, że są to wszystkie właściwości lub można dokładnie określić, którą właściwość należy zaktualizować. Tak jest w przypadku prim, chociaż w tym przypadku nie ma powodu, ponieważ istnieje tylko jedna właściwość. Następnie należy zauważyć, jak powiązać właściwość w komponencie bean z polem wejściowym:

57 <input type = "text" name = "arga" value = "$ math.arga" style = "width: 120px" /> W szczególności powinieneś zwrócić uwagę na to, jak odwoływać się do indywidualnej właściwości i używać samej nazwy zmiennej. Właśnie dlatego fasola musi przestrzegać domyślnej nazwy. Pamiętaj też, że nazwa pola wejściowego jest taka sama jak bieżąca właściwość, co jest wymagane. Zgodnie z pierwszą formą o nazwie form1 następuje tabela, która wstawia zwracane wartości 5 metod obliczeniowych przy użyciu tej samej składni, jak wtedy, gdy właściwość jest połączona z polem wejściowym. Pamiętaj, że strona JSP (a także strona HTML) musi mieć więcej formularzy. Po kliknięciu przycisku wysyłania na serwer przesyłane są tylko wartości składników, które są częścią tego samego formularza co przycisk. Druga forma ma tylko jeden element wejściowy, który wiąże się z właściwością dla prim. Dzieje się to w taki sam sposób, jak wyjaśniono powyżej, ale jest to po prostu kolejna fasola Java. Wreszcie istnieją dwa łącza, które wyślą żądanie do serwletu. Serwlet nosi nazwę Liczby pierwsze, ale należy podać argument, który mówi, która operacja ma zostać wykonana. W tym miejscu należy szczególnie zwrócić uwagę na składnię dodawania argumentu do adresu URL: Primes?arg=next Z powrotem jest tylko strona błędu, która jest dość prostą stroną JSP: <%@page contenttype="text/html" pageencoding="utf-8" iserrorpage="true" %> <!DOCTYPE html> <html> <head> <meta http-equiv="content-type" content="text/html; charset=utf-8"> <title>jsp Page</title> </head> <body> <h1>there has been an error</h1> <p><a href="index.jsp">repeat</a></p> </body> </html> Jest to oczywiście bardzo prosta obsługa błędów, ale powiadamia użytkownika, że wystąpił błąd, a nie tylko pozwala programowi na działanie. 5.2 FUNKCJE

58 Możliwe jest również wywołanie metody statycznej w klasie i zastosowanie wartości zwracanej na stronie JSP, ale wymaga ona zarejestrowania metody w deskryptorze biblioteki znaczników, który jest również nazywany TLD. Program BeanFunction otwiera powyższe okno. Istnieje jedno pole wejściowe, które jest powiązane z właściwością w komponencie bean Java i jest dostępny przycisk przesyłania. Kliknięcie przycisku wysyła wartość pola do serwera, a program wstawia tekst nie jest liczbą pierwszą lub liczbą pierwszą. Dzieje się tak przez wywołanie metody statycznej, której argument jest wartością powyższej właściwości. Kod klasy fasoli jest następujący i wygląda jak ta sama fasola z poprzedniego przykładu, ale jest po prostu prostszy: package beanfunction.beans; import java.io.*; public class PrimeBean implements Serializable private long prime = 0; public PrimeBean() public long getprime() return prime; public void setprime(long n) prime = n;

59 public static boolean isprime(long n) if (n == 2 n == 3 n == 5 n == 7) return true; if (n < 11 n % 2 == 0) return false; for (long t = 3, m = (long)math.sqrt(n) + 1; t <= m; t += 2) if (n % t == 0) return false; return true; Zauważ, że ustawiona metoda tym razem nie sprawdza wartości. Aby utworzyć deskryptor biblioteki znaczników, dodałem katalog o nazwie tlds do WEB-INF, a następnie dodałem deskryptor do tego katalogu: Ten podkatalog nie jest konieczny, ale zaleca się utworzenie takiego katalogu, ponieważ większa aplikacja internetowa może mieć więcej deskryptorów biblioteki znaczników. Sam deskryptor nazywa się functions.tld i jest dokumentem XML: <?xml version="1.0" encoding="utf-8"?> <taglib version="2.1" xmlns=" xmlns:xsi=" xsi:schemalocation=" <tlib-version>1.0</tlib-version> <short-name>f</short-name> <uri>/web-inf/tlds/functions</uri> <function> <name>isprime</name> <function-class>beanfunction.beans.primebean</function-class> <function-signature>boolean isprime(long)</function-signature> </function>

60 </taglib> W tym przypadku nazwa to functions.tld i ma tak zwaną krótką nazwę o nazwie f. Jest używany w odniesieniu do metody. Zdefiniowano pojedynczą funkcję, a definicja zawiera nazwę funkcji, klasę funkcji i jej podpis. Dokument musi zawierać opis każdej metody statycznej, która musi być dostępna dla stron JSP. Poniżej znajduje się kod strony JSP: <%@page contenttype="text/html" pageencoding="utf-8"%> <!DOCTYPE html> <%@taglib prefix="c" uri=" %> <%@taglib uri="/web-inf/tlds/functions.tld" prefix="f" %> <html> <head> <meta http-equiv="content-type" content="text/html; charset=utf-8"> <title>jsp Page</title> </head> <body> <jsp:usebean id="prim" scope="request" class="beanfunction.beans.primebean"/> <jsp:setproperty name="prim" property="prime"/> <h1>prime number</h1> <form name="form1" method="post"> <p>enter a prime: <input type="text" name="prime" value="$prim.prime"/></p> <br/> <input type="submit" value="ok"/> </form> <p> <c:choose> <c:when test="$f:isprime(prim.prime)"> is a prime </c:when> <c:otherwise> is not a prime </c:otherwise> </c:choose> </p> </body>

61 </html> Deskryptor biblioteki znaczników rozszerza JSP o nowe elementy w postaci funkcji Java, które można następnie wykorzystać na stronie. Oto pierwsza seria rozszerzeń, które umożliwiają wprowadzenie warunków i pętli na stronie JSP, podczas gdy ta druga jest deskryptorem zdefiniowanym powyżej i który jest częścią projektu. Do dwóch TLD odwołuje się na stronie przy użyciu prefiksu, którym są odpowiednio c i f. Jeśli weźmiesz pod uwagę część ciała, zobaczysz, że fasola jest zdefiniowana, a jej właściwości muszą zostać zaktualizowane. Następnie jest formularz z polem wejściowym i przyciskiem przesyłania, aw porównaniu z poprzednim przykładem nie ma tu nic nowego. Następnie warunek jest następujący: Najpierw zwróć uwagę na definicję dwóch TLD: taglib prefix = "c" uri = " taglib uri = "/ WEB-INF / tlds / functions.tld" prefix = "f"%> Deskryptor biblioteki znaczników rozszerza JSP o nowe elementy w postaci funkcji Java, które można następnie wykorzystać na stronie. Oto pierwsza seria rozszerzeń, które umożliwiają wprowadzenie warunków i pętli na stronie JSP, podczas gdy ta druga jest deskryptorem zdefiniowanym powyżej i który jest częścią projektu. Do dwóch TLD odwołuje się na stronie przy użyciu prefiksu, którym są odpowiednio c i f. Jeśli weźmiesz pod uwagę część ciała, zobaczysz, że fasola jest zdefiniowana, a jej właściwości muszą zostać zaktualizowane. Następnie jest formularz z polem wejściowym i przyciskiem przesyłania, aw porównaniu z poprzednim przykładem nie ma tu nic nowego. Następnie warunek jest następujący: <c:choose> <c:when test="$f:isprime(prim.prime)"> is a prime </c:when> <c:otherwise> is not a prime </c:otherwise> </c:choose> select jest konstrukcją zdefiniowaną w bibliotece znaczników, która jest zdefiniowana przez przedrostek c i odpowiada instrukcji switch. Każdorazowo, gdy element jest kontrolowany przez warunek, w tym przypadku wartość zwracana z obiektu komponentu bean jest liczbą pierwszą. Metoda isprime () jest zdefiniowana w bibliotece, która ma prefiks f, i powinieneś zanotować, jak napisać warunek. Należy również pamiętać, jak podać argument dla isprime (). Jeśli warunek jest spełniony, następujący dokument HTML (tutaj tylko tekst) jest wstawiany do dokumentu. Lub wykonywany jest kolejny element inny. W takim przypadku wybierz funkcje jako if / else, ale mogą istnieć wszystkie elementy when, które mogą być potrzebne. PROBLEM 1 Musisz rozwiązać to samo zadanie, co problem 1 w książce Java 2, ale tym razem powinna to być aplikacja internetowa. Oznacza to, że musisz napisać program obliczania pożyczki, w którym użytkownik musi wprowadzić parametry pożyczki (koszty pożyczki, kwota pożyczki, stopa procentowa,

62 liczba lat i liczba okresów rocznie). Program powinien następnie obliczyć płatność. Program powinien rozpocząć się od formularza pokazanego poniżej. Jeśli wprowadzone zostaną niedozwolone wartości: - koszty nie mogą być ujemne - kwota pożyczki nie może być ujemna - liczba lat musi wynosić od 1 do 60 - liczba okresów w roku musi wynosić od 1 do 12 - stopa procentowa musi być większa niż 0 i mniejsza niż 25, zamiast tego powinieneś zostać przekierowany na stronę błędu. Po kliknięciu przycisku Wyczyść pola formularza muszą być puste. Jeśli wprowadzone zostaną prawne parametry pożyczki i zostanie obliczona pożyczka, należy wyświetlić dodatkowy przycisk, a po kliknięciu tego przycisku nastąpi przekierowanie do strony przedstawiającej plan amortyzacji. Poszczególne strony (strona główna i strona z planem amortyzacji) muszą być zapisane jako strony JSP, a pożyczka powinna być reprezentowana przez Java bean. 5.3 DOKUMENTY JSP Kiedy tworzysz stronę jsp w NetBeans, dostajesz okno pokazane poniżej, gdzie dla opcji domyślnie jest wybrany plik JSP (standardowa składnia), aw większości przypadków prawdopodobnie będziesz się go trzymał, ale możesz również wybrać dokument JSP (XML Składnia). Rezultatem jest strona JSP, która ma rozszerzenie jspx, która przypomina standardową stronę JSP, ale gdzie wymagana jest akceptacja strony XML. Ponieważ powyższe przykłady są już dobrze przyjęte, nie będzie dużej różnicy poza tym, że będą wymaganiem. Najważniejsze jednak, że dokument JSP nie pozwala na użycie skryptletów, co

63 zmusza programistę do umieszczenia całego kodu Java w komponentach bean Java i innych klasach, i to jest właśnie ten cel tej odmiany stron JSP. Jako przykład pokażę pierwszy program w tym rozdziale (aplikacja internetowa DateServer), w której strona start.jsp jest zastąpiona stroną start.jspx. Program nazywa się DateTimeServer i działa dokładnie tak samo, jak aplikacja DateServer. Używa tej samej fasoli Java DateBean, a dodatkowo dodaje się następującą prosty bean: package datetimeserver.beans; import java.util.*; public class CurrentTime implements java.io.serializable public CurrentTime() public String gettime() Calendar dt = Calendar.getInstance(); return String.format("%02d-%02d-%04d %02d:%02d:%02d", dt.get(calendar.date), dt.get(calendar.month) + 1, dt.get(calendar.year), dt.get(calendar.hour_of_day), dt.get(calendar.minute), dt.get(calendar.second));

64 Then, the jspx page can be written as follows: <?xml version="1.0" encoding="utf-8"?> <jsp:root xmlns:jsp=" version="2.0"> <jsp:directive.page contenttype="text/html" pageencoding="utf-8"/> <jsp:element name="text"> <jsp:attribute name="lang">en</jsp:attribute> <jsp:body> <jsp:usebean id="datebean" scope="page" class="datetimeserver.beans.datebean"/> <jsp:usebean id="timebean" scope="page" class="datetimeserver.beans.currenttime"/> <jsp:setproperty name="datebean" property="*"/> <h1>hello World!</h1> <h2 style="color:red">the current time: $timebean.time</h2> <h3>the date is: $datebean.date</h3> <h3>the time is: $datebean.time</h3> <form method="post"> <table> <tr> <td>date</td> <td><input type="text" id="date" name="date" style="width:120px"/></td> </tr> <tr> <td>time</td> <td><input type="text" name="time" style="width:120px"/></td> </tr> </table> <input type="submit" value="update"/> </form> </jsp:body> </jsp:element> </jsp:root>

65 Jak widać, najczęściej kopiuje się i wkleja z poprzedniego przykładu, ale należy zauważyć trzy rzeczy. Przede wszystkim chodzi o dobrze sformatowany XML. Po drugie, nie ma skrawków, a jeśli spróbujesz użyć skrawków, pojawi się błąd. Po trzecie, istnieje kilka nowych elementów w postaci jsp: xxxx, a niektóre mogą pojawić się więcej niż pokazano w tym przykładzie. Jak wspomniano powyżej, celem dokumentów JSP jest zmuszenie do niestosowania skrawków. To prawda, że przesadne użycie skryptów prowadzi do kodu, który jest trudniejszy do odczytania i utrzymania, ale odwrotnie, ma również swoje zastosowania i ogólnie wolę standardowe strony JSP. Po pierwsze, dzięki nowoczesnym narzędziom programistycznym, takim jak NetBeans, łatwo jest upewnić się, że kod jest dobrze sformułowany, a po drugie, oznacza to, że ponieważ korzystanie ze skryptów jest dozwolone, nie musisz ich używać lub przynajmniej możesz zminimalizować używać i używać skrawków tylko tam, gdzie ma to sens. 5.4 ZMIANA ADRESU 2 Nazwałem ten przykład dla ChangeAddress2, ponieważ jest to trochę ten sam problem, co w przykładzie ChangeAddress1, ale tak naprawdę nie ma nic o przenoszeniu wiadomości. Przykład pokazuje aplikację internetową, która symuluje, że pracownicy w firmie mogą wprowadzać i przechowywać dane osobowe, takie jak imię i nazwisko, adres, adres i inne. Oprócz tego powinieneś być w stanie uzyskać ogólny przegląd wszystkich danych pracowników. Przykład jest nieco większy niż poprzednie przykłady w tej książce i powinien pokazywać wiele rozwiązań, które są częścią typowej aplikacji internetowej. Jest wiele szczegółów, ale jednym z głównych celów tego przykładu jest pokazanie aplikacji internetowej korzystającej z bazy danych. Dlatego zacznę od opisu bazy danych, która korzysta z tabeli o nazwie osoba w bazie danych. Oprócz tej tabeli używany jest kod pocztowy tabeli. Tabela osób jest zdefiniowana w następujący sposób: use padata; drop table if exists persons; create table persons ( id int not null auto_increment primary key, firstname varchar(40) not null, lastname varchar(30) not null, addrline1 varchar(30), addrline2 varchar(30), zipcode char(4) not null, phone varchar(20), varchar(50) not null, title varchar(50), date date, passwd varchar(150), foreign key (zipcode) references zipcode(code) ); alter table persons auto_increment=1001; Znaczenie kolumn powinno wynikać z nazw - być może dwóch ostatnich. Data kolumny musi zawierać datę ostatniej aktualizacji wiersza, a ostatnia kolumna może zawierać hasło, które powinno zostać zaszyfrowane. Należy również pamiętać, że oprócz klucza są jedynymi kolumnami, które muszą mieć wartość imię, nazwisko, kod pocztowy i adres , a także, że kod pocztowy kolumny jest kluczem obcym do kodu pocztowego tabeli. Po uruchomieniu aplikacji pojawia się następująca przeglądarka:

66 które mogą być postrzegane jako strona powitalna. Jest to strona JSP o nazwie index.jsp i zawiera łącza do trzech innych stron JSP, które dotyczą trzech funkcji, które aplikacja może wykonywać. Strona nie wygląda dużo, ale wciąż jest wiele nowych, ponieważ strona ma nagłówek (kolorowy obszar). Jest to strona JSP, która jest częścią innej strony JSP. Ponadto aplikacja korzysta z arkusza stylów i odrobiny kodu JavaScript. Patrząc na górną linię, składa się z nagłówka oraz tekstu dotyczącego webmastera strony. Ten ostatni jest przykładem niestandardowego elementu WWW. Przykład może być w tym przypadku nieco przeszukany, ale niestandardowy element internetowy jest zdefiniowany jako klasa pochodna klasy SimpleTagSupport: package changeaddress; import javax.servlet.jsp.*; import javax.servlet.jsp.tagext.*; public class Webmaster extends SimpleTagSupport private String master1 = null; private String master2 = null; public void setmaster1(string master) master1 = master; public void setmaster2(string master) master2 = master;

67 @Override public void dotag() throws JspException PageContext context = (PageContext) getjspcontext(); JspWriter out = context.getout(); try out.println("web master: " + master1); if(master2!= null) out.println(" and " + master2); catch (Exception e) W takim przypadku element musi mieć dwa atrybuty, które są łańcuchami i są odpowiednio nazywane master1 i master2. Oba atrybuty mają ustawione metody, ale w przeciwnym razie metoda dotag () określa sposób renderowania elementu w przeglądarce. Aby niestandardowe elementy sieciowe mogły być używane w aplikacji, muszą być zarejestrowane w pliku opisu tagu Lidrary (którego wcześniej użyłem do zdefiniowania funkcji), w tym przypadku zawartość jest następująca: <?xml version="1.0" encoding="utf-8"?> <taglib version="2.1" xmlns=" > <tlib-version>1.0</tlib-version> <short-name>t</short-name> <uri>/web-inf/tlds/taglib</uri> <tag> <name>webmaster</name> <tag-class>changeaddress.webmaster</tag-class> <body-content>empty</body-content>

68 <attribute> <name>master1</name> <rtexprvalue>true</rtexprvalue> <required>true</required> </attribute> <attribute> <name>master2</name> <rtexprvalue>true</rtexprvalue> <required>false</required> </attribute> </tag> </taglib> Zauważ, że jako skróconą nazwę użyłem litery t. Plik definiuje pojedynczy element o nazwie webmaster, a oprócz nazwy klasy musisz zdefiniować atrybuty elementu, w tym przypadku są dwa. Atrybut jest zdefiniowany przez nazwę i gdzie jest wymagany. Nazwa rtexprvalue określa, czy atrybut musi zostać zainicjowany wartością serwera $. Po wprowadzeniu tego niestandardowego elementu nagłówek można zdefiniować jako następującą stronę JSP, o nazwie header.jsp: <%@taglib uri="/web-inf/tlds/taglib.tld" prefix="t" %> <html xmlns:jsp=" version="2.0"> <jsp:directive.page contenttype="text/html" pageencoding="utf-8"/> <div class="header-class" style="height: 40px;"> <table> <tr> <td style="font-size: xx-large; font-weight: bold; color: navy;"> Borremose voldsted</td> <td style="font-size: small; color: gray;"> <t:webmaster master1="knud den Store" master2="regnar Lodbrog"/></td> </tr> </table> <br/> </div> </html> Należy zauważyć, że biblioteka znaczników opisana powyżej jest zdefiniowana przez dyrektywę, ale w przeciwnym razie należy zauważyć, że nie ma treści. To nie jest prawdziwa strona JSP, ale niektóre

69 strony JSP przeznaczone do wstawienia na innej stronie JSP. Jednym z głównych wyzwań w rozwoju aplikacji internetowych jest wizualna reprezentacja, a tym samym sposób wyświetlania strony w przeglądarce. Jest to coś, co dotknę tylko w ograniczonym zakresie, ale zazwyczaj szczegóły określasz za pomocą stylów. Oznacza to, że dla każdego z dwóch powyższych elementów TD zdefiniowano styl wskazujący rozmiar i kolor czcionki. Mówiąc bardziej ogólnie, możesz zdefiniować style w arkuszu stylów, który jest dokumentem stylów, które strony aplikacji mogą zastosować. W ramach tej aplikacji zdefiniowałem następujący arkusz stylów: body font-family: "Liberation Sans" p width: 800px li margin: 10px 0.error font-weight: bold; color: red.header-class background: bisque table.imagetable

70 font-family: verdana,arial,sans-serif; font-size:11px; color:#333333; border-width: 1px; border-color: #999999; border-collapse: collapse; table.imagetable th background:#b5cfd2 url('cell-blue.jpg'); border-width: 1px; padding: 8px; border-style: solid; border-color: #999999; table.imagetable td background:#dcddc0 url('cell-grey.jpg'); border-width: 1px; padding: 8px; border-style: solid; border-color: #999999; Istnieje oczywiście wiele szczegółów składniowych związanych z arkuszami stylów, ale kiedy czytasz poszczególne style, są one wystarczająco łatwe do zrozumienia, a NetBeans zna arkusze stylów, a także zapewnia pomoc dla poszczególnych stylów. W praktyce arkusz stylów może być bardzo obszerny, a cała idea polega na przeniesieniu definicji sposobu wyświetlania poszczególnych elementów HTML z dokumentów HTML i JSP. Oznacza to z jednej strony, że dokumenty te stają się prostsze i łatwiejsze do zrozumienia, a częściowo że łatwiej jest zachować wygląd witryn, ponieważ wystarczy zmodyfikować arkusz stylów. Chodzi o to, że dokumenty HTML i JSP powinny definiować tylko treść, a arkusze stylów określają sposób renderowania treści w przeglądarce. Arkusz stylów jest zatem dokumentem tekstowym wysyłanym ze stroną, ponieważ przeglądarka używa go do renderowania dokumentu. Arkusz stylów nie jest używany po stronie serwera. W tym przypadku zdefiniowano 9 stylów. Pierwsze trzy są bardzo proste i definiują czcionkę dla elementu body (a więc i całego dokumentu), która powinna obowiązywać domyślnie oraz jak szeroki

71 powinien być akapit (taka linia tekstu niekoniecznie wypełnia cały ekran), i która górny margines elementu li musi wynosić 10. Następne dwa definiują tak zwaną klasę, którą można powiązać z określonymi elementami. Na przykład klasa nagłówka używana w powyższym nagłówku: <div class = "header-class"> Ostatnie trzy style są bardziej złożone i definiują style, których można użyć w tabeli HTML. Wrócę do nich później. Te style są używane we wszystkich dokumentach korzystających z tego arkusza stylów. Jeśli spojrzysz na kod strony głównej, możesz zobaczyć, w jaki sposób element łączący w nagłówku pozwala na użycie danego arkusza stylów: <%@page contenttype="text/html" pageencoding="utf-8"%> <!DOCTYPE html> <html> <head> <meta http-equiv="content-type" content="text/html; charset=utf-8"> <title>start page</title> <link rel="stylesheet" href="styles.css" type="text/css"/> </head> <body> <jsp:include page="header.jsp"/> <h1>employee information</h1> <p>on this page.. </p> <p>the individual employee.. </p> <ul> <li><a href="login.jsp">enter employee information</a></li> <li><a href="show.jsp">show employee informations</a></li> <li><a href="passwd.jsp">new password</a></li> </ul> </body> </html> Należy również zwrócić uwagę na sposób wstawiania powyższego nagłówka za pomocą elementu jsp: include jako pierwszej linii w sekcji body. Należy pamiętać, że jest to po stronie serwera i to serwer jest odpowiedzialny za utworzenie ukończonego dokumentu. W tej aplikacji wszystkie strony zaczynają się od tego nagłówka i może pomóc zapewnić, że wszystkie strony w aplikacji sieci web mają wspólny wygląd i jest łatwy do zmiany, ponieważ można łatwo zmienić nagłówek. Należy również zauważyć, że w zasadzie strona JSP może zawierać wszystkie elementy jsp: zawierać elementy, które mogą być

72 pożądane i mogą pojawiać się w dowolnym miejscu. Jeśli klikniesz górny link na stronie głównej, pojawi się następująca przeglądarka: Powinien on ilustrować prostą stronę logowania. W takim przypadku użytkownik musi wprowadzić swój numer pracownika i hasło, a po kliknięciu przycisku informacje te zostaną przesłane do serwera. Jeśli użytkownik wprowadzi tylko hasło (nie ma numeru pracownika), jest to postrzegane jako tworzenie nowego pracownika, w przeciwnym razie oznacza to, że możesz edytować informacje o pracowniku. Ze względów praktycznych może nie być odpowiednie, ale nie chcę, aby aplikacja była bardziej rozbudowana niż to konieczne. Strona jest oczywiście w zasadzie formularzem i, w zasadzie, jest to bardzo prosta strona, która polega po prostu na wysłaniu formularza na serwer, ale niemniej jednak istnieją wyzwania wymagające rozwiązania. Gdy formularz jest wysyłany do serwera, serwer musi sprawdzić, czy wprowadzone dane są zgodne z prawem. W takim przypadku numer pracownika musi być 4-cyfrową liczbą całkowitą (automatycznie przypisywaną przez serwer bazy danych) i musi istnieć hasło. Jeśli numer pracownika jest pusty, serwer musi utworzyć nowego pracownika i przypisać go do automatycznie wygenerowanego numeru. Jeśli wprowadzono numer pracownika, serwer musi go zweryfikować, a jeśli jest to zgodne z prawem, serwer musi sprawdzić, czy w bazie danych znajduje się pracownik z tym numerem i hasłem oraz, jeśli to konieczne, załadować dane pracownika. Jeśli dane formularza są nielegalne, program musi powrócić do logowania z komunikatem o błędzie, a pola formularza muszą zachować tam zawartość, aby użytkownik mógł edytować treść. Jeśli dane mogą zostać zaakceptowane, serwer musi przejść do strony edycji, aby użytkownik mógł edytować dane. Wszystko to wymaga trochę kodu Java i chcę zacząć od prostej fasoli, która może reprezentować dane na stronie logowania: package changeaddress.beans; import java.io.*; public class LoginBean implements Serializable private String userid;

73 private String passwd; private String error; public LoginBean() public String getuserid() return userid; public void setuserid(string userid) this.userid = userid; public String getpasswd() return passwd; public void setpasswd(string passwd) this.passwd = passwd; public String geterror() return error;

74 public void seterror(string error) this.error = error; Nie ma wiele do wyjaśnienia, ale powinieneś zauważyć, że istnieje dodatkowa właściwość, którą nazwałem błędem i służy ona do odesłania komunikatu o błędzie. Następnie stronę JSP można zapisać w następujący sposób: <%@page contenttype="text/html" pageencoding="utf-8" session="true"%> <%@page errorpage="error.jsp" %> <!DOCTYPE html> <html> <head> <meta http-equiv="content-type" content="text/html; charset=utf-8"> <title>login</title> <link rel="stylesheet" href="styles.css" type="text/css"/> <script src='scripts.js'></script> <script> function encryptpassword() var passwd = ("" + document.getelementbyid("passwd").value).trim(); if (passwd.length > 0) document.getelementbyid("passwd").value = createhash(passwd); return true; </script> </head> <body> <jsp:usebean id="loginbean" class="changeaddress.beans.loginbean" scope="session"/> <jsp:include page="header.jsp"/> <h2>login</h2> <form method="post" action="personservlet" onsubmit="return encryptpassword()"> <table> <tr>

75 <td>enter your employee number: </td> <td><input type="text" id="mednr" name="userid" style="width:120px" value="$loginbean.userid"/></td> </tr> <tr> <td colspan="2"><div style="font-size: xx-small"> Aby utworzyć nowego pracownika, po prostu nie wpisuj numeru pracownika </div></td> </tr> <tr> <td colspan="2" style="height: 10px"></td> </tr> <tr> <td>enter password</td> <td><input type="password" id="passwd" name="passwd" style="width:120px" value="$loginbean.passwd"/></td> </tr> <tr> <td colspan="2" style="height: 20px"></td> </tr> <tr> <td colspan="2" style="text-align: right"><input type="submit" id="edit" name="edit" value="edit employee"/></td> </tr> <tr> <td colspan="2" style="height: 20px"></td> </tr> <tr> <td colspan="2" style="text-align: right"><a href="start">cancel</a></td> </tr> </table> </form>

76 <div class="error">$loginbean.error</div> </body> </html> Zauważ, że wiersz 2 odnosi się do strony błędu. Zasadniczo nigdy nie powinieneś wchodzić na tę stronę, ponieważ serwer sprawdza poprawność danych, ale zostaniesz wysłany na stronę błędu w przypadku jednego lub więcej poważnych błędów, czyli w przypadku wystąpienia wyjątku. Zwróć także uwagę, w jaki sposób zastosowano powyższy LoginBean i jak jego właściwości są połączone z polami wejściowymi, a także z elementem div na końcu dokumentu. Służy do wyświetlania możliwego komunikatu o błędzie. Należy pamiętać, że zakres konkretnej fasoli to sesja. Oznacza to, że wartość obiektów jest zachowywana przez całą sesję. Na koniec należy zauważyć, że strona odczytuje tylko obiekt bean, ale go nie aktualizuje. W przeciwnym razie możesz zauważyć, że strona używa arkusza stylów, a jedno pole wejściowe ma hasło typu. Oznacza to po prostu, że wpisy użytkownika nie są wyświetlane jako tekst. Najważniejszą rzeczą jest jednak element formularza, którego działanie wskazuje, że formularz należy wysłać do PersonServlet, który jest obiektem Java przetwarzającym formularz, a na koniec element formularza stwierdza, że przed przesłaniem funkcja JavaScript encryptpassword () należy wykonać. Hasło użytkownika musi być przechowywane w postaci zaszyfrowanej w bazie danych, a wcześniej pokazałem (w książce Java 7), jak to zrobić. Java ma dla niego klasy, które określają skrót hasła i przechowują go w bazie danych. Powoduje to jednak problem, ponieważ może się zdarzyć tylko po stronie serwera, dlatego hasło musi zostać przesłane do serwera zwykłym tekstem, aby inni mogli go przechwycić. Dlatego szyfrowanie musi być wykonane po stronie klienta, a tutaj mam obecnie tylko JavaScript. Podsumowanie wiadomości jest określane za pomocą złożonego algorytmu i istnieje kilka, które można zastosować i które różnią się pod względem siły, a tym samym stopnia trudności. Algorytm jest dobrze opisany w Internecie i można łatwo znaleźć przykład, w którym jest on zaimplementowany w JavaScript. Plik scripts.js implementuje taki algorytm (algorytm SHA-1). Nie jest to najsilniejszy algorytm, ale dla wielu praktycznych celów jest wystarczająco silny. Nie chcę tutaj przeglądać algorytmu ani pokazywać kodu, ale krótko mówiąc, pomysł polega na zmodyfikowaniu tekstu w taki sposób, aby nie można go było rozpoznać i nie można było żałować, a na podstawie tego komunikatu określić hasło. Jednak po stronie klienta pojawia się problem, więc każdy może zobaczyć, co się dzieje, i dlatego dyskutuje się, czy bezpiecznie jest zaszyfrować hasło za pomocą kodu skryptu, ponieważ taki kod nie jest nie do odrzucenia, ale w odniesieniu do tego przykładu, musi wystarczyć. Jeśli szyfrowanie jest bezpieczne, zwykle wymagane jest inne podejście (inna implementacja) niż pokazuje to ten przykład. Zanim spojrzę na PersonServlet, przyjrzę się klasie PersonBean, która jest fasolą Java, która definiuje osobę. Klasa jest obszerna i pokazałem tylko część kodu: public class PersonBean implements Serializable private static ArrayList<Zipcode> list = new ArrayList(); private int userid; private String firstname; private String lastname; private String addrline1; private String addrline2;

77 private String code; private String city; private String phone; private String ; private String title; private Calendar date; private String passwd; private String error; public PersonBean() public void setuserid(string userid) throws Exception if (userid.trim().length() == 0) this.userid = 0; return; try int id = Integer.parseInt(userid); if (id < 1000 id > 9999) throw new Exception(" "); this.userid = id; catch (Exception ex) throw new Exception("Illegal value for userid: " + ex.getmessage()); public void setfirstname(string firstname) throws Exception

78 firstname = firstname.trim(); if (firstname.length() == 0) throw new Exception(" "); this.firstname = Tools.cut(firstname, 40); public void setcode(string code) throws Exception code = code.trim(); for (Zipcode zc : list) if (zc.code.equals(code)) this.code = zc.code; this.city = zc.city; return; throw new Exception("Illegal zipcode"); public String getdate() if (date == null) return ""; return String.format("%02d-%02d-%04d", date.get(calendar.date), date.get(calendar.month) + 1, date.get(calendar.year)); public void setdate(string date) throws Exception try java.text.dateformat formatter = new java.text.simpledateformat("dd-mm-yyyy"); if (this.date == null) this.date = java.util.calendar.getinstance(); this.date.settime(formatter.parse(date)); catch (Exception ex)

79 throw new Exception("Illegal date"); static try (Connection conn = DB.getConnection(); Statement stmt = conn.createstatement()) ResultSet res = stmt.executequery("select * FROM zipcode"); while (res.next()) list.add(new Zipcode(res.getString("code"), res.getstring("city"))); catch(exception ex) class Zipcode public String code; public String city; public Zipcode(String code, String city) this.code = code; this.city = city; Patrząc na zmienne klasy, jasne jest, że odzwierciedla wiersz w bazie danych, a zatem może reprezentować osobę. Jednak klasa dalej definiuje kilka zmiennych jako miasto i błąd. W tym

80 przypadku ostatni należy użyć do komunikatu o błędzie podczas edytowania danych osoby. Podobnie jak w definicji bazy danych, należy sprawdzić następujące pola: - useris - Imię - nazwisko - kod - Metody ustawione dla tych zmiennych wywołują wyjątek w przypadku błędów. Na przykład metoda setfirstname (), która zapewnia, że imię ma wartość. Zmienna wiadomość jest sprawdzana za pomocą metody ismail (), którą można znaleźć w klasie Narzędzia. To ta sama metoda, którą pokazałem wcześniej. Wreszcie jest kod zmienny, a ponieważ odpowiednia kolumna w bazie danych to klucz obcy, metoda setcode () musi sprawdzić, czy znaleziono kod pocztowy. Aby metoda nie zawsze musiała łączyć się z bazą danych i wykonywać WYBÓR, kody pocztowe są ładowane raz na zawsze w ArrayList <Zipcode>. Oto kod pocztowy to prosta klasa, która może reprezentować kod pocztowy przez dwa pola. Odczytywanie kodów pocztowych odbywa się w konstruktorze statycznym i zasadniczo nie wymaga żadnego specjalnego wyjaśnienia. Wymaga to jednak połączenia z bazą danych, a klasa DB ma metodę, która może utworzyć to połączenie z bazą danych. Zaczekam na później opisanie tej klasy, ale będzie ona używana w kilku miejscach. Po zainicjowaniu listy arraylistów metoda setcode () może łatwo sprawdzić, czy kod pocztowy jest zgodny z prawem. W razie potrzeby inicjuje również zmienne miasto. Następnie istnieje PersonServlet, czyli serwlet, na który strona JSP login.jsp publikuje formularz po kliknięciu przycisku = "PersonServlet", urlpatterns = "/PersonServlet") public class PersonServlet extends HttpServlet protected void processrequest(httpservletrequest request, HttpServletResponse response) throws ServletException, IOException request.setcharacterencoding("utf-8"); LoginBean bean = (LoginBean)request.getSession(true).getAttribute("loginBean"); String usr = request.getparameter("userid").trim(); String pwd = request.getparameter("passwd").trim(); if (pwd.length() == 0) bean.seterror("you must enter password"); bean.setuserid(usr); bean.setpasswd(""); response.sendredirect("login.jsp");

81 return; PersonBean person = new PersonBean(); if (usr.length() > 0) if (!userok(usr)) bean.seterror("illegal user ID"); bean.setuserid(usr); bean.setpasswd(""); response.sendredirect("login.jsp"); return; if (!loadperson(person, usr, pwd)) bean.seterror("employee number not found or illegal password"); bean.setuserid(usr); bean.setpasswd(""); response.sendredirect("login.jsp"); return; else person.setpasswd(pwd); request.getsession().setattribute("personbean", request.getsession().removeattribute("loginbean"); request.getrequestdispatcher("/edit.jsp").forward(request, response); person); private boolean userok(string userid) try int t = Integer.parseInt(userid); return t > 1000 && t < 10000;

82 catch (Exception ex) return false; private boolean loadperson(personbean person, String userid, String passwd) try (Connection conn = DB.getConnection(); Statement stmt = conn.createstatement()) ResultSet res = stmt.executequery("select * FROM persons WHERE id = " + userid + " AND passwd = '" + passwd + "'"); if (res.next()) person.setuserid("" + res.getint("id")); person.setfirstname(res.getstring("firstname")); person.setlastname(res.getstring("lastname")); person.setaddrline1(res.getstring("addrline1")); person.setaddrline2(res.getstring("addrline2")); person.setcode(res.getstring("zipcode")); person.setphone(res.getstring("phone")); person.set (res.getstring(" ")); person.settitle(res.getstring("title")); person.setdate(tools.tostr(res.getdate("date"))); return true; return false; catch(exception ex) return false;

83 Pokazałem tylko tę część kodu, która wyjaśnia, co się dzieje i jest to przede wszystkim processrequest (). Najpierw zanotuj wiersz request.setcharacterencoding ( UTF-8 ); Konieczne jest zapewnienie poprawnego przetwarzania listów duńskich podczas przesyłania formularza. Być może nie jest tak ważne w tym przykładzie, ale w związku z następną formą jest. Pierwszą rzeczą, która się dzieje, jest dodanie odwołania do obiektu komponentu bean: LoginBean login = LoginBean) request.getsession (). GetAttribute ("loginbean"); Zauważ, że obiekt istnieje, ponieważ jest zdefiniowany w zakresie sesji. Następnie określana jest wartość numeru pracownika i hasła (które jest teraz szyfrowane), a metoda sprawdza, czy hasło zostało przesłane. Jeśli nie, do obiektu komponentu bean dołączany jest komunikat o błędzie, a serwer wykonuje przekierowanie z powrotem do login.jsp. Ponieważ obiekt komponentu bean nadal istnieje, strona wyświetli komunikat o błędzie. Po wprowadzeniu hasła tworzony jest obiekt PersonBean. Jeśli numer pracownika został wprowadzony (długość jest dodatnia), najpierw jest sprawdzany, jeśli jest to dodatnia 4-cyfrowa liczba całkowita. Jeśli nie, komunikat o błędzie zostanie zwrócony w taki sam sposób jak powyżej. W przeciwnym razie wywoływana jest metoda loadperson (), aby spróbować odczytać osobę z bazy danych z odpowiednim numerem pracownika i hasłem. Czy to możliwe, PersonBean inicjuje obiekt całymi danymi, ale w przeciwnym razie ponownie powraca do login.jsp z komunikatem o błędzie. Jeśli z drugiej strony wprowadzony numer pracownika jest pusty, PersonBean inicjuje obiekt za pomocą wprowadzonego hasła. Jeśli można uzyskać dostęp do hasła i numeru pracownika, wówczas PersonBean jest zapisywany jako obiekt sesji, jednocześnie usuwając obiekt sesji loginbean. Należy upewnić się, że element nie będzie dostępny przy następnym otwarciu strony logowania. Na koniec przekazywana jest strona edit.jsp, na której można edytować obiekt PersonBean. W ostatnim komentarzu do login.jsp znajduje się link do anulowania. Jeśli klikniesz ten link, musisz wrócić do strony głównej, ale zamiast robić to bezpośrednio, wywoływany jest serwlet StartServlet. Jego procesrequest () jest = "start", urlpatterns = "/start") public class StartServlet extends HttpServlet protected void processrequest(httpservletrequest request, HttpServletResponse response) throws ServletException, IOException HttpSession session = request.getsession(false); f (session!= null) session.invalidate(); request.getrequestdispatcher("/index.jsp").forward(request, response);

84 Celem jest zakończenie sesji, aby obiekt loginbean (i ewentualne inne obiekty sesji) przestał istnieć. Następnie jest edit.jsp, w przypadku nowego pracownika otwiera stronę poniżej. Strona jest w zasadzie formularzem i zasadniczo nie różni się od login.jsp. To dużo wypełnia, a pokazałem tylko część kodu HTML: <%@page contenttype="text/html" pageencoding="utf-8"%> <%@page errorpage="error.jsp" %> <!DOCTYPE html> <html> <head> <meta http-equiv="content-type" content="text/html; charset=utf-8"> <title>jsp Page</title> <link rel="stylesheet" href="styles.css" type="text/css"/> </head> <body> <jsp:usebean id="personbean" class="changeaddress.beans.personbean" scope="session"/> <jsp:include page="header.jsp"/> <h2>edit data</h2> <form method="post" action="storeservlet"> <table> <tr> <td>employee number </td> <td><input type="text" name="userid" readonly="true" style="width:60px" value="$personbean.userid" /></td> </tr> <tr> <td colspan="2" style="text-align: right"><a href="start">cancel</a></td> </tr> </table> </form> <br/><br/> <div class="error">$personbean.error</div>

85 </body> </html> W porównaniu do login.jsp nie ma nic nowego do wyjaśnienia i działa w zasadzie w ten sam sposób. Należy zauważyć, że istnieje odwołanie do obiektu personbean i że podczas przesyłania formularza wysyłane jest żądanie do serwletu o nazwie StoreServlet. Jest to processrequest(): protected void processrequest(httpservletrequest request, HttpServletResponse response) throws ServletException, IOException response.setcontenttype("text/html;charset=utf-8"); PersonBean person = (PersonBean)request.getSession().getAttribute("personBean"); try

86 request.setcharacterencoding("utf-8"); person.setfirstname(request.getparameter("firstname")); person.setlastname(request.getparameter("lastname")); person.setaddrline1(request.getparameter("addrline1")); person.setaddrline2(request.getparameter("addrline2")); person.setcode(request.getparameter("code")); person.setphone(request.getparameter("phone")); person.set (request.getparameter(" ")); person.settitle(request.getparameter("title")); if (person.getdate().length() == 0) person.setuserid("" + create(person)); request.getrequestdispatcher("/employee.jsp").forward(request, response); else update(person); request.getrequestdispatcher("/start").forward(request, response); catch (Exception ex) person.seterror(ex.tostring()); request.getrequestdispatcher("/edit.jsp").forward(request, response); Zaczyna się od zainicjowania obiektu sesji danymi formularza. Kilka ustawionych metod może zgłosić wyjątek, jeśli wartość jest niedozwolona, a jeśli tak się stanie, serwer wykonuje powrót do edit.jsp z komunikatem o błędzie. Inicjując obiekt poprawnie, pole daty służy do sprawdzenia, czy jest to aktualizacja, czy do dodania nowego wiersza do bazy danych. Dzieje się tak przy użyciu dwóch metod, których nie pokazałem tutaj, ale różnica polega na tym, że jedna wykonuje SQL INSERT, a druga wykonuje aktualizację SQL. Jeśli te metody nie zostaną poprawnie wykonane, zgłoszą wyjątek, który zostanie odesłany do edit.jsp jako komunikat o błędzie. Jeśli z drugiej strony baza danych jest poprawnie zaktualizowana, w przypadku aktualizacji odsyłamy z powrotem na stronę główną, ale jeśli jest to nowy pracownik, zostaniesz wysłany na stronę pracownik.jsp, który pokazuje, który pracownik przydzielony numer. Jeśli klikniesz środkowy link na stronie początkowej, uzyskasz przegląd wszystkich

87 pracowników w bazie danych. Rezultatem może być na przykład, jak pokazano poniżej, utworzenie dwóch pracowników: Wygląd i styl stołu zależy od arkusza stylów, w którym trzy ostatnie klasy są używane do stylizacji stołu. Zawartość strony JSP jest następująca: <%@page contenttype="text/html" pageencoding="utf-8"%> <%@page errorpage="error.jsp" %> <!DOCTYPE html> <%@taglib prefix="c" uri=" %> <html> <head> <meta http-equiv="content-type" content="text/html; charset=utf-8"> <title>jsp Page</title> <link rel="stylesheet" href="styles.css" type="text/css"/> </head> <body> <jsp:usebean id="personsbean" class="changeaddress.beans.personsbean" scope="page"/> <jsp:include page="header.jsp"/> <h2>employee list</h2> <table class="imagetable"> <tr> <th>employee</th> <th>name</th> <th>address</th>

88 <th></th> <th>post address</th> <th>phone</th> <th> </th> <th>title</th> <th>last modified</th> </tr> <c:foreach items="$personsbean.persons " var="pers"> <tr> <td>$pers.userid</td> <td>$pers.firstname $pers.lastname</td> <td>$pers.addrline1</td> <td>$pers.addrline2</td> <td>$pers.code $pers.city</td> <td>$pers.phone</td> <td>$pers. </td> <td>$pers.title</td> <td>$pers.date</td> </tr> </c:foreach> </table> <p><a href="start">back to start</a></p> </body> </html> Strona używa komponentu Java Bean o nazwie PersonsBean. Nie chcę tutaj wyświetlać kodu, ale tworzy on List <PersonBean>, który jest inicjowany ze wszystkimi pracownikami w bazie danych. Najważniejsze w tym miejscu jest zwrócenie uwagi na to, jak ta lista służy do dynamicznego tworzenia tabeli z wierszem dla każdego pracownika. W tym miejscu należy szczególnie zwrócić uwagę na składnię dotyczącą sposobu wstawiania pętli za pomocą elementu c: foreach na stronie JSP. Istnieje jeszcze inny link na stronie początkowej, na którym członek ma możliwość zmiany swojego hasła. Nie chcę tego tutaj pokazywać, ponieważ nie dodaje nic nowego. Jest to formularz, w którym użytkownik musi wprowadzić swój numer pracownika, hasło i nowe hasła, a strona używa serwletu do weryfikacji tych danych i ewentualnie aktualizacji bazy danych. Ta aplikacja internetowa jest prosta i jest w wielu miejscach uproszczona do praktycznej aplikacji, i oczywiście może być więcej funkcji, takich jak wyszukiwanie pracowników, ale jest to typowa aplikacja internetowa, w której użytkownicy mogą

89 edytować dane, które są przechowywane w bazie danych. W praktyce wiele aplikacji internetowych to aplikacje bazodanowe, na przykład myślące o klasycznym koszyku. Jednak zanim całkowicie opuszczę aplikację, istnieje jedna wyjątkowa cecha. Jak wspomniano, używam klasy DB do utworzenia połączenia z bazą danych. Wymaga przynajmniej użytkownika bazy danych w postaci nazwy użytkownika i hasła. Te informacje są często zapisywane w pliku konfiguracyjnym i użyłem pliku web.xml: <?xml version="1.0" encoding="utf-8"?> <web-app version="3.1" xmlns=" > <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> <listener> <listener-class>changeaddress.paramsfactory</listener-class> </listener> <context-param> <param-name>usr</param-name> <param-value>pa</param-value> </context-param> <context-param> <param-name>pwd</param-name> <param-value>volmer_1234</param-value> </context-param> </web-app> Ogólnie uważa się, że jest to bezpieczne miejsce, ponieważ nie jest wysyłane do klienta, a ponieważ kontener WWW nie pozwala na dostęp do pliku z zewnątrz. Oznacza to jednak, że klasa Java powinna być w stanie pobrać te parametry i można to zrobić za pomocą klasy nasłuchiwania, która pobiera informacje podczas uruchamiania aplikacji. Zauważ, że web.xml definiuje ten detektor jako klasę ParamsFactory, a serwer utworzy instancję obiektu tej klasy, który tworzy obiekt właściwości z parametrami kontekstu jako parę klucz / wartość. Ten przedmiot jest reprezentowany przez klasę package changeaddress; import java.util.*; public abstract class WebParams private static Properties contextproperties = new Properties();

90 public static String getparam(string key) return contextproperties.getproperty(key); public static void setproperties(properties properties) contextproperties = properties; mają tylko elementy statyczne. Obiekt Properties jest tworzony w ParamsFactory (obiekt nasłuchujący): package changeaddress; import java.util.*; import javax.servlet.*; public class ParamsFactory implements ServletContextListener public void contextdestroyed(servletcontextevent event) public void contextinitialized(servletcontextevent event) Properties properties = new Properties(); ServletContext servletcontext = event.getservletcontext(); Enumeration<?> keys = servletcontext.getinitparameternames(); while (keys.hasmoreelements()) String key = (String) keys.nextelement(); String value = servletcontext.getinitparameter(key); properties.setproperty(key, value);

91 WebParams.setProperties(properties); Ta metoda jest automatycznie wykonywana przez serwer Glassfish, a zatem następująca klasa może połączyć się z bazą danych: package changeaddress; import java.sql.*; public class DB public static Connection getconnection() throws SQLException String usr = WebParams.getParam("usr"); String pwd = WebParams.getParam("pwd"); return DriverManager.getConnection( "jdbc:mysql://localhost:3306/padata?usessl=false", usr, pwd); ĆWICZENIE 4 Zacznij od utworzenia kopii aplikacji internetowej ChangeAddress2. Musisz rozwinąć aplikację, aby dodać przycisk Usuń do strony edycji:

92 Przycisk powinien być dostępny tylko w przypadku edycji istniejącego pracownika. Po kliknięciu przycisku pracownik musi zostać usunięty z bazy danych. Najłatwiej jest pozwolić, aby przycisk wysłał wiadomość do nowego serwletu, który następnie usuwa pracownika. 6. JSF Cała idea JSP polega na oddzieleniu części prezentacji od logiki biznesowej aplikacji, tak aby poszczególne strony aplikacji internetowej były zapisywane jako strony JSP, które następnie przetwarzają swoje dane, wysyłając żądania do serwletów i, jak wspomniano, strona JSP samo jest przetłumaczone na serwlet. Dane, którymi ma manipulować strona JSP, są reprezentowane przez komponent bean Java, który jest klasą Java, której właściwości można natychmiast połączyć z polami strony JSP. Dzięki temu modelowi możesz tworzyć skuteczne dynamiczne strony internetowe. Od tego czasu technologia została udoskonalona, a dziś mówimy o JSF, który oznacza Java Server Faces, a celem było ułatwienie opracowania nowoczesnych aplikacji internetowych i ułatwienie korzystania z wielu nowych technologii internetowych. Strona JSF zastępuje strony JSP, a strona JSF jest połączona ze specjalnym serwletem, który nazywa się FacesServlet. Można również powiedzieć, że JSF to niewiele więcej niż naturalny rozwój technologii napędzany przez wiele nowych wymagań, które stale pojawiają

93 się w rozwoju skutecznych aplikacji internetowych. Zacznę od pokazania, w jaki sposób można napisać aplikację internetową z JSF za pomocą NetBeans. Aplikacja jest w zasadzie taka sama, jak pokazałem wcześniej, gdzie użytkownik musi wprowadzić dwie liczby, po których program może wykonać Obliczenia są jednym z czterech typów obliczeń i są dwa przyciski, jeden wyczyści pola (dwa pola wprowadzania i wynik), a drugi wykonuje obliczenia. Projekt nazywa się CalculationPage i jest tworzony w NetBeans jako inne aplikacje internetowe, ale w oknie Ustawienia serwera klikam przycisk Dalej, a następnie przechodzę do okna wyboru ram. Tutaj musisz zaznaczyć pole JavaServer Faces (patrz poniżej). Reszta musi pozostać bez zmian, a po kliknięciu przycisku Zakończ została utworzona aplikacja internetowa JSF, która składa się z jednego pliku o nazwie index.xhtml:

94 <?xml version='1.0' encoding='utf-8'?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" " <html xmlns=" xmlns:h=" <h:head> <title>facelet Title</title> </h:head> <h:body> Hello from Facelets </h:body> </html> Jak widać, jest to dokument XML ze składnią HTML, a tak naprawdę jest to kompletna aplikacja internetowa, którą można przetłumaczyć i otworzyć w przeglądarce. Zadaniem jest oczywiście zmodyfikowanie tej strony, aby wyświetlała okno, jak pokazano powyżej. Dane na stronie JSP są reprezentowane przez komponent bean Java, a na każdej stronie JSP zwykle będzie komponent bean Java. To samo dotyczy stron JSF, ale zamiast tego mówisz o nazwanej fasoli (dokładnie CDI o nazwie fasola) lub kontrolerze, ale w zasadzie jest to zwykła fasola Java z dwiema adnotacjami przed klasą. Aby skojarzyć taką nazwaną fasolę z projektem, dodałem pakiet obliczania strony. Fasoli, jak poprzednio. Następnie kliknąłem prawym przyciskiem myszy i wybrałem JSF Managed Bean (patrz poniżej). Po kliknięciu OK pojawia się okno do utworzenia pożądanej klasy (patrz poniżej). Nazywa się CalulationController i należy pamiętać, że wybrany został powyższy pakiet. Zwróć również uwagę na pole Nazwa, które jest nazwą, którą klasa jest znana na stronie JSF. Domyślnie NetBeans wybiera nazwę

95 klasy zaczynającą się od małej litery, i rzadko istnieje powód, aby ją zmieniać. Na koniec zwróć uwagę na pole Zakres, w którym mam sesję wyboru. Po kliknięciu OK NetBeans utworzy nazwany bean:

96 package calculationpage.beans; import javax.inject.named; import javax.enterprise.context.sessionscoped; import = public class CalculationController implements Serializable public CalculationController() Zasadniczo jest to zwykły szkielet dla klasy, ale należy zauważyć, że klasę można przekształcić do postaci szeregowej, podobnie jak inne komponenty Java i oczywiście dwie adnotacje. W tym miejscu należy zauważyć, że wartościami są wartości wybrane na poprzednim ekranie. Po dołączeniu nazwanej fasoli do projektu, kod musi zostać napisany i zostanie wykonany w taki sam sposób, jak inne fasole. Rezultat jest następujący, w którym nie pokazałem kodu dla metod get i set (wszystkie są = public class CalculationController implements Serializable private static final String ADDITION = "Addition"; private static final String SUBTRACTION = "Subtraction"; private static final String MULTIPLICATION = "Multiplication"; private static final String DIVISION = "Division"; private long number1; private long number2; private long result; private String calculation; private List<SelectItem> calculations; public CalculationController()

97 clear(); calculations = new ArrayList(); calculations.add(new SelectItem(ADDITION)); calculations.add(new SelectItem(SUBTRACTION)); calculations.add(new SelectItem(MULTIPLICATION)); calculations.add(new SelectItem(DIVISION)); public void clear() number1 = 0; number2 = 0; result = 0; calculation = null; public void calculate() if (calculation.equals(addition)) setresult(number1 + number2); else if (calculation.equals(subtraction)) setresult(number1 number2); else if (calculation.equals(multiplication)) setresult(number1 * number2); else if (calculation.equals(division)) try setresult(number1 / number2); catch (Exception ex) FacesMessage facesmsg = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Invalid Calculation", "Invalid Calculation"); FacesContext.getCurrentInstance().addMessage(null, facesmsg);

98 Klasa ma cztery proste właściwości, których znaczenie powinno być oczywiste (ta ostatnia służy do wykonania operacji obliczeniowej), a także istnieje lista obiektów o typie SelectionItem, która reprezentuje elementy, które strona JSF może wyświetlić w menu rozwijanym lista. Oprócz właściwości klasa ma dwie metody: pierwsza ustawia wszystkie właściwości na 0, a ostatnia wykonuje obliczenia. Ponieważ nie można podzielić przez 0, operacja PODZIAŁ może wywołać wyjątek. Jeśli tak się stanie, zostanie utworzony obiekt FacesMessage reprezentujący komunikat o błędzie. Pokazuję poniżej, w jaki sposób jest używany. Następnie jest strona JSF, a oto najważniejsze: <?xml version='1.0' encoding='utf-8'?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" " <html xmlns=" xmlns:f=" xmlns:h=" <h:head> <title>calculation page</title> </h:head> <h:body> <f:view> <h1>perform a Calculation</h1> <p>enter two integers</p> <h:messages errorstyle="color: red" infostyle="color: green" globalonly="true"/> <br/> <h:form id="calulationform"> Enter number 1: <h:inputtext id="number1" value="#calculationcontroller.number1"/> <br/> Enter number 2: <h:inputtext id="number2" value="#calculationcontroller.number2"/> <br/> <br/> Select calculation: <h:selectonemenu id="calculation" value="#calculationcontroller.calculation"> <f:selectitems value="#calculationcontroller.calculations"/> </h:selectonemenu>

99 <br/> <br/> Result: <h:outputtext id="result" value="#calculationcontroller.result"/> <br/> <br/> <h:commandbutton action="#calculationcontroller.clear()" value="clear"/> <h:commandbutton action="#calculationcontroller.calculate()" value="calculate"/> </h:form> </f:view> </h:body> </html> Kiedy zobaczysz kod, łatwo go zrozumieć i natychmiast zauważysz, że jest to dokument XML i że znaczna część kodu jest podobna do HTML. Jednak używanych jest wiele nowych elementów, które nie są standardowymi elementami HTML, ale elementami zdefiniowanymi w dwóch bibliotekach znaczników i zwykle nazywanymi elementami JSF: xmlns: f = " xmlns: h = " Taki element definiuje różne atrybuty, które można zainicjować, a element jest tłumaczony na standardowy HTML. Na przykład istnieje element <h: messages errorstyle = "color: red" infostyle = "color: green" globalonly = "true" /> co na ogół nie powoduje żadnego kodu, ale jeśli w obliczeniach wystąpi błąd (dzielenie z 0), do dokumentu dodaje się następujący tekst: <ul> <li style = "color: red"> Niepoprawne obliczenie </li> </ul> Należy pamiętać, że te nowe elementy nie oznaczają, że nie można używać standardowego kodu HTML. Jest to możliwe w taki sam sposób jak poprzednio. Chodzi tylko o to, że nowe elementy dają nowe możliwości i możliwości łatwiejszego generowania pożądanego kodu HTML niż pisanie go od zera. Zwróć uwagę na przykład, jak zdefiniowana jest lista rozwijana: <h:selectonemenu id="calculation" value="#calculationcontroller.calculation"> <f:selectitems value="#calculationcontroller.calculations"/> </h:selectonemenu> Zwróć uwagę w szczególności na to, jak odwoływać się do właściwości komponentu bean, i zasadniczo odbywa się to w taki sam sposób, jak na stronie JSP, wystarczy użyć znaku # zamiast $. Patrząc na powyższą definicję, powstaje następujący kod HTML: <select id="calulationform:calculation" name="calulationform:calculation" size="1"> <option value="addition" selected="selected">addition</option> <option value="subtraction">subtraction</option>

100 <option value="multiplication">multiplication</option> <option value="division">division</option> </select> Strona definiuje również element formularza, ale nie zdefiniowano żadnej akcji. To działanie jest zamiast tego powiązane z definicją przycisku, na przykład: <h:commandbutton action="#calculationcontroller.clear()" value="clear"/> Poniżej znajduje się przykład kodu HTML generowanego przez tę stronę JSF: <?xml version='1.0' encoding='utf-8'?> <!DOCTYPE html> <html xmlns=" <head id="j_idt2"> <title>calculation page</title> </head> <body> <h1>perform a Calculation</h1> <p>enter two integers</p> <br /> <form id="calulationform" name="calulationform" method="post" action="/calculationpage/faces/index.xhtml" enctype="application/x-www-form-urlencoded"> <input type="hidden" name="calulationform" value="calulationform" /> Enter number 1: <input id="calulationform:number1" type="text" name="calulationform:number1" value="0" /> <br /> Enter number 2: <input id="calulationform:number2" type="text" name="calulationform:number2" value="0" /> <br /> <br /> Select calculation: <select id="calulationform:calculation" name="calulationform:calculation" size="1"> <option value="addition">addition</option> <option value="subtraction">subtraction</option> <option value="multiplication">multiplication</option>

101 <option value="division">division</option> </select> <br /> <br /> Result: <span id="calulationform:result">0</span> <br /> <br /><input type="submit" name="calulationform:j_idt14" value="clear" /> <input type="submit" name="calulationform:j_idt16" value="calculate" /> <input type="hidden" name="javax.faces.viewstate" id="j_id1:javax.faces.viewstate:0" value=" : " autocomplete="off" /> </form> </body> </html> Większość można rozpoznać. Istnieje jednak kilka ukrytych pól, których wartość jest trudna do interpretacji, ale tutaj musisz pamiętać, jak powstaje dokument HTML: Strona JSF jest tłumaczona na serwlet, a ten serwlet wysyła powyższy dokument HTML w odpowiedzi. Podsumowując, aplikacja JSF składa się z wielu stron XHTML, które zawierają głównie elementy JSF, a także co najmniej jedną nazwaną fasolę i opcjonalnie plik konfiguracyjny o nazwie faces-config.xml. Jak pokażą poniższe przykłady, mogą istnieć również inne klasy Java, które zazwyczaj reprezentują klasy modeli. W ramach projektu NetBeans dodał plik konfiguracyjny web.xml: <?xml version="1.0" encoding="utf-8"?> <web-app version="3.1" xmlns=" xmlns:xsi=" xsi:schemalocation=" <context-param> <param-name>javax.faces.project_stage</param-name> <param-value>development</param-value> </context-param> <servlet> <servlet-name>faces Servlet</servlet-name> <servlet-class>javax.faces.webapp.facesservlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet>

102 <servlet-mapping> <servlet-name>faces Servlet</servlet-name> <url-pattern>/faces/*</url-pattern> </servlet-mapping> <session-config> <session-timeout> 30 </session-timeout> </session-config> <welcome-file-list> <welcome-file>faces/index.xhtml</welcome-file> </welcome-file-list> </web-app> Nie ma wiele do zapamiętania i rzadko jest utrzymywany ten plik, ale początkowo wstawiono element kontekstu-parametru, który definiuje wartość parametru o wartości Rozwój, co oznacza dodanie pewnych informacji debugowania do projektu. Nie jest on zainteresowany ukończoną aplikacją, a wartość można następnie zmienić na Produkcja. Zauważ również, że web.xml definiuje stronę początkową. 6.1 ZMIANA ADRESU 3 Chcę pokazać, jak napisać aplikację JSF, podobną do ChangeAddress1. Zaczynam od nowego projektu aplikacji sieci Web, który nazwałam ChangeAddress3, a kiedy podszedłem do okna, aby wybrać strukturę, wybrałem twarze JavaServer i zakres sesji jak wyżej. Rezultatem jest ponownie strona JSF o nazwie index.xhtml, która jest stroną główną aplikacji. Jeśli otworzysz aplikację, pojawi się następujące okno. Jeśli wpiszesz datę i klikniesz przycisk Wyślij, wynikiem będzie okno poniżej. Powodem jest to, że program sprawdza poprawność zawartości pól, a gdy wartość jest wprowadzana dla daty, dzieje się tak, ponieważ pole to jest sprawdzane inaczej niż inne pola. Jeśli obok pól Adres i Tytuł stanowiska nie ma komunikatu o błędzie, dzieje się tak dlatego, że pierwszy musi być pusty, a ostatni w ogóle nie jest sprawdzany.

103 Po wprowadzeniu prawidłowego adresu jest on zapisywany na liście, a pola są puste, aby można było wprowadzić inny adres. Jeśli klikniesz dolny link, pojawi się prośba o stronę zawierającą przegląd wprowadzonych adresów. Wynik może być na przykład:

104 Następnie do kodu. W ramach pakietów źródłowych utworzono trzy pakiety: 1. changeaddress.beans, który zawiera fasolę aplikacji, i tylko jedna jest nazwaną fasolą 2. changeaddress.models, który zawiera inną klasę Java, i tylko jedna reprezentuje adres 3. changeaddress.validators, który zawiera klasy do sprawdzania poprawności pól interfejsu użytkownika i są dwa Chcę zacząć od klasy, która reprezentuje adres. Klasa nazywa się Osoba i jest zwykłą klasą modelową, w rzeczywistości jest to komponent Java bean: package changeaddress.models; public class Person implements java.io.serializable private String firstname; private String lastname; private String address; private String code; private String city; private String ; private String title; private String date; public Person() public Person(String fi String lastname, String address, String code, String city, String , String title, String date)

105 public boolean islegal() return firstname!= null && firstname.length() > 0 && lastname!= null && lastname.length() > 0 && date!= null && date.length() > 0; Nie ma wiele do wyjaśnienia, a ja nie pokazałem metod klasy get i set, ponieważ wszystkie są trywialne. Należy zwrócić uwagę na ostatnią metodę, która stwierdza, że obiekt Person jest legalny, jeśli obiekt ma imię, nazwisko i datę. Celem tej klasy jest przede wszystkim pokazanie, że aplikacja internetowa może korzystać z klas modelowych w taki sam sposób, jak inne aplikacje Java, a tutaj szczególnie tam, gdzie klasa jest używana ze stron JSF. W następnym przykładzie pokażę klasę Validator, która w tym przypadku służy do sprawdzania poprawności pola wejściowego, a tutaj wartością pola musi być prawna data: package ="datevalidator") public class DateValidator implements public void validate(facescontext facescontext, UIComponent uicomponent, Object value) throws ValidatorException HtmlInputText htmlinputtext = (HtmlInputText) uicomponent; String label = htmlinputtext.getlabel() == null htmlinputtext.getlabel().trim().equals("")? htmlinputtext.getid() : htmlinputtext.getlabel(); if (!isdate((string)value)) FacesMessage facesmessage =

106 new FacesMessage(label + ": Illegal value for date"); throw new ValidatorException(facesMessage); private boolean isdate(string text). Po pierwsze, zauważ, że klasa jest ozdobiona adnotacją informującą, że jest to klasa Validatora. Zauważ też, że klasa implementuje interfejs Validator, który definiuje pojedynczą metodę validate (), która jest metodą, która sprawdza wartość pola, która jest wartością parametru. uicomponent to komponent, którego wartość musi zostać zweryfikowana, a metoda rozpoczyna się od ustalenia wartości atrybutu dla tego komponentu (jego ID lub etykiety). Następnie wartość jest testowana przy użyciu prywatnej metody pomocniczej o nazwie isdate (). Nie pokazałem kodu, ponieważ zawiera on tylko to, co pokazałem w innych książkach. Jeśli wartości nie można zweryfikować poprawnie, tworzony jest obiekt FacesMessage i wyjątek stanowi ten parametr jako parametr. W rezultacie komunikat błędu pojawia się w oknie. Istnieje odpowiednia klasa Validator, o nazwie Validator. Jest w zasadzie identyczny z powyższym i nie chcę tutaj pokazywać kodu. Wreszcie aplikacja ma nazwaną fasolę. Klasa jest prosta i składa się głównie z get i ustawiam metody, w których pokazałem tylko kilka przykładów: package = public class IndexController implements Serializable private Person person = new Person(); private List<Person> persons = new ArrayList(); public IndexController()

107 public String getfirstname() return person.getfirstname(); public void setfirstname(string firstname) person.setfirstname(firstname);. public List<Person> getpersons() return persons; public void add() if (person.islegal()) persons.add(person); person = new Person(); Istnieje odpowiednia klasa Validator, o nazwie Validator. Jest w zasadzie identyczny z powyższym i nie chcę tutaj pokazywać kodu. Wreszcie aplikacja ma nazwaną fasolę. Klasa jest prosta i składa się głównie z metod get i set, w których pokazałem tylko kilka przykładów: package changeaddress.beans;

108 = public class IndexController implements Serializable private Person person = new Person(); private List<Person> persons = new ArrayList(); public IndexController() public String getfirstname() return person.getfirstname(); public void setfirstname(string firstname) person.setfirstname(firstname);. public List<Person> getpersons() return persons; public void add()

109 if (person.islegal()) persons.add(person); person = new Person(); Widziana z index.xhtml jest najważniejszą metodą add () jako metodą wykonywaną po kliknięciu przycisku Send. Sprawdza, czy dana osoba jest legalna, a jeśli tak, metoda dodaje obiekt Person do listy, po czym tworzony jest nowy obiekt Person. Wybrałem, aby ten komponent bean miał zakres sesji i dostępne są następujące opcje: 1. Żądanie oznacza, że komponent bean istnieje tylko dla bieżącego żądania HTTP. Oznacza to, że należy go utworzyć dla każdego żądania. 2. Sesja, co oznacza, że obiekt komponentu bean istnieje w sesji HTTP pojedynczego użytkownika. 3. Rozmowa, co oznacza, że komponent bean istnieje w wielu żądaniach HTTP. 4. Aplikacja, co oznacza, że ten sam komponent bean jest dostępny dla wszystkich użytkowników aplikacji w wielu sesjach użytkowników. 5. Zależny, co oznacza, że fasola jest tworzona za każdym razem, gdy jest taka potrzeba. Następnie index.xhtml, który jest typowym przykładem formularza: <?xml version='1.0' encoding='utf-8'?> <!DOCTYPE > <html xmlns=" xmlns:h=" xmlns:f=" <h:head> <meta http-equiv="content-type" content="text/html; charset=utf-8"/> <title>change address</title> <h:outputstylesheet library="css" name="styles.css"/> </h:head> <h:body> <h1>change address</h1> <h:form> <h:panelgrid columns="3" columnclasses="rightalign,leftalign,leftalign"> <h:outputlabel value="first name:" for="firstname"/>

110 <h:inputtext id="firstname" label="first name" required="true" style="width: 300px" value="#indexcontroller.firstname" /> <h:message for="firstname" class="error-message" /> <h:outputlabel value="last name:" for="lastname"/> <h:inputtext id="lastname" label="lastname" required="true" style="width: 200px" value="#indexcontroller.lastname" /> <h:message for="lastname" class="error-message" /> <h:outputlabel value="address:" for="address"/> <h:inputtext id="address" label="address" required="true" style="width: 300px" value="#indexcontroller.address" /> <h:message for="address" class="error-message" /> <h:outputlabel value="zip code:" for="code" /> <h:inputtext id="code" label="zipcode" style="width: 60px" required="false" value="#indexcontroller.code"> <f:validatelength minimum="4" maximum="4"/> </h:inputtext> <h:message for="code" class="error-message" /> <h:outputlabel value="city:" for="city"/> <h:inputtext id="city" label="city" required="true" style="width: 200px" value="#indexcontroller.city" /> <h:message for="city" class="error-message" /> <h:outputlabel value=" address:" for=" "/> <h:inputtext id=" " label=" address" required="false" style="width: 300px" value="#indexcontroller. "> <f:validator validatorid=" validator"/> </h:inputtext> <h:message for=" " class="error-message" /> <h:outputlabel value="change date:" for="date"/> <h:inputtext id="date" label="change date" required="true" style="width: 100px" value="#indexcontroller.date" immediate="true" onchange="submit()"> <f:validator validatorid="datevalidator"/> </h:inputtext> <h:message for="date" class="error-message" />

111 <h:outputlabel value="job titel: " for="title"/> <h:inputtext id="title" required="false" style="width: 300px" value="#indexcontroller.title" /> <h:panelgroup/> <h:commandbutton value="send" action="#indexcontroller.add()" /> </h:panelgrid> <a href="list.xhtml">show addresses</a> </h:form> </h:body> </html> Kiedy widzisz kod, jest on w większości łatwy do zrozumienia, ale jest kilka rzeczy, które powinieneś zauważyć. Aplikacja używa arkusza stylów, który znajduje się w katalogu zasoby / css Należy zwrócić uwagę, jak odnieść się do tego arkusza stylów w nagłówku. W przeciwnym razie formularz składa się głównie z pól ułożonych w h: panelgrid, który jest tłumaczony na tabelę HTML z wierszem dla każdego pola i gdzie są trzy kolumny. Pierwsza kolumna to tekst, druga pole wprowadzania, a trzecia możliwa wiadomość o błędzie. Pierwszy wiersz dotyczy imienia i jest zdefiniowany w następujący sposób: <h:outputlabel value="first name:" for="firstname"/> <h:inputtext id="firstname" label="first name" required="true" style="width: 300px" value="#indexcontroller.firstname" /> <h:message for="firstname" class="error-message" /> Pierwsza instrukcja definiuje tekst, a jednocześnie stwierdza się, że tekst z atrybutem dla jest dołączony do imienia pola wejściowego. Gdy to pole ma atrybut etykiety, dzieje się tak, ponieważ jest używane w połączeniu z komunikatem o błędzie. Zwróć również uwagę na to, jak wartość pola jest powiązana z właściwością w indexcontroller. Wreszcie ostatnia instrukcja dotyczy komunikatu o błędzie i należy zauważyć, że element z atrybutem for jest dołączony do pola wejściowego. Jeśli weźmiesz pod uwagę pole wejściowe, ma ono atrybut required="true co oznacza, że walidator jest dołączony do pola, co po prostu oznacza, że należy wprowadzić wartość imienia. Jeśli nie, pole komunikatu wyświetla komunikat o błędzie. Jest to przykład predefiniowanego walidatora i jest ich kilka. Na przykład, jeśli spojrzysz na pole z kodem pocztowym, ma ono również Walidator, który sprawdza wartość pola w celu uzyskania długości w przedziale. W rzeczywistości jest to bardzo przydatny walidator. Jeśli weźmiesz pod uwagę dotychczasowe pole wejściowe, użyje ono niestandardowego walidatora, który jest obiektem DateValidator: <h:inputtext id="date" label="change date" required="true" style="width: 100px" value="#indexcontroller.date" immediate="true" onchange="submit()">

112 <f:validator validatorid="datevalidator"/> </h:inputtext> Zasadniczo sprawdzanie poprawności odbywa się po kliknięciu przycisku przesyłania - i przed wykonaniem metody działania. Ważne jest, aby pamiętać, że sprawdzanie poprawności odbywa się po stronie serwera i że do serwera wysyłane jest żądanie. Jeśli nie można sprawdzić wszystkich pól, metoda akcji nie jest wykonywana, ale następuje powrót do index.xhmtl i wyświetlane są komunikaty o błędach. Należy zauważyć, że w tym przypadku pole wejściowe ma dwa nowe atrybuty: immediate="true" onchange="submit()" Oznacza to, że zawartość pola musi zostać zweryfikowana natychmiast po utracie ostrości pola, a zatem nie tylko podczas przesyłania formularza. Ta opcja nie jest używana tak często, jak ciągle występuje żądanie do serwera, ponieważ można to zrobić lepiej za pomocą ajax (patrz następna książka). Na koniec zwróć uwagę na pole wejściowe dla tytułu i że nie ma ono walidatora. Jak wspomniano, komponenty w tym przykładzie są umieszczane za pomocą panelugrid, który jest elementem JSF, który jest tłumaczony na tabelę HTML. Istnieje również element panelgroup służący do gromadzenia wielu elementów jako pojedynczej komórki w tabeli. Oto pusta grupa panelu, co oznacza po prostu, że występuje pusta komórka. Kliknięcie dolnego łącza spowoduje, jak wspomniano powyżej, wyświetlenie strony z przeglądem wprowadzonych adresów. Jest to także strona JSF (a zatem FaceLet) o nazwie list.xhmtl: <?xml version='1.0' encoding='utf-8'?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" > <html xmlns=" > <h:head> <meta http-equiv="content-type" content="text/html; charset=utf-8"/> <title>facelet Title</title> <h:outputstylesheet library="css" name="styles.css"/> </h:head> <h:body> <h:form> <h1>addresses</h1> <h:datatable id="addrtable" var="addr" border="1" value="#indexcontroller.persons" rendered="#indexcontroller.persons.size() > 0"> <f:facet name="header"> Entered addresses in this session </f:facet> <h:column id="namecol"> <f:facet name="header">name</f:facet>

113 <h:outputtext id="name" value="#addr.firstname #addr.lastname"/> </h:column> <h:column id="addrcol"> <f:facet name="header">address</f:facet> <h:outputtext id="addr" value="#addr.address"/> </h:column> <h:column id="citycol"> <f:facet name="header">city</f:facet> <h:outputtext id="city" value="#addr.code #addr.city"/> </h:column> <h:column id="jobcol"> <f:facet name="header">title</f:facet> <h:outputtext id="job" value="#addr.title"/> </h:column> <h:column id="mailcol"> <f:facet name="header">mail</f:facet> <h:outputtext id="mail" value="#addr. "/> </h:column> <h:column id="datecol"> <f:facet name="header">date</f:facet> <h:outputtext id="date" value="#addr.date"/> </h:column> </h:datatable> <p><a href="index.xhtml">back to start</a></p> </h:form> </h:body> </html> Kod jest przykładem, który dynamicznie buduje tabelę. Należy zwrócić uwagę na składnię i fakt, że strona używa tej samej nazwanej fasoli (tego samego kontrolera) co index.xhmtl. W szczególności powinieneś zauważyć, jak iterować wszystkie obiekty osób na liście obiektów bean. Następnie aplikacja jest kompletna, ale jest jeszcze jeden zaległy. Aplikacja może wyświetlać znaki narodowe niepoprawnie. Problem polega na tym, że Glassfish może używać nieprawidłowego domyślnego

114 kodowania. Jeśli klikniesz prawym przyciskiem myszy WEB-INF i wybierzesz nowy, możesz dodać deskryptor do serwera: Plik nazywa się glassfish-web.xml, a zawartość musi być: <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE glassfish-web-app PUBLIC "-//GlassFish.org//DTD GlassFish Application Server 3.1 Servlet 3.0//EN" " <glassfish-web-app error-url=""> <class-loader delegate="true"/> <jsp-config> <property name="keepgenerated" value="true"> <description> </description> </property> </jsp-config> <parameter-encoding default-charset="utf-8" /> </glassfish-web-app> dzie dodałem niebieską linię. Następnie aplikacja jest zakończona.

115 6.2 NAWIGACJA NA STRONACH Typowa aplikacja internetowa składa się z wielu stron (lub widoków) i działa, gdy użytkownik często nawiguje między różnymi stronami, wykonując akcję za pomocą elementu h: commandbutton lub h: commandlink. W obu przypadkach oznacza to wywołanie nazwanej fasoli. W przypadku dużych aplikacji kontrola może być skomplikowana, zwłaszcza że nawigacja po stronie może zależeć od określonego warunku. Z tych powodów wprowadzono specjalny plik deskryptora, który określa sposób nawigacji. Przykład ViewNavigation ma następujący index.xhtml: gdzie są trzy przyciski, z których każdy ma typ h: commandbutton i ma akcję. Kliknięcie pierwszego przycisku powoduje wyświetlenie następującego okna, które jest innym widokiem (o nazwie info.xhtml): i kliknięcie tutaj przycisku powoduje powrót do index.xhtml. Po kliknięciu środkowego przycisku na ekranie startowym pojawi się następujące okno:

116 o nazwie login.xhtml i kliknięciu przycisku pojawia się okno data.xhtml: Kliknięcie tego przycisku spowoduje powrót do strony początkowej (index.xhtml). Jeśli ponownie klikniesz środkowy przycisk, przejdziesz bezpośrednio do data.xhtml bez konieczności przechodzenia do login.xhtml. Ostatni przycisk na stronie startowej służy do wylogowania, a jeśli klikniesz go, a następnie środkowy przycisk, ponownie będziesz musiał przejść do login.xhtml. Aby to kontrolować, używa się nazwanego komponentu bean, o nazwie NavigationController: package viewnavigation.beans; import javax.inject.named; import javax.enterprise.context.sessionscoped; import = public class NavigationController implements Serializable private boolean loggedin = false;

117 public NavigationController() public String tostart() return "START"; public String toinfo() return "INFO"; public String nextpage() if (loggedin) return "data"; else return "login"; public String login() loggedin = true; return "LOGIN"; public void logout() loggedin = false;

118 Definiuje metody zwracające ciąg znaków i można je wywoływać jako akcję. Klasa ma zmienną symulowaną, jeśli użytkownik jest zalogowany. Istnieją dwa rodzaje nawigacji. Pierwsza nazywa się nawigacją jawną, w której metoda akcji odwołuje się do ciągu (klucza), który odnosi się do pliku konfiguracyjnego face-config.xml, który następnie wskazuje, który widok powinien zostać wyświetlony. Drugi nazywany jest niejawną nawigacją, w której metoda akcji zwraca nazwę bieżącego widoku (ale bez rozszerzenia). Na przykład, jeśli weźmiesz pod uwagę metody tostart () i toinfo (), zwracają one ciąg znaków użyty w Faces-config.xml i są przykładami jawnej nawigacji. Jako kolejny przykład metoda nextpage () jest przykładem niejawnej nawigacji, ponieważ po prostu zwraca nazwę widoku (zależnie od warunku). Zwróć także uwagę na dwie ostatnie metody, z których pierwsza jest również używana jako metoda akcji do jawnej nawigacji, ale najpierw modyfikuje zmienną loggedin, aby symulować, że użytkownik jest zalogowany. Ostatnia jest w rzeczywistości metodą akcji, ale nie zwraca cokolwiek, co oznacza, że nie ma możliwości przejścia do innego widoku. Następnie jest plik konfiguracyjny (dodany do WEB-INF): <?xml version='1.0' encoding='utf-8'?> <faces-config version="2.2" > <navigation-rule> <from-view-id>/index.xhtml</from-view-id> <navigation-case> <from-outcome>info</from-outcome> <to-view-id>/info.xhtml</to-view-id> </navigation-case> </navigation-rule> <navigation-rule> <from-view-id>/info.xhtml</from-view-id> <navigation-case> <from-outcome>start</from-outcome> <to-view-id>/index.xhtml</to-view-id> </navigation-case> </navigation-rule> <navigation-rule> <from-view-id>/login.xhtml</from-view-id> <navigation-case> <from-outcome>login</from-outcome> <to-view-id>/data.xhtml</to-view-id> </navigation-case>

119 </navigation-rule> </faces-config> W takim przypadku zdefiniowane są trzy reguły nawigacji. Pierwszy interpretowany jest w następujący sposób. Jeśli pochodzisz z (akcja miała miejsce) index.xhtml, istnieje jeden przypadek nawigacji, który mówi, że jeśli wartością (kluczem) jest INFO, musisz przejść do strony info.xhtml. Należy zauważyć, że reguła nawigacji może zawierać więcej (wielu) pozycji z przypadkami nawigacji. Korzystając z pliku Faces-config.xml, możesz całkowicie kontrolować sposób nawigacji między poszczególnymi widokami w aplikacji internetowej, ale może to oznaczać bardzo duży plik, w którym musisz dużo pisać. Dlatego wprowadzono pojęcie niejawnej nawigacji, która nie korzysta z pliku konfiguracyjnego. Poniżej znajduje się kod index.xhtml: <?xml version='1.0' encoding='utf-8'?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" > <html xmlns=" xmlns:h=" <h:head> <title>facelet Title</title> </h:head> <h:body> <h:form id="form"> <h1>hello World</h1> <h2>demonstrates page navigation</h2> <br/> <h:commandbutton style="width: 150px" action="#navigationcontroller.toinfo" value="go To Information"/> <h:commandbutton style="width: 150px" action="#navigationcontroller.nextpage" value="goto data page"/> <h:commandbutton style="width: 150px" action="#navigationcontroller.logout" value="logout"/> </h:form> </h:body> </html> Nie ma wiele do wyjaśnienia, ale należy pamiętać, że widok ma trzy polecenia. Pierwszy zawsze przekierowuje do info.xhtml (poprzez jawną nawigację). Drugi przekaże do login.xhtml lub data.xhtml za pomocą niejawnej nawigacji. Wreszcie ostatni nie dokona przekazania, ponieważ metoda logout () nie zwraca wartości. Na koniec chcę pokazać data.xhtml: <?xml version='1.0' encoding='utf-8'?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" >

120 <html xmlns=" xmlns:h=" <h:head> <title>facelet Title</title> </h:head> <h:body> <h:form> <h1>the data</h1> <ul> <li>gorm den Gamle</li> <li>harald Blåtand</li> <li>svend Tverskæg</li> </ul> <br/> <h:commandbutton action="index" value="go to start"/> </h:form> </h:body> </html> W tym miejscu należy zauważyć, że używana jest niejawna nawigacja, ale zamiast wywoływania metody nazwa widoku jest wyświetlana bezpośrednio jako argument atrybutu akcji. PROBLEM 2 W tym zadaniu musisz napisać aplikację internetową dla prostej księgi gości, takiej jak ćwiczenie 2. Program powinien zasadniczo otworzyć ten sam formularz, ale w przeciwieństwie do ćwiczenia 2 dane muszą być przechowywane w bazie danych. Zacznij od utworzenia bazy danych o nazwie księga gości. Baza danych powinna mieć tylko jedną tabelę, którą można utworzyć za pomocą następującego skryptu: use guestbook; drop table if exists guests; create table guests ( id int auto_increment primary key, name varchar(100) not null, addr varchar(100) not null, code char(4) not null, mail varchar(100), text text not null, date date );

121 gdzie data jest automatycznie przypisywana podczas pisania w księdze gości. Wymagane jest, aby program został napisany przy użyciu JavaServer Faces. Oprócz formularza do pisania w księdze gości, musi istnieć strona JSF, do której prowadzi strona główna, która pokazuje zawartość księgi gości. 6.3 SZABLONY Jak wspomniano, aplikacja internetowa będzie polegać w praktyce na wielu stronach lub widokach i zazwyczaj są one do siebie podobne i mają wspólny wygląd. Ponadto można używać szablonów, a następująca aplikacja pokazuje, w jaki sposób. W szczególności pokażę krok po kroku rozwój aplikacji, w tym sposób korzystania z szablonów. Przykład pokazuje również wiele innych szczegółów dotyczących tworzenia aplikacji internetowych, a zwłaszcza możliwość korzystania ze składników kompozytowych, które są kodem, który można wykorzystać w wielu widokach. Ponadto przykład pokazuje, jak stosować obrazy. Aplikacja nazywa się PaWeb i zilustruje bardzo prostą osobistą stronę internetową, na której osoba (i tutaj autor) chce udostępnić prywatne informacje za pośrednictwem publicznej strony internetowej. Aplikacja jest tworzona tak jak wszystkie inne aplikacje internetowe w tym rozdziale i tworzony jest FaceLet o nazwie index.xhtml, który służy jako program uruchamiający aplikacje. Zauważ, że po utworzeniu aplikacji, oprócz pliku index.xhtml, utworzono również deskryptor web.xml, który w zasadzie stwierdza, że jest to aplikacja JSF. Zredagowałem plik index.xhtml, więc gotowy kod jest następujący, który pokazuje tylko stronę powitalną: <?xml version='1.0' encoding='utf-8'?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional// EN" > <html xmlns=" xmlns:h=" <h:head> <title>facelet Title</title> </h:head> <h:body style="color: darkblue; background: bisque"> <h:form> <div style="font-size: 144pt; font-weight: bold; text-align: center"> Welcome</div> <div style="font-size: 72pt; text-align: center">to my website</div> <div style="font-size: 36pt; text-align: center"> The site about big and small in my everyday life</div> <p style="text-align: center"><h:commandlink value="it sounds interesting so read on here" action="gallery"/></p> <p style="text-align: center">poul Klausen</p> </h:form> </h:body> </html> Nie ma wiele nowego do wyjaśnienia, ale należy pamiętać, że kod jest mieszanką typowych elementów HTML i elementów JSF formularza

122 <h:code >.</h:code> Elementy JSF to kod serwera, a zatem elementy są tłumaczone przez serwer na HTML i wysyłane jako część odpowiedzi serwera. Istnieje wiele takich elementów JSF i nie ma nic złego w mieszaniu elementów JSF i elementów HTML. Zauważ również, że powyższy widok JSF używa stylów. Style omówiono w następnej książce, ale gdy zobaczysz powyższy kod, łatwo jest zinterpretować znaczenie każdego stylu. Zauważ, że używając stylów możesz zdefiniować bardzo dużą czcionkę. Widok jest formularzem, ponieważ zawiera pojedynczy element formularza, który ma element CommandLink, który jest tłumaczony przez serwer na wspólny element łącza. Element ma akcję, która jest widokiem, który powinien zostać wyświetlony po kliknięciu łącza i nazywa się gallery.xhtml. Chociaż ten widok nie został utworzony, aplikację można łatwo przetłumaczyć i otworzyć w przeglądarce. Następnie pokażę, jak zdefiniować szablon, który definiuje ogólny projekt widoku. W NetBeans kliknij prawym przyciskiem myszy na Strony WWW i wybierz Szablon Nowy i Facelets: Po kliknięciu OK przejdziesz do następującego okna:

123 gdzie musisz wybrać nazwę i częściowo wybrać projekt. Wpisałem nazwę maintemplate i wybrałem projekt, który dzieli widok na cztery sekcje (górny, lewy, dolny i środkowy). Po kliknięciu przycisku Zakończ NetBeans tworzy stronę JSF: maintemplate.xhtml Ponadto tworzony jest katalog resources/css i w tym dwa arkusze stylów. Jak sama nazwa wskazuje, zasoby to katalog zasobów, takich jak arkusze stylów, ale mogą to być również kody skryptów lub obrazy. Jeśli przyjrzysz się maintemplate. xhtml, kod jest następujący: <?xml version='1.0' encoding='utf-8'?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional// EN" > <html xmlns=" xmlns:ui=" xmlns:h=" <h:head> <meta http-equiv="content-type" content="text/html; charset=utf-8" /> <h:outputstylesheet name="./css/default.css"/> <h:outputstylesheet name="./css/csslayout.css"/> <title>facelets Template</title> </h:head>

124 <h:body> <div id="top"> <ui:insert name="top">top</ui:insert> </div> <div> <div id="left"> <ui:insert name="left">left</ui:insert> </div> <div id="content" class="left_content"> <ui:insert name="content">content</ui:insert> </div> </div> <div id="bottom"> <ui:insert name="bottom">bottom</ui:insert> </div> </h:body> </html> Należy zauważyć, że sekcja jest zdefiniowana jako element interfejsu użytkownika: wstaw, w którym domyślnie wstawiany jest tekst i to ten tekst FaceLets korzystający z szablonu zastąpi własną treścią. W rzeczywistości jest to typowy widok JSF, który można otworzyć w przeglądarce, a jeśli tak, to wynik, jak pokazano poniżej. Nie ma to tak wielkiego znaczenia, a szablon nie ma być widokiem prawdziwym, ale projektem, który mogą zastosować inne widoki JSF. Jak widać, widok zawiera dwa komunikaty o błędach, a to dlatego, że należy zmienić dwie linie w nagłówku odnoszące się do dwóch arkuszy stylów: <h:head> <meta http-equiv="content-type" content="text/html; charset=utf-8" /> <h:outputstylesheet library="css" name="default.css"/> <h:outputstylesheet library="css" name="csslayout.css"/> <title>facelets Template</title> </h:head>

125 Jeśli następnie ponownie otworzysz stronę, wynikiem będzie: a to dlatego, że szablon korzysta teraz z dwóch arkuszy stylów i mogą być następnie używane przez wszystkie widoki, które używają tego szablonu. Nie chcę tutaj pokazywać dwóch arkuszy stylów, ale zachęcamy do zapoznania się z zawartością dwóch plików, a jeśli porównasz z powyższym oknem, możesz łatwo zinterpretować treść. Jak widać z powyższego, szablon (w tym przypadku) dzieli widok na cztery sekcje, które są zdefiniowane przez element formularza: <ui: insert name = "top"> Top </ ui: insert> Te elementy można modyfikować, aby uzyskać bardziej znaczącą treść, ale inne widoki powinny zawierać kod w jednym lub więcej z czterech obszarów. Dodam teraz inny widok do aplikacji o nazwie gallery.xhtml, ale powinien on zostać utworzony jako klient szablonu Facelet:

126 Po kliknięciu przycisku Dalej pojawi się następujące okno, w którym należy wpisać nazwę i wybrać szablon do użycia: a ponadto możesz wybrać, które sekcje w szablonie, ponieważ ten widok ma wstawić kod. Wynikiem jest następujący widok: <?xml version='1.0' encoding='utf-8'?>

127 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" > <html xmlns=" xmlns:ui=" <body> <ui:composition template="./maintemplate.xhtml"> <ui:define name="top"> top </ui:define> <ui:define name="content"> content </ui:define> </ui:composition> </body> </html> Należy zauważyć, że jest to strona JSF, a zatem widok, ale używa szablonu i wstawia kod w górnej i środkowej części. Jeśli uruchomisz aplikację, otwórz stronę początkową (index.xhtml) i kliknij link, otwiera widok gallery.xhtml, który wyświetla to samo okno, jak pokazano powyżej. Teraz zadaniem jest zdobycie czegoś bardziej znaczącego w czterech obszarach. Podam z szablonem. Najpierw stworzyłem obrazy podkatalogów w ramach zasobów i do tego skopiowałem zdjęcie o nazwie thy.jpg. Następnie tutaj zmieniłem maintemplate.xhtml na następujący: <?xml version='1.0' encoding='utf-8'?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional// EN" > <html xmlns=" > <h:head> <meta http-equiv="content-type" content="text/html; charset=utf-8" /> <h:outputstylesheet library="css" name="default.css"/> <h:outputstylesheet library="css" name="csslayout.css"/> <title>facelets Template</title> </h:head> <h:body> <div id="top"> <ui:insert name="top"> <h1>poul's Website</h1> </ui:insert>

128 </div> <div> <div id="left"> <ui:insert name="left"> <h:form> <h:commandlink value="my cars" action="mycars" /><br/> <h:commandlink value="my gallery" action="gallery" /><br/> </h:form> </ui:insert> </div> <div id="content" class="left_content"> <ui:insert name="content">content</ui:insert> </div> </div> <div id="bottom"> <ui:insert name="bottom"> <h:graphicimage library="images" style="width: 100%" name="thy.jpg"/> </ui:insert> </div> </h:body> </html> Oznacza to, że wstawiłem kod do trzech z czterech obszarów. Jeśli otworzysz aplikację i klikniesz link na stronie głównej, otrzymasz następujące wyniki (którym jest gallery.xhtml):

129 W lewym obszarze znajduje się formularz zawierający menu z elementami commandlink. Pierwsze linki do samego widoku, podczas gdy inne linki do widoku, który nie został jeszcze utworzony. Należy zwrócić uwagę na spód i sposób wstawiania obrazu. Zwróć uwagę w szczególności na stylizację obrazu, aby wypełnić całe okno. Wreszcie jest góra, która zawiera tylko element h1, ale najwyraźniej ten element nie jest używany. Powodem jest to, że góra jest przesłonięta przez galerię. xhtmp, który wstawia domyślną treść do górnej sekcji, zastępując w ten sposób wynik z szablonu. Następnym zadaniem jest uzupełnienie widoku galley.xhtml. Treść musi być listą linków do zdjęć, a obraz można zobaczyć, klikając link. Widok, podobnie jak inne widoki, ma kontroler, ale najpierw chcę zdefiniować klasę, która może reprezentować obraz: package paweb.models; public class Data private String name; private String text; public Data(String name, String text) this.name = name; this.text = text; public String getname() return name; public String gettext() return text; gdzie klasa znajduje się w pakiecie paweb.models. Jest to dość prosta klasa modelowa i zwykła klasa Java. Tekst to wartość wyświetlana na ekranie, a nazwa to nazwa obrazu (lub czegoś innego), którą klasa powinna reprezentować. W praktyce prawdopodobnie obraz miałby więcej właściwości i dla zilustrowania go zdefiniowałem następującą klasę pochodną; package paweb.models;

130 public class Photo extends Data public Photo(String name, String text) super(name, text); public String tostring() return gettext(); Następnie napisałem klasę kontrolera do widoku galerii: package paweb.beans; import java.util.*; import javax.inject.named; import javax.enterprise.context.sessionscoped; import java.io.serializable; import = public class GalleryController implements Serializable private List<Photo> photos = new ArrayList(); public GalleryController() photos.add(new Photo("lion", "Lion, a mail")); photos.add(new Photo("cheetah", "Cheetah, maybe three siblings"));

131 photos.add(new Photo("leopard", "Leopard with a kill")); public List<Photo> getphotos() return photos; Jest to bardzo prosty kontroler z jedną właściwością, która jest listą obiektów fotograficznych. Następnie zmieniłem gallery.xhtml, więc teraz wstawia kod w obszarze środkowym: <?xml version='1.0' encoding='utf-8'?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional// EN" > <html xmlns=" xmlns:ui=" xmlns:h=" xmlns:f=" <body> <ui:composition template="./maintemplate.xhtml"> <ui:define name="top"> top </ui:define> <ui:define name="content"> <h:form> <h1>some pictures from Africa</h1> <h:datatable value="#gallerycontroller.photos" var="img"> <f:facet name="header">photos</f:facet> <h:column> <h:commandlink value = "#img.text" action = "photoview"> <f:param name = "imagename" value = "#img.name.jpg" /> </h:commandlink> </h:column> </h:datatable> </h:form>

132 </ui:define> </ui:composition> </body> </html> Treść jest formularzem z elementem datetable, a tabela zawiera szereg elementów commandlink określonych przez klasę kontrolera. Jest to przykład akcji z parametrem, w której parametr jest zdefiniowany przez element param. Jeśli następnie wypróbujesz program, pojawi się następujące okno Poszczególne elementy commandlink odnoszą się do widoku, który nie został jeszcze utworzony. Najpierw skopiowałem jeszcze trzy zdjęcia do folderu zasobów / obrazów (lion.jpg, leopard.jpg i gepard. Jpg), a następnie utworzyłem stronę JSF o nazwie photoview.xhtml, aby wyświetlić obraz. Zauważ, że każde polecenielink ma parametr o nazwie imagename, a wartością jest nazwa obrazu: <f:param name = "imagename" value = "#img.name.jpg" /> Następnie jest photoview.xhtml <?xml version='1.0' encoding='utf-8'?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" > <html xmlns=" xmlns:ui=" xmlns:f=" xmlns:h=" <body> <ui:composition template="./maintemplate.xhtml"> <ui:define name="content"> <h2>this is one of my pictures</h2> <h:graphicimage library="images" style="width: 800px; height: 450px" name="#request.getparameter('imagename')"/> </ui:define>

133 </ui:composition> </body> </html> Jest to również widok, który korzysta z szablonu, ale definiuje tylko kod sekcji środkowej. Tutaj wstawiasz obraz i przede wszystkim powinieneś zwrócić uwagę na to, jak odwoływać się do nazwy obrazu, czyli parametru przesłanego z gallery.xhtml. Jeśli następnie wypróbujesz aplikację i klikniesz jeden z trzech łączy, otworzy się strona z obrazem. Zwróć uwagę, że strona pokazuje poprawną górną sekcję zdefiniowaną w szablonie. Pamiętaj, że wrócisz do strony galerii, klikając link w menu po lewej stronie. Ostatnią rzeczą, której brakuje w galerii, jest górna sekcja, w której należy dodać kod do tej sekcji. Celem jest pokazanie, jak utworzyć i dodać komponent kompozytowy. Jest to plik elementów JSF, który można wstawić w innym widoku i ewentualnie w wielu widokach. W JavaServers Faces wybrałem JSP Composite Component: Tutaj wpisuję nazwę (w tym przypadku szukaj) i miejsce, w którym komponent ma zostać umieszczony. NetBeans sugeruje resources / ezcomp i zaleca się zachowanie tej nazwy. Po kliknięciu przycisku Zakończ NetBeanns tworzy plik search.xhtml: <?xml version='1.0' encoding='utf-8'?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" > <html xmlns=" xmlns:cc=" <!-- INTERFACE --> <cc:interface> </cc:interface> <!-- IMPLEMENTATION --> <cc:implementation>

134 </cc:implementation> </html> Jest to zwykły szkielet, w którym część interfejsu musi definiować atrybuty komponentu, natomiast w sekcji implementacji należy zdefiniować kod, który ma być renderowany przez przeglądarkę. Gotowy komponent pokazano poniżej: <?xml version='1.0' encoding='utf-8'?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" > <html xmlns=" xmlns:h=" xmlns:f=" xmlns:cc=" <cc:interface> <cc:attribute name="searchlist"/> <cc:attribute name="searchaction" default="#searchcontroller.searchdata(cc.attrs.searchlist)" method-signature="java.lang.string action(java.util.list)"/> </cc:interface> <cc:implementation> <h:form id="searchform"> <h:outputtext id="error" value="#searchcontroller.errortext"/> <br/> <h:inputtext id="searchtext" styleclass="searchbox" style="width: 200px" value="#searchcontroller.searchtext"/> <h:commandbutton id="searchbutton" value="search" action="#cc.attrs.searchaction" /> <h:commandlink value="#searchcontroller.foundtext" action="photoview"> <f:param name = "imagename" value = "#searchcontroller.imagetext.jpg" /> </h:commandlink> </h:form> </cc:implementation> </html> Zauważ najpierw, że dodałem dwie domyślne przestrzenie nazw dotyczące elementów JSF. Następnie definiowane są dwa atrybuty, pierwszy to prosty atrybut o nazwie searchlist. Drugi nazywa się searchaction i definiuje metodę. Ma wartość domyślną, która jest metodą zdefiniowaną w nazwanej fasoli o nazwie SearchController, która ma wartość atrybutu searchlist jako parametr. Ponadto istnieje definicja podpisu metody jako metody, która zwraca ciąg znaków i ma listę jako parametr. Sekcja implementacji rozpoczyna się od parametru outputstream, który ma być użyty do komunikatu o błędzie z serachcontroller (jeśli szukasz czegoś, co nie istnieje). Następnie jest tekst inputtext, w którym użytkownik może wpisać szukany tekst, a następnie przycisk CommandButton, którego akcja jest metodą zdefiniowaną w sekcji interfejsu. Wreszcie istnieje CommandoLink, którego wartość jest

135 powiązana z właściwością w searchcontroller i którego akcja to photoview.xhtml. Ten link definiuje parametr, który jest również powiązany z właściwością w searchcontroller. Jak widać, ten komponent kompozytowy używa nazwanego komponentu bean: package paweb.beans; import java.util.*; import javax.inject.named; import javax.enterprise.context.sessionscoped; import java.io.serializable; import = public class SearchController implements Serializable private String searchtext; private String errortext; private String imagetext; private String foundtext; public SearchController() public void searchdata(list<data> list) errortext = ""; for (Data data : list) if (data.gettext().tolowercase().contains(searchtext.tolowercase())) imagetext = data.getname(); foundtext = data.gettext(); return; imagetext = ""; foundtext = ""; seterrortext("not found");

136 public String getsearchtext() return searchtext; public void setsearchtext(string searchtext) this.searchtext = searchtext; public String geterrortext() return errortext; public void seterrortext(string errortext) this.errortext = errortext; public String getimagetext() return imagetext; public String getfoundtext() return foundtext; Określa cztery właściwości i należy go używać do wyszukiwania obrazów. Cztery właściwości są używane do:

137 1. searchtext, podobnie jak to, co jest wyszukiwane 2. errortext, który jest komunikatem o błędzie w przypadku, gdy nic nie zostanie znalezione 3. imagetext, który jest tekstem znalezionego obiektu 4. foundtext, który jest nazwą znalezionego obiektu W przeciwnym razie główną metodą jest searchdata () jako metoda wywoływana ze składnika złożonego. Metoda ma parametr, który jest listą obiektów typu Data, czyli listą do przeszukania. Znalezienie obiektu inicjuje dwie właściwości imagetext i foundtext, a w przeciwnym razie errortext ma przypisaną wartość. Po zakończeniu komponentu należy go użyć w galerii.xhtml: <?xml version='1.0' encoding='utf-8'?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" > <html xmlns=" xmlns:ui=" xmlns:f=" xmlns:h=" xmlns:ez=" <body> <ui:composition template="./maintemplate.xhtml"> <ui:define name="top"> <h2>pouls website</h2> <ez:search id="searchgallery" searchlist="#gallerycontroller.photos"/> </ui:define> <ui:define name="content"> <h:form> <h1>some pictures from Africa</h1> <h:datatable value="#gallerycontroller.photos" var="img"> <f:facet name="header">photos</f:facet> <h:column> <h:commandlink value = "#img.text" action = "photoview"> <f:param name = "imagename" value = "#img.name.jpg" /> </h:commandlink> </h:column> </h:datatable> </h:form> </ui:define>

138 </ui:composition> </body> </html> W tym miejscu należy zwrócić uwagę na sposób użycia komponentu, a tutaj w szczególności na określenie listy do przeszukiwania za pomocą atrybutu zdefiniowanego w części interfejsu komponentu. Następnie kończy się pierwsza część aplikacji i muszę zaimplementować część odpowiadającą pierwszej pozycji menu w lewym sektorze. Zasadniczo jest to powtórzenie wielu z powyższych, ale poczyniono następujące. Stworzyłem klasę modelu całkowicie identyczną z Photo: package paweb.models; public class Car extends Data public Car(String name, String text) super(name, text); public String tostring() return gettext(); Nie ma oczywiście żadnego powodu, aby ta klasa była uwzględniona, a jej celem jest jedynie wykazanie, że w praktyce zawartość tej klasy byłaby inna niż w Photo. Dodano również klasę CarController, która odpowiada GalleryController, a dwie klasy są w zasadzie takie same, więc nie chcę tutaj pokazywać kodu. Dodano także carview.xhtml FaceLet, który jest prawie identyczny z photoview.xhtml. Następnie jest plik FaceLet cars.xhtml, ale zanim go obejrzę, dodam niewielką zmianę do komponentu kompozytowego: <?xml version='1.0' encoding='utf-8'?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" > <html xmlns=" > <cc:interface> <cc:attribute name="searchlist"/> <cc:attribute name="searchaction" default="#searchcontroller.searchdata(cc.attrs.searchlist)" method-signature="java.lang.string action(java.util.list)"/>

139 <cc:attribute name="viewer"/> <cc:attribute name="showaction" default="#searchcontroller.show(cc.attrs.viewer)" method-signature="java.lang.string action(java.lang.string)"/> </cc:interface> <cc:implementation> <h:form id="searchform"> <h:outputtext id="error" value="#searchcontroller.errortext"/> <br/> <h:inputtext id="searchtext" styleclass="searchbox" style="width: 200px" value="#searchcontroller.searchtext"/> <h:commandbutton id="searchbutton" value="search" action="#cc.attrs.searchaction" /> <h:commandlink value="#searchcontroller.foundtext" action="#cc.attrs.showaction"> <f:param name = "imagename" value = "#searchcontroller.imagetext.jpg" /> </h:commandlink> </h:form> </cc:implementation> </html> Rozszerzyłem o dwa nowe atrybuty, z których jeden odnosi się do metody w SearchController. Celem jest sparametryzowanie akcji, która ma zostać wykonana po kliknięciu łącza. Metoda w SearchController to public String show(string name) return name; Po tej zmianie należy także zaktualizować widok gallery.xhtml, aby zainicjować atrybut komponentu. Wreszcie plik cars.xhtml można zapisać w następujący sposób: <?xml version='1.0' encoding='utf-8'?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" > <html xmlns=" xmlns:ui=" xmlns:f=" xmlns:h=" xmlns:ez=" <body> <ui:composition template="./maintemplate.xhtml">

140 <ui:define name="top"> <h2>pouls website</h2> <ez:search id="searchgallery" searchlist="#carcontroller.cars" viewer="carview"/> </ui:define> <ui:define name="content"> <h:form> <h1>that is my cars</h1> <p>the following </p> <table> <ui:repeat var="car" value="#carcontroller.cars"> <tr> <td> <h:commandlink value = "#car.text" action = "carview"> <f:param name = "imagename" value = "#car.name.jpg" /> </h:commandlink> </td> </tr> </ui:repeat> </table> </h:form> </ui:define> </ui:composition> </body> </html> Zauważ, że użyto innej pętli. Nie ma żadnego szczególnego powodu, dla którego chcesz zadbać o to, jak zbudowana jest tabela, na przykład ze względu na style. Na koniec zasoby / obrazy dyrekcji są aktualizowane trzema obrazami, a aplikacja jest wykonywana, a jeśli wybierzesz lewe menu Moje samochody, pojawi się okno:

141 6.4 MOTYWY Jeśli masz aplikację internetową, możesz zastosować motywy, w których widoki aplikacji są renderowane zgodnie z wybranym motywem. Na przykład aplikacja może wyglądać inaczej w zależności od zalogowanego użytkownika. Motywy są oparte na szablonach, a ja w tej sekcji pokażę, jak to działa. Jeśli otworzysz aplikację Kontrakty, pojawi się powyższe okno. To jest proste okno z tekstem. Jeśli z rozwijanej listy wybierz ciemny motyw i kliknij Wybierz, okno zmieni się na:

142 Punktem wyjścia jest zwykła aplikacja JSF o nazwie Kontrakty. Dodatkowo dodałem Resource Library Contract: a po kliknięciu przycisku Dalej przypisałem nazwę (domyślnie) i wybrałem szablon (nazwany szablon patrz poniżej). Następnie NetBeans tworzy umowy katalogowe / domyślne z szablonem (i dwoma arkuszami stylów). Następnie powtórzyłem to wszystko i stworzyłem kolejny kontrakt na bibliotekę zasobów, ale tym razem o nazwie dark. W przeciwnym razie nie ma różnic

143 Po utworzeniu dwóch umów treść projektu jest następująca, do której dodano również nazwaną fasolę o nazwie ThemeSelector: Dwa szablony są takie same, ale pomysł polega na tym, że można je modyfikować według potrzeb. W tym przypadku tak nie jest, ale treść jest: <?xml version='1.0' encoding='utf-8'?>

144 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN",,, > <html xmlns=" > <h:head> <meta http-equiv="content-type" content="text/html; charset=utf-8" /> <h:outputstylesheet library="css" name="default.css"/> <h:outputstylesheet library="css" name="csslayout.css"/> <title>facelets Template</title> </h:head> <h:body> <div id="top" class="top"> <ui:insert name="top">top</ui:insert> </div> <div id="content" class="center_content"> <ui:insert name="content">content</ui:insert> </div> </h:body> </html> Następnie zmodyfikowałem index.xhtml na (alternatywnie mogłeś stworzyć nowego klienta szablonu FaceLets): <?xml version='1.0' encoding='utf-8'?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" > <html xmlns=" > <h:body> <f:view contracts="#themeselector.name"> <ui:composition template="/template.xhtml"> <ui:define name="top"> <h:form> <h:outputlabel for="selector" value="select a theme"/> <h:selectonemenu id="selector" value="#themeselector.name"> <f:selectitem itemlabel="default" itemvalue="default"/> <f:selectitem itemlabel="dark" itemvalue="dark"/>

145 </h:selectonemenu> <h:commandbutton value="select" action="index"/> </h:form> </ui:define> <ui:define name="content"> <p> </p> </ui:define> </ui:composition> </f:view> </h:body> </html> Tutaj należy zauważyć, że wszystko jest otoczone przez element f: view, określony przez obiekt bean, który określa, którego motywu użyć. W przeciwnym razie reszta to po prostu kod wstawiony do dwóch sekcji zdefiniowanych przez szablon. Zauważ również, że element commandbutton u góry wykonuje przesłanie do samej strony, co oznacza, że strona jest renderowana na podstawie wybranego motywu. Korzystanie z motywów jest dość proste, ale na razie oba motywy są takie same i nie będzie różnicy, jeśli wybierzesz jeden lub drugi motyw. Rozwiązuje się to poprzez zmianę dwóch szablonów oraz używanych przez nich arkuszy stylów. Zmieniłem szablon domyślnego motywu na następujący: <h:body> <div id="top" class="top"> <ui:insert name="top">top</ui:insert> </div> <div id="content" class="center_content"> <h2>the theme is default</h2> <ui:insert name="content">content</ui:insert> </div> </h:body> A drugi szablon został odpowiednio zmieniony, tak więc tekst to Motyw jest ciemny. Na koniec, dla motywu ciemnego, zmieniłem jedną claas w csslayout.css na.center_content position: relative; background-color: #444444; color: #ffffff; padding: 5px;

146 PROBLEM 3 W tym zadaniu musisz napisać aplikację internetową, która otwiera prostą stronę powitalną: Treść nie jest bardzo ważna, ale musi być link do poniższego formularza. Powinno to ilustrować, że dana osoba chce subskrybować biuletyny (w tym przypadku biuletyny z klubu winiarskiego lub odpowiednika). Celem jest praca z elementami JSF, o których nie wspomniałem. Częścią zadania jest ustalenie, jak nazywane są poszczególne elementy i jak są one używane.

147 Gdy formularz jest wysyłany na serwer, należy sprawdzić, czy zostało wprowadzone imię i nazwisko oraz czy został wpisany legalny adres . Należy również potwierdzić, że wybrano płeć. Na koniec należy sprawdzić, czy zawartość dwóch pól hasła jest taka sama. Poniżej znajduje się przykład wypełnionego formularza:

148 Jeśli klikniesz Wyślij, zobaczysz stronę potwierdzenia poniżej, na której możesz kliknąć Edytuj aby zmienić wprowadzone dane:

149 6.5 UPLOAD OBRAZÓW Aby zakończyć tą część i JavaServer Faces, pokażę mały przykład aplikacji internetowej, w której możesz przesyłać obrazy na serwer WWW. W rzeczywistości jest to powszechny problem, więc ten przykład, ale jest dość łatwy. Przykład składa się tylko z index.xhtml i pojedynczego bean: <?xml version='1.0' encoding='utf-8'?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" > <html xmlns=" xmlns:f=" xmlns:h=" <h:head> <title>upload image</title> </h:head> <h:body> <h:form enctype="multipart/form-data"> <h2>choose a file to upload to the server:</h2>

150 <h:inputfile value="#uploadcontroller.file"> <f:ajax listener="#uploadcontroller.save" /> </h:inputfile> </h:form> </h:body> </html> Wszystko to odbywa się za pomocą jednego elementu JSF o nazwie h: inputfile, który wiąże się z właściwością pliku w komponencie bean. Za pomocą tego komponentu możesz przeglądać lokalny system plików i przesyłać obraz (a nawet dowolny plik). Teraz obraz również musi zostać zapisany, co dzieje się z poleceniem ajax. Ajax jest omówiony w następnej książce, a tutaj musisz tylko wziąć pod uwagę składnię, ale w rezultacie wywoływana jest metoda w klasie bean, która jest następnie odpowiedzialna za zapisanie obrazu. Klasa bean jest następująca: package upload.beans; import java.io.*; import java.nio.file.*; import javax.inject.named; import javax.enterprise.context.*; import = public class UploadController implements Serializable private Part file; private String uploads = System.getProperty("user.home") + "/tmp"; public UploadController() public Part getfile() return file;

151 public void setfile(part file) this.file = file; public void save() try (InputStream input = file.getinputstream()) Files.copy(input, new File(uploads, fi catch (IOException ex) Problem związany z aplikacją wymagającą rozwiązania polega na tym, że obrazy (pliki) muszą zostać zapisane. Oczywiście aplikacja musi wiedzieć, gdzie i musi istnieć katalog na serwerze, który można wite. W tym przykładzie katalog jest wybrany w moim katalogu domowym, ale w praktyce oczywiście wymagane jest inne rozwiązanie. Na przykład możesz przestudiować sposób rozwiązania problemu w ostatnim przykładzie. Klasa ma zmienną o nazwie plik, a tutaj należy szczególnie zwrócić uwagę na typ: javax.servlet.http.part W przeciwnym razie nie ma wiele do zauważenia poza metodą save (), która tworzy kopię w wybranym katalogu przesyłanego pliku. 7 OSTATNI PRZYKŁAD Zadanie polega na napisaniu aplikacji internetowej dla weterana klubu samochodowego, w której członkowie klubu mogą zaprezentować swoje samochody publiczności. Jest to więc typowa aplikacja internetowa, która ma dwie prezentacje: 1. strona publiczna, która jest rzeczywistą witryną i może być używana przez wszystkich użytkowników 2. strona administracyjna, z której mogą korzystać tylko osoby, które muszą administrować witryną (webmasterzy), a ta część aplikacji zwykle wymaga logowania

152 W takim przypadku musi być jeden lub więcej webmasterów, którzy mogą wszystkim, a szczególnie utrzymywać informacje o członkach klubu. Inni członkowie klubu również powinni mieć możliwość korzystania z części administracyjnej, ale powinni mieć jedynie możliwość przechowywania informacji o swoich samochodach. Jeśli chodzi o stronę publiczną, każdy musi mieć do niej dostęp, a strona powinna zasadniczo zawierać informacje o samochodach członków i zazwyczaj jedno lub więcej zdjęć. Ponadto strona musi być dołączona do księgi gości, gdzie każdy ma możliwość dołączenia komentarza. 7.1 ANALIZA Strona publiczna jest ogólnie prosta i składa się z następujących widoków, w których strzałki pokazują, jak poruszać się po witrynie: 1. indeks to strona główna lub strona powitalna, która daje krótką prezentację witryny 2. samochody to strona wyszukiwania, na której użytkownik ma możliwość przeszukiwania samochodów członków 3. samochód to strona prezentacji, która pokazuje szczegółowe informacje o jednym samochodzie, w tym informacje o właścicielu samochodu 4. Goście to księga gości, w której znajduje się spis treści posortowany według daty 5. Gość pokazuje, co napisał dany gość 6. edit to strona, na której użytkownik może pisać w księdze gości W odniesieniu do części administracyjnej musi zawierać następujące strony:

153 1. logowanie to strona logowania dla webmasterów i członków 2. start to strona główna części administracyjnej 3. hasło służy do zmiany hasła 4. showcars pokazuje przegląd poszczególnych samochodów członków, a dla webmasterów wszystkie samochody 5. editcar służy do edycji informacji o samochodzie, w tym do stworzenia nowego samochodu i do usunięcia istniejącego samochodu 6. członkowie pokazuje przegląd członków klubu - z tej funkcji mogą korzystać tylko webmasterzy 7. członek służący do edycji informacji o członku, w tym tworzenie nowego członka, a także usuwanie istniejącego członka - z tej funkcji mogą korzystać tylko webmasterzy 8. delguest służy do usuwania stron z księgi gości, jeśli coś zostało napisane, że klub nie zaakceptuje - z funkcji mogą korzystać tylko webmasterzy ebmaster może w szczególności utrzymywać samochody nie będące własnością członka. Jeśli tak, powinien pojawić się na stronie publicznej. Słownik danych Członkowie: - liczba (która jest unikalną 5 cyfrową liczbą całkowitą) - imię - adres - kod pocztowy

154 - mail (używany jako nazwa użytkownika) - telefon - hasło - opis - rola użytkownika (0 = domyślny webmaster, 1 = web master, 2 = członek) Domyślny webmaster to standardowy webmaster (superużytkownik) tworzony podczas tworzenia bazy danych i nie można go usunąć. Inni webmasterzy są w zasadzie zwykłym członkiem, ale mają uprawnienia administratora. Opis ma na celu umożliwienie członkowi przedstawienia siebie lub swoich samochodów. Księga gości: - imię - kod pocztowy - Poczta - data (kiedy jest zapisana w księdze gości) - tekst Samochody: - kod kraju (gdzie produkowany jest samochód) - producent (na przykład Opel, Ford, ) - imię - oznaczenie modelu - oznaczenie wariantu w modelu - silnik (na przykład V8) - efekt (efekt silnika w HK i możliwej jednostce) - rok produkcji - właściciel (członek) - opis - zdjęcie (jedno lub więcej zdjęć) 7.2 PROJEKT

155 Strona index.xhtml pokazuje następujący widok, który jest prostą stroną powitalną. Na dole znajduje się link do strony publicznej, a więc do cars.xhtml, podczas gdy w prawym górnym rogu znajduje się link do części administracyjnej, a tym samym link do login.xhtml: Dane aplikacji muszą być przechowywane w bazie danych, z wyjątkiem obrazów przesłanych bezpośrednio Dane aplikacji muszą być przechowywane w bazie danych, z wyjątkiem obrazów przesłanych do katalogu na serwerze. Baza danych powinna mieć przede wszystkim trzy tabele: 1. do członków 2. do samochodów 3. do księgi gości a pełny projekt bazy danych pokazano w następującym skrypcie: use sys; drop database if exists veteran; create database veteran; use veteran; create table guest ( id int auto_increment primary key, name varchar(100), code char(4), mail varchar(50), date date, text text );

156 create table owners ( id char(5) primary key, name varchar(100), address varchar(100), code char(4), mail varchar(50), phone varchar(20), text text, role int default 1, passwd varchar(150) ); create table brands ( id int auto_increment primary key, country char(2), name varchar(100) ); create table cars ( id int auto_increment primary key, brand int, name varchar(100), model varchar(100), variant varchar(100), motor varchar(100), effekt varchar(20), year int, owner char(5), text text, foreign key (brand) references brands (id), foreign key (owner) references owners (id) ); create table image ( id int auto_increment primary key, name varchar(100), car_id int, foreign key (car_id) references cars(id) ); insert into owners (id, name, mail, text, role) values ("00000", "Web master", "poul.klausen@mail.dk", "Super User", 0); Obraz w tabeli zawiera nazwy obrazów (w stosunku do katalogu obrazów). Powodem tej tabeli jest to, że do tego samego samochodu można dołączyć więcej zdjęć. Podobnie istnieje tabela marek, która zawiera listę marek samochodów. Powodem tej tabeli jest częściowo to, że wiele samochodów ma tego samego producenta, a marka samochodów ma być używana podczas wyszukiwania samochodów. Ogólny wygląd jest następujący:

157 gdzie administrator dyrekcji musi zawierać wszystkie FaceLety dotyczące części administracyjnej. Szczególnym problemem jest bezpieczeństwo i sposób, w jaki osoby nieupoważnione nie mogą zmieniać zawartości bazy danych witryny. W takim przypadku bezpieczeństwo musi mieć niski priorytet. Częściowo dlatego, że zawartość strony nie wymaga specjalnej ochrony i nie można oczekiwać, że ktokolwiek użyje energii do zaatakowania strony, a częściowo dlatego, że (i przede wszystkim) nie rozwiązałem jeszcze problemu bezpieczeństwa. Aby uzyskać dostęp do sekcji administracyjnej, członek (właściciel samochodu) musi wprowadzić swój numer członkowski i hasło. Utworzenie odpowiedniego hasła musi być obowiązkiem członka i jest ono przechowywane w postaci zaszyfrowanej w bazie danych. Oprócz tego, że nie twierdzi się siły hasła i że obowiązkiem użytkownika jest utworzenie hasła, największą słabością jest to, że hasło jest przesyłane jawnym tekstem (niezaszyfrowane) z klienta na serwer, a zatem może zostać przechwycone przez atakującego. 7.3 PROGRAMOWANIE Gotowe miejsce składa się z 15 fasetek i dodatkowo kontrolerów (nazwanych ziaren), klas modeli i innych klas pomocniczych. Nie ma pełnego dopasowania między 15 fasetkami a powyższymi mapami nawigacyjnymi (diagramy pokazują tylko 14 widoków) i zwykle podczas programowania będą dokonywane zmiany co do tego, jakie widoki będzie zawierać ukończone rozwiązanie. Niemniej jednak uważam, że warto poświęcić czas na sporządzenie wykresów, nawet jeśli końcowy wynik różni się, a im bardziej ostrożny jesteś w analizie, tym większa szansa, że programowanie oznacza jedynie drobne korekty. W porównaniu z wieloma praktycznymi aplikacjami internetowymi, obecna aplikacja jest niewielka i generalnie nie będę wyświetlać kodu ani facelitów, ani klas Java, ale wyjaśnię, w jaki sposób aplikacja jest rozwijana. Zachęcamy jednak do przestudiowania kodu, a w porównaniu z tym, co w tej książce dotyczy aplikacji internetowych, wiele szczegółów zostało rozwiązanych. Część administracyjna Zacznę od części dotyczącej zarządzania, która jest typowa dla tworzenia aplikacji internetowych tego typu. Stronę publiczną można opracować dopiero po dodaniu danych do bazy danych. Do warstwy modelu dodaje się następujące klasy: - Marka - Samochód - Zdjęcie - Właściciel

158 - Gość który modeluje tabele bazy danych. To wszystkie proste klasy modeli, być może zbliżone do Car, które zawierają odniesienia do innych obiektów: Ponadto istnieje repozytorium klas, które jest singletonem z metodami obsługi bazy danych. Klasa jest stosunkowo złożona (kompleksowa), ale nie zawiera niczego nowego w porównaniu z odpowiednimi klasami z innych programów. Parametry bazy danych (nazwa użytkownika i hasło) są przechowywane w pliku web.xml, a także nazwa katalogu zawierającego przesłane obrazy: <?xml version="1.0" encoding="utf-8"?> <web-app >. <welcome-file-list> <welcome-file>faces/index.xhtml</welcome-file> </welcome-file-list> <listener> <listener-class>veterancars.models.paramsfactory</listener-class> </listener> <context-param> <param-name>usr</param-name> <param-value>pa</param-value> </context-param> <context-param> <param-name>pwd</param-name> <param-value>volmer_1234</param-value> </context-param> <context-param> <param-name>images</param-name> <param-value>/home/pa/tmp</param-value>

159 </context-param> </web-app> W przypadku zdjęć należy je przesłać do katalogu z prawami zapisu. Za każdym razem, gdy obraz jest przesyłany, na obrazie tabeli tworzony jest wiersz, a wierszowi przypisywany jest numer automatyczny. Ten numer jest jednocześnie używany jako nazwa pliku obrazu, a jeśli na przykład obraz jest przypisany do numeru 123 (przez serwer bazy danych), obraz zostaje zapisany pod nazwą 123.jpg. W związku z tym postanowiono, że program będzie obsługiwał tylko obrazy jpg (zdjęcia). Wszystkie widoki dotyczące administracji znajdują się w folderze administratora, a prawie jeden jest powiązany z kontrolerem. Po wybraniu administracji na stronie powitalnej zobaczysz logon.xhtml, gdzie musisz wprowadzić numer członka i hasło. Następnie przejdziesz na stronę powitalną sekcji zarządzania o nazwie start.xhtml. Ta strona ma menu funkcji u góry. Zgodnie ze specyfikacją wymagań część administracyjna musi spełniać następujące funkcje: 1. Utrzymanie marek samochodów 2. Konserwacja samochodów 3. Utrzymanie właścicieli (członków) 4. Utrzymanie księgi gości 5. Zmień hasło Pierwsza funkcja jest prosta i może być wykonywana tylko przez użytkownika z uprawnieniami administratora. Zawiera dwa widoki: 1. Brands.xhtml, który pokazuje przegląd wszystkich marek samochodów, które zostały utworzone i edytujesz markę samochodu, klikając na nią 2. brand.xhtml, które służą do tworzenia i utrzymywania marek samochodów Następna funkcja jest najbardziej wszechstronna i może być wykonywana przez wszystkich, ale jeśli nie masz uprawnień administratora, będą wyświetlane tylko własne samochody. Funtion ma trzy widoki: 1. cars.xhtml, który pokazuje przegląd wszystkich samochodów pogrupowanych według marki samochodu, więc jeśli klikniesz markę samochodu, otrzymasz wszystkie samochody dla tej marki i klikniesz samochód, otrzymasz wszystkie szczegóły samochodu i tam to także link, dzięki któremu możesz edytować informacje o samochodzie 2. car.xhtml, który służy do tworzenia i utrzymywania informacji o samochodzie 3. showcar.xhtml, który pokazuje szczegółowe informacje o samochodzie i zawiera wszelkie zdjęcia Gdy ta funkcja jest złożona, jest to częściowo spowodowane przesyłaniem obrazów, w których powinna istnieć możliwość edycji podpisu, a także możliwość pokazania obrazu przez zawartość

160 showcar.xhtml (zawartość pliku). Ostatni problem rozwiązany jest za pomocą serwletu. Trzecia funkcja przypomina pierwszą funkcję i może być wykonywana przez wszystkich użytkowników z uprawnieniami administratora. Funkcja ma dwa widoki: 1. właściciele.xhtml, pokazujący przegląd wszystkich właścicieli 2. właściciel.xhtml, używany do tworzenia i edycji informacji o właścicielu (członku) Po zaimplementowaniu tych funkcji napisałem kod na stronie publicznej. Strona publiczna Ze strony powitalnej przejdziesz do main.xhtml, który jest główną stroną witryny. Tutaj możesz kliknąć samochody, korzystając z menu po lewej stronie, gdzie samochody są pogrupowane według marki samochodu. Możesz także wyszukać samochód za pomocą dowolnego tekstu, który wyszukuje markę, nazwę, model i tekst samochodu. Pasujące samochody są wyświetlane w rozwijanym polu, z którego można wybrać samochód. U góry znajduje się również link do księgi gości, który składa się z dwóch widoków: 1. guests.xhtml, który pozwala przeszukiwać księgę gości, w której można wyszukiwać według daty lub wpisać szukany tekst według nazwy i samego tekstu 2. guest.xhtm, który pozwala pisać w księdze gości Zakończenie części administracyjnej Wreszcie ukończyłem część administracyjną. Funkcja zmiany hasła jest prosta i składa się tylko z jednego widoku ze sterownikiem. Ostatnia funkcja ma również tylko jeden widok i jest praktycznie identyczna z gość.xhtml i używa tego samego kontrolera. Jedyną różnicą jest to, że można usunąć stronę z księgi gości. 7.4 WDROŻENIE Aby aplikacja internetowa mogła zostać uruchomiona (otwiera się w przeglądarce), aplikacja musi zostać zainstalowana na serwerze Glassfish, proces ten nazywany jest wdrożeniem. Na razie zignorowałem wszystko, ponieważ NetBeans robi to automatycznie na lokalnym serwerze Glassfish. Pokażę teraz, jako przykład, jak wdrożyć bieżącą aplikację na innym komputerze. Warunkiem jest, aby maszyna miała działający serwer Glassfish, a także działający serwer bazy danych. Proces wymaga dwóch plików: 1. veteran.sql, który jest skryptem SQL służącym do tworzenia bazy danych 2. VeteranCars.war, który jest plikiem wojny z aplikacją internetową (znajduje się w katalogu dist projektu) Pierwszym krokiem jest utworzenie bazy danych, która polega po prostu na uruchomieniu powyższego skryptu. Następnie należy utworzyć katalog dla obrazów. Pamiętaj, że jeśli chcesz bazę danych danych, możesz wykonać kopię zapasową bazy danych z maszyny programisty i utworzyć jej przywrócenie, pamiętając jednocześnie o skopiowaniu obrazów z maszyny programisty. W celu wdrożenia otwórz program administracyjny w przeglądarce:

161 Tutaj musisz kliknąć Aplikacje po lewej stronie, a następnie zakładkę Wdróż... a następnie możesz przejść do pliku wojny (patrz poniżej). Wszystkie pozostałe ustawienia można zachować jako domyślne, a następnie kliknąć OK, aplikacja zostanie wdrożona. Pozostaje tylko upewnić się, że parametry pliku web.xml odpowiednio dla serwera bazy danych i katalogu obrazów są prawidłowe. Możesz edytować plik, klikając nazwę aplikacji i wybierając kartę Deskryptor (patrz poniżej). Oto link do pliku web.xml, w którym możesz edytować plik.

162 Następnie wszystko powinno być gotowe, a aplikację można otworzyć w przeglądarce (na innym komputerze), wpisując (zakładając, że adres IP jest poprawny): 8 UWAGI KOŃCOWE Przykład z poprzedniego rozdziału należy postrzegać jako formę statusu tego wprowadzenia do aplikacji internetowych, a także jest to klasyczny przykład aplikacji internetowej. Powstaje zatem pytanie, czego brakuje, zanim zostaniesz w pełni przeszkolony jako programista - a tych książek jest coraz więcej. Chciałbym zakończyć trochę powyższą aplikacją, aw szczególności jej wadami i wymaganiami dotyczącymi aplikacji internetowych w praktyce, a tym samym tematami, które są omówione w pewnym stopniu w dwóch poniższych książkach. Spojrzę na program w odniesieniu do następujących 5 nagłówków: 1. Przyjazny w utrzymaniu 2. Atrakcyjne interfejsy użytkownika 3. Programowanie po stronie klienta 4. Uwierzytelnianie i bezpieczeństwo 5. Programowanie Distribueret Przyjazny w utrzymaniu

prepared by: Programowanie WWW Servlety

prepared by: Programowanie WWW Servlety Programowanie WWW Servlety Przypomnienie problemu Aplikacja do liczenia kredytów Klasa Kredyt Formatka do wprowadzania danych (czysty HTML) Skrypt liczący ratę (JSP wykorzystujące klasę Kredyt) Klasa Kredyt

Bardziej szczegółowo

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

Elementy JEE. 1. Wprowadzenie. 2. Prerekwizyty. 3. Pierwszy servlet. obsługa parametrów żądań 4. JavaServer Pages. Elementy JEE 1. Wprowadzenie. 2. Prerekwizyty. 3. Pierwszy servlet. obsługa parametrów żądań 4. JavaServer Pages. 1 Java Enterprice Edition Java Enterprice Edition (JEE) jest rozszerzeniem Java Standard

Bardziej szczegółowo

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

Zaawansowane aplikacje internetowe - laboratorium Web Services (część 1). Zaawansowane aplikacje internetowe - laboratorium Web Services (część 1). Celem ćwiczenia jest przygotowanie prostej aplikacji internetowej wykorzystującej technologię usług sieciowych (ang. Web Services).

Bardziej szczegółowo

Aplikacje internetowe i rozproszone - laboratorium

Aplikacje internetowe i rozproszone - laboratorium Aplikacje internetowe i rozproszone - laboratorium Enterprise JavaBeans (EJB) Celem tego zestawu ćwiczeń jest zapoznanie z technologią EJB w wersji 3.0, a w szczególności: implementacja komponentów sesyjnych,

Bardziej szczegółowo

Architektury Usług Internetowych. Laboratorium 1. Servlety

Architektury Usług Internetowych. Laboratorium 1. Servlety Architektury Usług Internetowych Laboratorium 1. Servlety Wstęp Celem laboratorium jest zapoznanie się z modelem klient-serwer (żądanie-odpowiedź) na przykładzie serwletów. Kontener webowy Kontener webowy

Bardziej szczegółowo

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

Wykład dla studentów Informatyki Stosowanej UJ 2012/2013 e-biznes Wykład dla studentów Informatyki Stosowanej UJ 2012/2013 Michał Cieśla pok. 440a, email: michal.ciesla@uj.edu.pl konsultacje: środy 10-12 http://users.uj.edu.pl/~ciesla/ 1 Literatura B. Burke,

Bardziej szczegółowo

Aplikacje WWW - laboratorium

Aplikacje WWW - laboratorium Aplikacje WWW - laboratorium JavaServer Pages Celem ćwiczenia jest zbudowanie kilku prostych stron internetowych z użyciem technologii JSP. Podczas ćwiczenia wykorzystany zostanie algorytm sortowania bąbelkowego

Bardziej szczegółowo

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

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 Zaawansowane aplikacje internetowe EJB 2 Celem tego laboratorium jest pokazanie, w jaki sposób aplikacje stworzone w różnych technologiach mogą korzystać z funkcjonalności udostępnianej przez komponenty

Bardziej szczegółowo

Architektury Usług Internetowych. Laboratorium 1 Servlety

Architektury Usług Internetowych. Laboratorium 1 Servlety Architektury Usług Internetowych Laboratorium 1 Servlety Wstęp Celem laboratorium jest zapoznanie się z modelem klient-serwer (żądanieodpowiedź) na przykładzie serwletów. Kontener webowy Kontener webowy

Bardziej szczegółowo

Enterprise JavaBeans (EJB)

Enterprise JavaBeans (EJB) Enterprise JavaBeans (EJB) Celem tego zestawu ćwiczeń jest zapoznanie z sesyjnymi komponentami Enterprise JavaBeans. Zilustrowane będą różnice między komponentami stanowymi i bezstanowymi. Pokazane będzie

Bardziej szczegółowo

Wybrane działy Informatyki Stosowanej

Wybrane działy Informatyki Stosowanej Wybrane działy Informatyki Stosowanej Laboratorium 2. Formularze HTML. Metody przekazywania parametrów. Spis treści I. Wprowadzanie wartości parametrów w formularzu HTML... 1 II. Projektowanie formularza

Bardziej szczegółowo

Laboratorium 1 Wprowadzenie do PHP

Laboratorium 1 Wprowadzenie do PHP Laboratorium 1 Wprowadzenie do PHP Ćwiczenie 1. Tworzenie i uruchamianie projektu PHP w Netbeans Tworzenie projektu Uruchom środowisko NetBeans. Stwórz nowy projekt typu PHP Application (File->New Project,

Bardziej szczegółowo

Narzędzia i aplikacje Java EE. Usługi sieciowe Paweł Czarnul pczarnul@eti.pg.gda.pl

Narzędzia i aplikacje Java EE. Usługi sieciowe Paweł Czarnul pczarnul@eti.pg.gda.pl Narzędzia i aplikacje Java EE Usługi sieciowe Paweł Czarnul pczarnul@eti.pg.gda.pl Niniejsze opracowanie wprowadza w technologię usług sieciowych i implementację usługi na platformie Java EE (JAX-WS) z

Bardziej szczegółowo

Wybrane Działy Informatyki Stosowanej LABORATORIUM 1.

Wybrane Działy Informatyki Stosowanej LABORATORIUM 1. WDIS 2019L: Zajęcia 1. Serwer Apache Tomcat. Środowisko NetBeans. Strona 1 z 9 Wybrane Działy Informatyki Stosowanej LABORATORIUM 1. KONFIGUROWANIE SERWERA APACHE TOMCAT. PODSTAWY UMIESZCZANIA PLIKÓW HTML,

Bardziej szczegółowo

Aplikacje WWW - laboratorium

Aplikacje WWW - laboratorium Aplikacje WWW - laboratorium Serwlety Celem ćwiczenia jest przygotowanie kilku prostych serwletów ilustrujących możliwości tej technologii. Poszczególne ćwiczenia prezentują sposób przygotowania środowiska,

Bardziej szczegółowo

Podstawy technologii WWW

Podstawy technologii WWW Podstawy technologii WWW Ćwiczenie 8 PHP, czyli poczatki nowej, dynamicznej znajomosci Na dzisiejszych zajęciach rozpoczniemy programowanie po stronie serwera w języku PHP. Po otrzymaniu żądania serwer

Bardziej szczegółowo

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

Materiały oryginalne: ZAWWW-2st1.2-l11.tresc-1.0kolor.pdf. Materiały poprawione Materiały oryginalne: ZAWWW-2st1.2-l11.tresc-1.0kolor.pdf Materiały poprawione Rozwiązanie zadania w NetBeans IDE 7.4: Jarosław Ksybek, Adam Miazio Celem ćwiczenia jest przygotowanie prostej aplikacji

Bardziej szczegółowo

Laboratorium - Przechwytywanie i badanie datagramów DNS w programie Wireshark

Laboratorium - Przechwytywanie i badanie datagramów DNS w programie Wireshark Laboratorium - Przechwytywanie i badanie datagramów DNS w programie Wireshark Topologia Cele Część 1: Zapisanie informacji dotyczących konfiguracji IP komputerów Część 2: Użycie programu Wireshark do przechwycenia

Bardziej szczegółowo

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

Przykłady tworzenia aplikacji komponentowych w technologii JavaServer Faces 2.1 na podstawie Przykłady tworzenia aplikacji komponentowych w technologii JavaServer Faces 2.1 na podstawie http://docs.oracle.com/javaee/6/tutorial/doc/ Przykłady na podstawie zadań lab. z przedmiotu Technologie internetowe

Bardziej szczegółowo

Serwery aplikacji. dr Radosław Matusik. radmat

Serwery aplikacji. dr Radosław Matusik.   radmat www.math.uni.lodz.pl/ radmat Ciasteczka trwałe i sesyjne Ciasteczka trwałe - pozostają na komputerze użytkownika po zamknięciu strony, z której zostały pobrane / przeglądarki. Ciasteczka sesyjne - są związane

Bardziej szczegółowo

Laboratorium 1. Wzorce oprogramowania lab1, Zofia Kruczkiewicz

Laboratorium 1. Wzorce oprogramowania lab1, Zofia Kruczkiewicz Aplikacja internetowa zbudowana w oparciu o środowisko Visual Web Java Server Faces. Zarządzanie obiektami typu SesionBeans, RequestBeen i ApplicationBeans, Laboratorium 1 Wzorce oprogramowania lab1, Okres

Bardziej szczegółowo

Ćwiczenie 1. Kolejki IBM Message Queue (MQ)

Ćwiczenie 1. Kolejki IBM Message Queue (MQ) Ćwiczenie 1. Kolejki IBM Message Queue (MQ) 1. Przygotowanie Przed rozpoczęciem pracy, należy uruchomić "Kreator przygotowania WebSphere MQ" oraz przejść przez wszystkie kroki kreatora, na końcu zaznaczając

Bardziej szczegółowo

A Zasady współpracy. Ocena rozwiązań punktów punktów punktów punktów punktów

A Zasady współpracy. Ocena rozwiązań punktów punktów punktów punktów punktów A Zasady współpracy Ocena rozwiązań 3.0 25 40 punktów 3.5 41 65 punktów 4.0 66 80 punktów 4.5 81 100 punktów 5.0 101 130 punktów Warunki zaliczenia przedmiotu Student uzyska ocenę zaliczającą (3.0) o ile

Bardziej szczegółowo

Sposoby tworzenia projektu zawierającego aplet w środowisku NetBeans. Metody zabezpieczenia komputera użytkownika przed działaniem apletu.

Sposoby tworzenia projektu zawierającego aplet w środowisku NetBeans. Metody zabezpieczenia komputera użytkownika przed działaniem apletu. Sposoby tworzenia projektu zawierającego aplet w środowisku NetBeans. Metody zabezpieczenia komputera użytkownika przed działaniem apletu. Dr inż. Zofia Kruczkiewicz Dwa sposoby tworzenia apletów Dwa sposoby

Bardziej szczegółowo

Sesje, ciasteczka, wyjątki. Ciasteczka w PHP. Zastosowanie cookies. Sprawdzanie obecności ciasteczka

Sesje, ciasteczka, wyjątki. Ciasteczka w PHP. Zastosowanie cookies. Sprawdzanie obecności ciasteczka Sesje, ciasteczka, wyjątki Nie sposób wyobrazić sobie bez nich takich podstawowych zastosowań, jak logowanie użytkowników czy funkcjonowanie koszyka na zakupy. Oprócz tego dowiesz się, czym są wyjątki,

Bardziej szczegółowo

In»ynieria systemów informacyjnych - Adam Krechowicz

In»ynieria systemów informacyjnych - Adam Krechowicz In»ynieria systemów informacyjnych - Adam Krechowicz 1 Serwlety Klasa j zyka Java pozwalaj ca na obsªugiwanie» da«od klientów. 1.1 Serwlet HTTP Klasa pozwala na dynamiczne tworzenie stron internetowych

Bardziej szczegółowo

Aplikacje WWW - laboratorium

Aplikacje WWW - laboratorium Aplikacje WWW - laboratorium PHP. Celem ćwiczenia jest przygotowanie prostej aplikacji internetowej wykorzystującej technologię PHP. Aplikacja pokazuje takie aspekty, obsługa formularzy oraz zmiennych

Bardziej szczegółowo

Zaawansowane aplikacje internetowe

Zaawansowane aplikacje internetowe Zaawansowane aplikacje internetowe AJAX 1 Celem tego laboratorium jest pokazanie moŝliwości technologii AJAX. W ramach ćwiczeń zostanie zbudowana prosta aplikacja, przechwytująca kliknięcia uŝytkownika

Bardziej szczegółowo

Java Database Connectivity

Java Database Connectivity Java Database Connectivity Celem ćwiczenia jest zbudowanie kilku prostych serwletów z użyciem technologii JDBC. Podczas ćwiczenia zbudowane zostaną serwlety ilustrujące podstawowe techniki łączenia się

Bardziej szczegółowo

Instalacja i konfiguracja IIS-a na potrzeby dostępu WEB do aplikacji Wonderware InTouch Machine Edition

Instalacja i konfiguracja IIS-a na potrzeby dostępu WEB do aplikacji Wonderware InTouch Machine Edition Instalacja i konfiguracja IIS-a na potrzeby dostępu WEB do aplikacji Wonderware InTouch Machine Edition Informator Techniczny Wonderware nr 164 27.06.2017 r. INSTALACJA MICROSOFT INTERNET INFORMATION SERVICES

Bardziej szczegółowo

Piotr Laskowski Krzysztof Stefański. Java Servlets

Piotr Laskowski Krzysztof Stefański. Java Servlets Piotr Laskowski Krzysztof Stefański Java Servlets Java Servlets Technologia dynamicznego generowania treści dla aplikacji WWW Wyspecyfikowana przez Sun, obecnie przez Java Community Process Pierwsza formalna

Bardziej szczegółowo

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

Serwery aplikacji. mgr Radosław Matusik. Wydział Matematyki i Informatyki Uniwersytetu Łódzkiego www.math.uni.lodz.pl/ radmat radmat@math.uni.lodz. Wydział Matematyki i Informatyki Uniwersytetu Łódzkiego www.math.uni.lodz.pl/ radmat radmat@math.uni.lodz.pl Serwer aplikacji Serwer aplikacji to: Serwer wchodzący w skład sieci komputerowej, przeznaczony

Bardziej szczegółowo

Testowanie podstawowej konfiguracji serwera w środowisku NetBeans

Testowanie podstawowej konfiguracji serwera w środowisku NetBeans WDIS: Apache Tomcat 7.0.34 NetBeans 7.3.1. Zajęcia 1 strona - 1 TESTOWANIE SERWERA TOMCAT FUNDACJI APACHE Testowanie podstawowej konfiguracji serwera w środowisku NetBeans 1. Uruchom środowisko NetBeans

Bardziej szczegółowo

1 Wprowadzenie do J2EE

1 Wprowadzenie do J2EE Wprowadzenie do J2EE 1 Plan prezentacji 2 Wprowadzenie do Java 2 Enterprise Edition Aplikacje J2EE Serwer aplikacji J2EE Główne cele V Szkoły PLOUG - nowe podejścia do konstrukcji aplikacji J2EE Java 2

Bardziej szczegółowo

Java EE: Serwlety i filtry serwletów

Java EE: Serwlety i filtry serwletów Java EE: Serwlety i filtry serwletów Do realizacji projektu potrzebne jest zintegrowane środowisko programistyczne NetBeans 6.9 Celem ćwiczenia jest przedstawienie podstawowej technologii platformy Java

Bardziej szczegółowo

Wzorce prezentacji internetowych

Wzorce prezentacji internetowych Wzorce prezentacji internetowych 1. Model kontrolera widoku (Model View Controller). 2. Kontroler strony (Page Controller). 3. Kontroler fasady (Front Controller). 4. Szablon widoku (Template View). 5.

Bardziej szczegółowo

Programowanie w języku Java

Programowanie w języku Java Programowanie w języku Java Wykład 6: Programowanie rozproszone: Servlety, JSP JEE warstwa WWW Programowanie w języku Java 2 1 Interakcje serwer-klient Programowanie w języku Java 3 Technologie warstwy

Bardziej szczegółowo

Instrukcja 10 Laboratorium 13 Testy akceptacyjne z wykorzystaniem narzędzia FitNesse

Instrukcja 10 Laboratorium 13 Testy akceptacyjne z wykorzystaniem narzędzia FitNesse Instrukcja 10 Laboratorium 13 Testy akceptacyjne z wykorzystaniem narzędzia FitNesse 1 Cel laboratorium: Nabycie umiejętności przygotowywania testów akceptacyjnych za pomocą narzędzia FitNesse 1. Wg wskazówek

Bardziej szczegółowo

Wprowadzenie do projektu QualitySpy

Wprowadzenie do projektu QualitySpy Wprowadzenie do projektu QualitySpy Na podstawie instrukcji implementacji prostej funkcjonalności. 1. Wstęp Celem tego poradnika jest wprowadzić programistę do projektu QualitySpy. Będziemy implementować

Bardziej szczegółowo

Zaawansowane aplikacje internetowe laboratorium

Zaawansowane aplikacje internetowe laboratorium Zaawansowane aplikacje internetowe laboratorium Web Services (część 1). Celem ćwiczenia jest przygotowanie prostej aplikacji internetowej wykorzystującej technologię usług sieciowych (ang. Web Services).

Bardziej szczegółowo

Programowanie komponentowe. Przykład 1 Bezpieczeństwo wg The Java EE 5 Tutorial Autor: Zofia Kruczkiewicz

Programowanie komponentowe. Przykład 1 Bezpieczeństwo wg The Java EE 5 Tutorial Autor: Zofia Kruczkiewicz Programowanie komponentowe Przykład 1 Bezpieczeństwo wg The Java EE 5 Tutorial Autor: Zofia Kruczkiewicz Struktura wykładu 1. Utworzenie użytkowników i ról na serwerze aplikacji Sun Java System Application

Bardziej szczegółowo

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

Programowanie w Sieci Internet JSP ciąg dalszy. Kraków, 9 stycznia 2015 r. mgr Piotr Rytko Wydział Matematyki i Informatyki Programowanie w Sieci Internet JSP ciąg dalszy Kraków, 9 stycznia 2015 r. mgr Piotr Rytko Wydział Matematyki i Informatyki Co dziś będziemy robić JSP tags, Używanie tagów, Custom tags, JSP objests, Obiekty

Bardziej szczegółowo

timetrack Przewodnik Użytkownika timetrack Najważniejsze Funkcje

timetrack Przewodnik Użytkownika timetrack Najważniejsze Funkcje timetrack Przewodnik Użytkownika timetrack jest łatwą w obsłudze aplikacją, stworzoną do rejestracji czasu. Pozwala ona na zapisywanie czasu spędzonego z klientami oraz podczas pracy nad projektami i zadaniami

Bardziej szczegółowo

Aplikacje WWW - laboratorium

Aplikacje WWW - laboratorium Aplikacje WWW - laboratorium JavaServer Faces Celem ćwiczenia jest przygotowanie aplikacji internetowej z wykorzystaniem technologii JSF. Prezentowane ćwiczenia zostały wykonane w środowisku Oracle JDeveloper

Bardziej szczegółowo

Programowanie wielowarstwowe i komponentowe

Programowanie wielowarstwowe i komponentowe Programowanie wielowarstwowe i komponentowe JSF 2 wprowadzenie Konfiguracja Eclipse - dodanie szablonu XHTML dla potrzeb JSF 1. Otwórz menu Window/Preferences. Następnie z drzewka wybierz Web/HTML Files/Editor/Templates.

Bardziej szczegółowo

Wprowadzenie do Doctrine ORM

Wprowadzenie do Doctrine ORM Wprowadzenie do Doctrine ORM Przygotowanie środowiska Do wykonania ćwiczenia konieczne będzie zainstalowanie narzędzia Composer i odpowiednie skonfigurowanie Netbeans (Tools->Options->Framework & Tools->Composer,

Bardziej szczegółowo

Programowanie obiektowe

Programowanie obiektowe Programowanie obiektowe Laboratorium 1. Wstęp do programowania w języku Java. Narzędzia 1. Aby móc tworzyć programy w języku Java, potrzebny jest zestaw narzędzi Java Development Kit, który można ściągnąć

Bardziej szczegółowo

Modele danych walidacja widoki zorientowane na model

Modele danych walidacja widoki zorientowane na model Modele danych walidacja widoki zorientowane na model 1. Wprowadzenie Modele danych Modele danych w ASP.NET MVC to klasy znajdujące się w katalogu Models. Ich zadaniem jest mapowanie danych przesyłanych

Bardziej szczegółowo

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

Programowanie w Sieci Internet filtry oraz web.xml. Kraków, 11 stycznia 2013 r. mgr Piotr Rytko Wydział Matematyki i Informatyki Programowanie w Sieci Internet filtry oraz web.xml Kraków, 11 stycznia 2013 r. mgr Piotr Rytko Wydział Matematyki i Informatyki Co dziś będziemy robić Filtry, wywoływanie filtrów, wywołania łańcuchowe

Bardziej szczegółowo

znajdowały się różne instrukcje) to tak naprawdę definicja funkcji main.

znajdowały się różne instrukcje) to tak naprawdę definicja funkcji main. Część XVI C++ Funkcje Jeśli nasz program rozrósł się już do kilkudziesięciu linijek, warto pomyśleć o jego podziale na mniejsze części. Poznajmy więc funkcje. Szybko się przekonamy, że funkcja to bardzo

Bardziej szczegółowo

Serwis jest dostępny w internecie pod adresem www.solidnyserwis.pl. Rysunek 1: Strona startowa solidnego serwisu

Serwis jest dostępny w internecie pod adresem www.solidnyserwis.pl. Rysunek 1: Strona startowa solidnego serwisu Spis treści 1. Zgłoszenia serwisowe wstęp... 2 2. Obsługa konta w solidnym serwisie... 2 Rejestracja w serwisie...3 Logowanie się do serwisu...4 Zmiana danych...5 3. Zakładanie i podgląd zgłoszenia...

Bardziej szczegółowo

Programowanie Multimediów. Programowanie Multimediów JAVA. wprowadzenie do programowania (3/3) [1]

Programowanie Multimediów. Programowanie Multimediów JAVA. wprowadzenie do programowania (3/3) [1] JAVA wprowadzenie do programowania (3/3) [1] Czym jest aplikacja Java Web Start? Aplikacje JAWS są formą pośrednią pomiędzy apletami a aplikacjami Javy. Nie wymagają do pracy przeglądarki WWW, jednak mogą

Bardziej szczegółowo

PHP: bloki kodu, tablice, obiekty i formularze

PHP: bloki kodu, tablice, obiekty i formularze 1 PHP: bloki kodu, tablice, obiekty i formularze SYSTEMY SIECIOWE Michał Simiński 2 Bloki kodu Blok if-else Switch Pętle Funkcje Blok if-else 3 W PHP blok if i blok if-else wyglądają tak samo i funkcjonują

Bardziej szczegółowo

Rozdział 4 KLASY, OBIEKTY, METODY

Rozdział 4 KLASY, OBIEKTY, METODY Rozdział 4 KLASY, OBIEKTY, METODY Java jest językiem w pełni zorientowanym obiektowo. Wszystkie elementy opisujące dane, za wyjątkiem zmiennych prostych są obiektami. Sam program też jest obiektem pewnej

Bardziej szczegółowo

Aplikacje internetowe - laboratorium

Aplikacje internetowe - laboratorium Aplikacje internetowe - laboratorium PHP Celem ćwiczenia jest przygotowanie prostej aplikacji internetowej opartej o język PHP. Aplikacja ilustruje takie mechanizmy jak: obsługa formularzy oraz obsługa

Bardziej szczegółowo

b) Jako nazwę projektu wpisz SerwletyJSPJSTL. Nie zmieniaj wartości pozostałych opcji. Kliknij przycisk Next >.

b) Jako nazwę projektu wpisz SerwletyJSPJSTL. Nie zmieniaj wartości pozostałych opcji. Kliknij przycisk Next >. Serwlety, JSP, JSTL Do realizacji projektu potrzebne jest zintegrowane środowisko programistyczne NetBeans 7 (zrzuty ekranów pochodzą z wersji 7.0.1). Celem ćwiczenia jest wprowadzenie do podstawowych

Bardziej szczegółowo

Podstawy JavaScript ćwiczenia

Podstawy JavaScript ćwiczenia Podstawy JavaScript ćwiczenia Kontekst:

Bardziej szczegółowo

Laboratorium 7 Blog: dodawanie i edycja wpisów

Laboratorium 7 Blog: dodawanie i edycja wpisów Laboratorium 7 Blog: dodawanie i edycja wpisów Dodawanie nowych wpisów Tworzenie formularza Za obsługę formularzy odpowiada klasa Zend_Form. Dla każdego formularza w projekcie tworzymy klasę dziedziczącą

Bardziej szczegółowo

Zaawansowane aplikacje WWW - laboratorium

Zaawansowane aplikacje WWW - laboratorium Zaawansowane aplikacje WWW - laboratorium Przetwarzanie XML (część 2) Celem ćwiczenia jest przygotowanie aplikacji, która umożliwi odczyt i przetwarzanie pliku z zawartością XML. Aplikacja, napisana w

Bardziej szczegółowo

Platforma e-learningowa

Platforma e-learningowa Dotyczy projektu nr WND-RPPD.04.01.00-20-002/11 pn. Wdrażanie elektronicznych usług dla ludności województwa podlaskiego część II, administracja samorządowa realizowanego w ramach Decyzji nr UDA- RPPD.04.01.00-20-002/11-00

Bardziej szczegółowo

uczyć się bez zagłębiania się w formalnym otoczeniu,

uczyć się bez zagłębiania się w formalnym otoczeniu, CZĘŚĆ 3 - INTERNET 3.1 WSTĘP Internet jest globalnym zbiorem połączonych ze sobą komputerów, które przesyłają informacje między sobą za pośrednictwem szybkich połączeń sieciowych oraz linii telefonicznych.

Bardziej szczegółowo

Instalacja i konfiguracja IIS-a na potrzeby dostępu WEBowego/Secure

Instalacja i konfiguracja IIS-a na potrzeby dostępu WEBowego/Secure Instalacja i konfiguracja IIS-a na potrzeby dostępu WEBowego/Secure Viewer-a do aplikacji Wonderware InTouch Machine Edition Informator Techniczny Wonderware nr 164 27.06.2017 r. INSTALACJA MICROSOFT INTERNET

Bardziej szczegółowo

Java wybrane technologie spotkanie nr 5. Java Server Pages

Java wybrane technologie spotkanie nr 5. Java Server Pages Java wybrane technologie spotkanie nr 5 Java Server Pages 1 Składnia dowolny HTML (template) 2

Bardziej szczegółowo

Architektury Usług Internetowych. Laboratorium 2. Usługi sieciowe

Architektury Usług Internetowych. Laboratorium 2. Usługi sieciowe Architektury Usług Internetowych Laboratorium 2. Usługi sieciowe Wstęp Celem laboratorium jest zapoznanie się z modelem usług sieciowych na przykładzie prostego serwera Apache Axis2. Apache Axis2 Apache

Bardziej szczegółowo

Instrukcja użytkownika

Instrukcja użytkownika Instrukcja użytkownika ul. Zawalna 1/5 51-118 Wrocław e-mail: biuro@innotechtion.pl www.innotechtion.pl Spis treści 1 Instalacja oprogramowania SMS Studio...2 2 Pierwsze uruchomienie... 4 2.1 Rejestracja...

Bardziej szczegółowo

Przegląd technologii JSP

Przegląd technologii JSP Marcin Paszkowski Czego potrzebujemy? Przegląd technologii JSP Do obsługi serwletów oraz JSP używamy kontenera. Czym on jest? Zapewnia on prosty mechanizm komunikacji pomiędzy serwletami a serwerem www.

Bardziej szczegółowo

Tomasz Greszata - Koszalin

Tomasz Greszata - Koszalin T: Konfiguracja usługi HTTP w systemie Windows. Zadanie1: Odszukaj w serwisie internetowym Wikipedii informacje na temat protokołów HTTP oraz HTTPS i oprogramowania IIS (ang. Internet Information Services).

Bardziej szczegółowo

Java pierwszy program w Eclipse «Grzegorz Góralski strona własna

Java pierwszy program w Eclipse «Grzegorz Góralski strona własna Strona 1 z 9 «Przykładowe zadania do cz. III ćwiczeń z genetyki Java pierwsze kroki w programowaniu (01)» Kategoria: java, Tagi: eclipse - java - programowanie. Autor: Grzegorz, napisał dnia: February

Bardziej szczegółowo

Uruchamianie bazy PostgreSQL

Uruchamianie bazy PostgreSQL Uruchamianie bazy PostgreSQL PostgreSQL i PostGIS Ten przewodnik może zostać pobrany jako PostgreSQL_pl.odt lub PostgreSQL_pl.pdf Przejrzano 10.09.2016 W tym rozdziale zobaczymy, jak uruchomić PostgreSQL

Bardziej szczegółowo

PekaoBIZNES 24 Szybki START. Przewodnik dla Użytkowników z dostępem podstawowym

PekaoBIZNES 24 Szybki START. Przewodnik dla Użytkowników z dostępem podstawowym PekaoBIZNES 24 Szybki START Przewodnik dla Użytkowników z dostępem podstawowym Podręcznik przygotowany na potrzeby wdrożenia systemu w zborach i obwodach Świadków Jehowy ZAWARTOŚĆ PRZEWODNIKA Niniejszy

Bardziej szczegółowo

Zaawansowane aplikacje internetowe - laboratorium

Zaawansowane aplikacje internetowe - laboratorium Zaawansowane aplikacje internetowe - laboratorium Web Services (część 3). Do wykonania ćwiczeń potrzebne jest zintegrowane środowisko programistyczne Microsoft Visual Studio 2005. Ponadto wymagany jest

Bardziej szczegółowo

Podstawowe wykorzystanie Hibernate

Podstawowe wykorzystanie Hibernate Podstawowe wykorzystanie Hibernate Cel Wykonanie prostej aplikacji webowej przedstawiającą wykorzystanie biblioteki. Aplikacja sprawdza w zależności od wybranej metody dodaje, nową pozycje do bazy, zmienia

Bardziej szczegółowo

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

PLAN WYNIKOWY PROGRAMOWANIE APLIKACJI INTERNETOWYCH. KL IV TI 6 godziny tygodniowo (6x15 tygodni =90 godzin ), PLAN WYNIKOWY PROGRAMOWANIE APLIKACJI INTERNETOWYCH KL IV TI 6 godziny tygodniowo (6x15 tygodni =90 godzin ), Program 351203 Opracowanie: Grzegorz Majda Tematyka zajęć 2. Przygotowanie środowiska pracy

Bardziej szczegółowo

Korzystanie z edytora zasad grupy do zarządzania zasadami komputera lokalnego w systemie Windows XP

Korzystanie z edytora zasad grupy do zarządzania zasadami komputera lokalnego w systemie Windows XP Korzystanie z edytora zasad grupy do zarządzania zasadami komputera lokalnego w systemie Windows XP W tym opracowaniu opisano, jak korzystać z edytora zasad grupy do zmiany ustawień zasad lokalnych dla

Bardziej szczegółowo

8. Listy wartości, dodatkowe informacje dotyczące elementów i przycisków

8. Listy wartości, dodatkowe informacje dotyczące elementów i przycisków 8. Listy wartości, dodatkowe informacje dotyczące elementów i przycisków 1. Jak wspomnieliśmy wcześniej, nie można wymagać od użytkowników, znajomości wszystkich identyfikatorów prowadzących, wykonawców

Bardziej szczegółowo

BACKUP BAZ DANYCH FIREBIRD

BACKUP BAZ DANYCH FIREBIRD BACKUP BAZ DANYCH FIREBIRD SPIS TREŚCI Informacje ogólne... 2 Tworzenie projektu... 2 Krok 1: Informacje podstawowe... 2 Krok 2: Dane... 3 Backup bazy umieszczonej na serwerze... 3 Bezpośredni backup pliku

Bardziej szczegółowo

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

Serwlety. Co to jest serwlet? Przykładowy kod serwletu. Po co są serwlety? Serwlety Co to jest serwlet? kawałek kodu w Javie po stronie serwera HTTP rozszerza moŝliwośći serwera CGI, w Javie, wzbogacone o biblioteki ułatwiające Ŝycie programiście (np. utrzymywanie sesji, wpólne

Bardziej szczegółowo

Poradnik zetula.pl. Jak założyć konto na zetula.pl. i zabezpieczyć dane na swoim komputerze?

Poradnik zetula.pl. Jak założyć konto na zetula.pl. i zabezpieczyć dane na swoim komputerze? Poradnik zetula.pl Jak założyć konto na zetula.pl i zabezpieczyć dane na swoim komputerze? 1.Wejdź na stronę www.zetula.pl 2.Kliknij na odnośniku Utwórz nowe konto 3.Wypełnij formularz rejestracyjny. Pola

Bardziej szczegółowo

prepared by: pawel@kasprowski.pl Programowanie WWW Model-View-Controller

prepared by: pawel@kasprowski.pl Programowanie WWW Model-View-Controller Programowanie WWW Model-View-Controller Przypomnienie problemu Aplikacja do liczenia kredytów Klasa Kredyt Formatka do wprowadzania danych (czysty HTML) Skrypt liczący ratę (JSP wykorzystujące klasę Kredyt)

Bardziej szczegółowo

etrader Pekao Podręcznik użytkownika Strumieniowanie Excel

etrader Pekao Podręcznik użytkownika Strumieniowanie Excel etrader Pekao Podręcznik użytkownika Strumieniowanie Excel Spis treści 1. Opis okna... 3 2. Otwieranie okna... 3 3. Zawartość okna... 4 3.1. Definiowanie listy instrumentów... 4 3.2. Modyfikacja lub usunięcie

Bardziej szczegółowo

Laboratorium - Monitorowanie i zarządzanie zasobami systemu Windows XP

Laboratorium - Monitorowanie i zarządzanie zasobami systemu Windows XP 5.0 5.3.3.7 Laboratorium - Monitorowanie i zarządzanie zasobami systemu Windows XP Wprowadzenie Wydrukuj i uzupełnij to laboratorium. W tym laboratorium, będziesz korzystać z narzędzi administracyjnych

Bardziej szczegółowo

IIIIIIIIIIIIIIIMMIMMIII

IIIIIIIIIIIIIIIMMIMMIII IIIIIIIIIIIIIIIMMIMMIII O programie Program Itelix itender Manager przeznaczony jest do zarządzania zapytaniami ofertowymi przesyłanymi za pomocą poczty elektronicznej przez firmy korzystające z systemu

Bardziej szczegółowo

Wykład 03 JavaScript. Michał Drabik

Wykład 03 JavaScript. Michał Drabik Wykład 03 JavaScript Michał Drabik Język programowania wykorzystywany na stronach internetowych głównie w celu umożliwienia interakcji z użytkownikiem. Kod JavaScript może być umieszczany w kodzie XHTML

Bardziej szczegółowo

Włączanie/wyłączanie paska menu

Włączanie/wyłączanie paska menu Włączanie/wyłączanie paska menu Po zainstalowaniu przeglądarki Internet Eksplorer oraz Firefox domyślnie górny pasek menu jest wyłączony. Czasem warto go włączyć aby mieć szybszy dostęp do narzędzi. Po

Bardziej szczegółowo

Serwery aplikacji. dr Radosław Matusik. radmat

Serwery aplikacji. dr Radosław Matusik.   radmat www.math.uni.lodz.pl/ radmat EL - Expression Language Załóżmy, że mamy klasę Pracownik, której atrybutem jest PESEL. Załóżmy dalej, że w atrybucie sesji zalogowany przechowujemy obiekt aktualnie zalogowanego

Bardziej szczegółowo

Java wybrane technologie spotkanie nr 3. Serwlety

Java wybrane technologie spotkanie nr 3. Serwlety Java wybrane technologie spotkanie nr 3 Serwlety 1 Klient-Serwer Odpowiedzialność serwera przyjmowanie żądań od klienta przygotowywanie odpowiedzi statyczna dynamiczna Rodzaje odpowiedzi statyczna dynamiczna

Bardziej szczegółowo

Palety by CTI. Instrukcja

Palety by CTI. Instrukcja Palety by CTI Instrukcja Spis treści 1. Logowanie... 3 2. Okno główne programu... 4 3. Konfiguracja... 5 4. Zmiana Lokalizacji... 6 5. Nowa Paleta z dokumentu MMP... 8 6. Realizacja Zlecenia ZW... 10 7.

Bardziej szczegółowo

Aplikacja webowa w Javie szybkie programowanie biznesowych aplikacji Spring Boot + Vaadin

Aplikacja webowa w Javie szybkie programowanie biznesowych aplikacji Spring Boot + Vaadin Aplikacja webowa w Javie szybkie programowanie biznesowych aplikacji Spring Boot + Vaadin Czym jest Spring Boot? Spring Boot jest szkieletem aplikacji, opiera się o Spring Framework czyli Framework szeroko

Bardziej szczegółowo

Ćwiczenie: JavaScript Cookies (3x45 minut)

Ćwiczenie: JavaScript Cookies (3x45 minut) Ćwiczenie: JavaScript Cookies (3x45 minut) Cookies niewielkie porcje danych tekstowych, które mogą być przesyłane między serwerem a przeglądarką. Przeglądarka przechowuje te dane przez określony czas.

Bardziej szczegółowo

Java jako język programowania

Java jako język programowania Java jako język programowania Interpretowany programy wykonują się na wirtualnej maszynie (JVM Java Virtual Machine) Składnia oparta o język C++ W pełni zorientowany obiektowo (wszystko jest obiektem)

Bardziej szczegółowo

Wybrane działy Informatyki Stosowanej

Wybrane działy Informatyki Stosowanej Wybrane działy Informatyki Stosowanej JSP - Java Server Pages dr hab. inż. Andrzej Czerepicki a.czerepicki@wt.pw.edu.pl http://www2.wt.pw.edu.pl/~a.czerepicki 2019 Aplikacje i skrypty WWW klasyfikacja

Bardziej szczegółowo

ASP.NET MVC. Podstawy. Zaawansowane programowanie internetowe Instrukcja nr 3

ASP.NET MVC. Podstawy. Zaawansowane programowanie internetowe Instrukcja nr 3 3 ASP.NET MVC Podstawy 1 1. Cel zajęć Celem zajęć jest zapoznanie się z podstawami ASP.NET MVC 2.0 Framework. 2. Zadanie Proszę zbudować prostą aplikację WWW przy zastosowaniu framework a ASP.NET MVC 2.0

Bardziej szczegółowo

Klient poczty elektronicznej - Thunderbird

Klient poczty elektronicznej - Thunderbird Klient poczty elektronicznej - Thunderbird Wstęp Wstęp Klient poczty elektronicznej, to program który umożliwia korzystanie z poczty bez konieczności logowania się na stronie internetowej. Za jego pomocą

Bardziej szczegółowo

APLIKACJA SHAREPOINT

APLIKACJA SHAREPOINT APLIKACJA SHAREPOINT Spis treści 1. Co to jest SharePoint?... 2 2. Tworzenie nowej witryny SharePoint (obszar roboczy)... 2 3. Gdzie znaleźć utworzone witryny SharePoint?... 3 4. Personalizacja obszaru

Bardziej szczegółowo

JAX-RS czyli REST w Javie. Adam Kędziora

JAX-RS czyli REST w Javie. Adam Kędziora JAX-RS czyli REST w Javie Adam Kędziora Webservice Usługa sieciowa (ang. web service) komponent programowy niezależny od platformy i implementacji, dostarczający określonej funkcjonalności. SOAP,UDDI,XML,WSDL

Bardziej szczegółowo

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

Java wybrane technologie spotkanie nr 4. Serwlety c.d. Java wybrane technologie spotkanie nr 4 Serwlety c.d. 1 Wprowadzenie Narzucona struktura katalogów aplikacji (większa przenośności) webapps -app1 -app2 -app3 (root) -*.html, *.gif, *.js, *.css (być może

Bardziej szczegółowo

Instrukcja wczytywania i przekazywania zbiorów centralnych w Centralnej Aplikacji Statystycznej (CAS) przez użytkowników podobszaru PS

Instrukcja wczytywania i przekazywania zbiorów centralnych w Centralnej Aplikacji Statystycznej (CAS) przez użytkowników podobszaru PS Instrukcja wczytywania i przekazywania zbiorów centralnych w Centralnej Aplikacji Statystycznej (CAS) przez użytkowników podobszaru PS Uwaga! Opisane w niniejszej instrukcji funkcje Centralnej Aplikacji

Bardziej szczegółowo

Aplikacje internetowe - laboratorium

Aplikacje internetowe - laboratorium Aplikacje internetowe - laboratorium Administracja serwerem aplikacji. Celem ćwiczenia jest zainstalowanie i administracja prostym serwerem aplikacji. Ćwiczenie zostanie wykonane przy użyciu popularnego

Bardziej szczegółowo