420 Przegląd d innych rozwiąza zań szkieletowych dla J2EE
Plan prezentacji 421 WebWork Tapestry Turbine AppFuse
WebWork 422
WebWork 423 Technologia szkieletowa ułatwiająca konstrukcję aplikacji J2EE zgodnych z Model-View-Controller Konkurencja dla Struts Swoboda wyboru technologii dla komponentów View WebWork nie jest bezwzględnie uzależnione od J2EE
Architektura WebWork 424 odbiera żądania przeglądarki (element gotowy) przekazuje odpowiedź do przeglądarki ServletDispatcher Result View WebWork2 przechwytuje żądanie i odpowiedź Interceptor1 obsługuje żądanie, generuje odpowiedź Interceptor2 Action XWork xwork.xml plik konfiguracyjny, opis ścieżek nawigacyjnych
Architektura WebWork: Action 425 Klasa Java implementowana przez programistę Implementuje reakcję na żądanie przeglądarki Koordynuje obsługę żądania (Controller) Odbiera parametry wywołania i przekazuje je do komponentów modelu
Architektura WebWork: Action 426 Implementacja: klasa Java implementująca interfejs Action zawiera metodę execute() zawiera metody set/get dla parametrów wywołania import com.opensymphony.xwork.action; public class HelloWorldAction implements Action{ dane modelu dostęp do danych modelu metoda obsługi żądania } String greeting; public String getgreeting() { return greeting; } public String execute() throws Exception { greeting = "Hello World!"; return SUCCESS; } sygnał nawigacyjny
Architektura WebWork: Action 427 Reprezentacja modelu: model zintegrowany z klasą Action model implementowany przez oddzielną klasę public class Akcja1 implements Action { public String getfirstname(){} } public setfirstname(...){} public String getlastname(){} public setlastname(...){} public class Akcja1 implements Action { public Pracownik getpracownik(){} public setpracownik(...){} } public class Pracownik { public String getfirstname(){} public setfirstname(...){} public String getlastname(){} public setlastname(...){} }
Architektura WebWork: Result View 428 Komponent prezentacyjny implementowany przez programistę Dostępne technologie: JavaServer Pages, Velocity, XML, Free Marker, JasperReports Posiada dostęp do danych modelu <%@ taglib prefix="ww" uri="webwork" %> <html> <head> <title>webwork Example</title> </head> <body> <p><ww:property value="greeting"/></p> </body> </html> biblioteka znaczników WebWork do użycia w JSP greetings.jsp wyświetla dane modelu powiązanego z obsługą żądania
Architektura WebWork: Result View 429 Biblioteka znaczników JSP Przykładowe znaczniki: <textfield label="nazwa użytkownika" name="username"/> <password label="hasło" name="password"/> <property value="atrybut"/> <submit value="login"/> <if test="warunek"></if> <iterator value="elementy"></iterator> itd.
Architektura WebWork: Interceptor 430 Klasa Java implementowana przez programistę Wywoływana przed/po obsłudze żądania przez klasę Action Umożliwia filtrowanie, modyfikację, rejestrację, transformację żądań i odpowiedzi Przykłady zastosowań: nawiązywanie połączenia z bazą danych ochrona dostępu do aplikacji Implementacja: klasa Java implementująca interfejs Interceptor zawiera metody intercept(), before(), after()
Architektura WebWork: Interceptor 431 Interceptor implementujący metodę intercept() przechwytuje każde żądanie, jawnie wykonuje kod Action (lub kod kolejnego Interceptora): public class TimerInterceptor implements Interceptor {... public String intercept(actioninvocation dispatcher)...{ long starttime = System.currentTimeMillis(); String result = dispatcher.invoke(); long extime = System.currentTimeMillis() - starttime; log.info("czas wykonania:" + extime + "ms."); return result; } } przechwytuje żądanie wywołuje następny element w łańcuchu przepływu sterowania
Architektura WebWork: Interceptor 432 Interceptor implementujący metody before()/after() jest uruchamiany przed/po wykonaniem kodu Action (lub kolejnego Interceptora). public class LoggingInterceptor extends AbstractInterceptor {... protected void before(actioninvocation invocation)... { log.info("rozpoczęcie obsługi żądania"); } } protected void after(actioninvocation invocation, String result)...{ log.info("zakończenie obsługi żądania); } wywoływane przed przekazaniem żądania do kolejnego elementu w łańcuchu wywoływane po zakończeniu obsługi żądania przez kolejny element w łańcuchu
Architektura WebWork: : plik xwork.xml xml 433 Definiuje strukturę całej aplikacji Zawiera deklaracje klas Action, klas Interceptor, modułów Result View Opisuje ścieżki nawigacyjne <interceptor name="int0" class="logginginterceptor"/> <action name="hello" class="helloworldaction"> <result name="success" type="dispatcher"> <param name="location">/greetings.jsp</param> </result> <interceptor-ref name="debugstack"/> <interceptor-ref name="defaultstack"/> <interceptor-ref name="int0"/> </action> deklaracja klasy Interceptora stos Interceptorów deklaracja klasy Action na sygnał "success" skocz do greetings.jsp
Przykładowa aplikacja: przebieg sterowania 434 http://.../hello.action ServletDispatcher xwork.xml LoggingInterceptor.before() HelloWorldAction.execute() success HelloWorldAction.getGreetings() LoggingInterceptor.after() success greetings.jsp
Walidacja parametrów w wywołania 435 Deklaratywna RequiredString - pole ma wartość o niezerowej długości IntRange - liczba całkowita w zadanym przedziale DateRange - data w zadanym przedziale Email - adres e-mail o poprawnej strukturze URL - adres URL o poprawnej strukturze Expression/FieldExpression - wyrażenie OGNL zwraca true Implementowana za pomocą klas walidatorów Implementowana za pomocą klas Interceptor
Walidacja parametrów w wywołania 436 Deklaratywna walidacja parametrów wywołania <validators> <field name="username"> <field-validator type="requiredstring"> <message>podaj nazwę użytkownika!</message> </field-validator> </field> <field name="confirm"> <field-validator type="fieldexpression"> <param name="expression"> confirm == password.equals(confirm) </param> <message>niepoprawne hasło!</message> </field-validator> </field> </validators> <nazwa_klasy_action>-validation.xml nazwa parametru wywołania reguła walidacji komunikat wyświetlany w przypadku naruszenia reguły walidacji
Język wyrażeń OGNL 437 OGNL: Object Graph Navigation Language Język wyrażeń opracowywany w ramach projektu Open Source - www.ognl.org Przykłady: Wyrażenie OGNL employee.name name.tostring employee.categories[0] name in {null, "abc"} categories.{name} getname().tostring() Wynik getemployee().getname() Pierwszy element kolekcji categories stanowiącej atrybut obiektu employee name ma warość nul lub "abc" na każdym elemencie kolekcji categories wywołuje metodę getname(), zwraca nową kolekcję wyników
Tapestry 438
Tapestry 439 Komponentowe środowisko szkieletowe służące do konstrukcji aplikacji J2EE Rozpowszechniane na zasadach open-source Stara się upodobnić proces tworzenia aplikacji internetowych do procesu tworzenia tradycyjnych aplikacji z graficznym interfejsem użytkownika Wspiera architekturę Model-View-Controller Oparte bezpośrednio na Servlet API
Elementy Model-View View-Controller 440 Komponenty Model: samodzielne klasy Java możliwość integracji z komponentami Controller Komponenty View: szablony HTML wyposażone w specjalne markery służące do osadzania komponentów nie korzysta z JSP Komponenty Controller: specyfikacja strony (XML) - wiąże markery z pozostałymi komponentami (w katalogu WEB-INF) klasa Java implementująca interfejs org.apache.tapestry.ipage - zawiera właściwości strony/modelu (w katalogu WEB-INF/classes)
Strona formularza Przykładowa aplikacja Strona wyników 441
Przykładowa aplikacja 442 V strona formularza specyfikacja strony V strona wyniku specyfikacja strony C M C M klasa obsługi strony formularza zintegrowana z modelem klasa obsługi strony wyniku klasa modelu dla strony wyniku
Kod źródłowy strony formularza <html> <body> Przykładowa aplikacja <h1>notowania giełdowe</h1> <div jwcid="@conditional" condition="ognl:error"> <font color="red"> <span class="error" jwcid="@insert" value="ognl:error"> Błąd!</span> Java Web Component ID: wskazuje <br></font> wzorzec komponentu </div> <form jwcid="@form" listener="ognl:listeners.formsubmit"> Symbol waloru: <input jwcid="@textfield" value="ognl:symbol" size="8"/> <input type="submit" jwcid="@submit" value="szukaj"/> </form> </body> </html> Wyrażenie warunkowe w języku OGNL Nazwy typów komponentów wbudowanych Nazwa właściwości strony skojarzonej z polem 443
Przykładowa aplikacja 444 Plik specyfikacji strony formularza <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE page-specification PUBLIC "-//Apache Software Foundation//Tapestry Specification 3.0//EN" "http://jakarta.apache.org/tapestry/dtd/tapestry_3_0.dtd"> <page-specification class="mypackage.gielda"> <property-specification name="error" type="java.lang.string"/> <property-specification name="symbol" type="java.lang.string"/> </page-specification> Nazwa klasy obsługi strony Nazwa właściwości strony (atrybut klasy obsługi strony)
Klasa obsługi strony formularza Przykładowa aplikacja public abstract class Gielda extends BasePage { public abstract String geterror(); Metody dostępowe dla właściwości public abstract void seterror(string error); strony (abstract - public abstract String getsymbol(); wygeneruje je public abstract void setsymbol(string symbol); Tapestry) public void formsubmit(irequestcycle cycle) { String symbol = getsymbol(); if (symbol == null symbol.trim().length() == 0) { seterror("wprowadź symbol waloru"); return; } <form jwcid="@form" try { listener="ognl:listeners.formsubmit"> Walor quote =...; PokazWalor pokazwalor = (PokazWalor) cycle.getpage("pokazwalor"); pokazwalor.setquote(quote); Przygotowanie i skok do strony cycle.activate(pokazwalor); wyświetlającej wyniki } catch (Exception e) {seterror("niepoprawny kod waloru");} } 445
Przykładowa aplikacja 446 Kod źródłowy strony wyniku <html> <body> <h1> <span jwcid="@insert" value="ognl:quote.spolka">walor</span> </h1> Kurs aktualny: <span jwcid="@insert" value="ognl:quote.kurs"> kurs</span><br> Obrót (tys.zł): <span jwcid="@insert" value="ognl:quote.obrot"> obrót</span><br>... <br> Atrybut klasy obsługi strony wyniku <span jwcid="@pagelink" page="gielda">powrót do formularza</span> </body> </html>
Przykładowa aplikacja 447 Plik specyfikacji strony wyniku <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE page-specification PUBLIC "-//Apache Software Foundation//Tapestry Specification 3.0//EN" "http://jakarta.apache.org/tapestry/dtd/tapestry_3_0.dtd"> <page-specification class="mypackage.pokazwalor"> <property-specification name="quote" type="mypackage.walor"/> </page-specification> Klasa obsługi strony wyniku public abstract class pokazwalor extends BasePage { public abstract Walor getquote(); public abstract void setquote(walor quote); }
Tapestry - pozostałe e własnow asności 448 Walidacja parametrów wywołania, zarówno po stronie serwera, jak i po stronie klienta Internacjonalizacja Narzędzia wspomagające programistę Spindle - plug-in dla Eclipse (http://spindle.sourceforge.net)
Jakarta Turbine 449
Jakarta Turbine Web Application Framework Szkielet aplikacji oparty o technologię serwletów Java W pełni zgodny z J2EE Oparty o model MVC Rozpowszechniany na zasadach Apache Software License Platforma do tworzenia aplikacji, a nie tylko ich uruchamiania Zalety (wg dokumentacji): Łatwa personalizacja stron internetowych Łatwa kontrola dostępu do fragmentów aplikacji Dobry wybór dla aplikacji opartych o architekturę zorientowaną na usługi Usługi implementowane wg wzorca projektowego singleton Jedna instancja usługi w systemie Zbiór predefiniowanych, gotowych do użycia usług, m.in. Zarządzanie użytkownikami i przywilejami File upload Transformacje XSLT 450
Technologie składowe Turbine 451 Velocity dla warstwy prezentacji Podstawowa technologia w Turbine, ale wspierane również JSP Velocity jest jedną z technologii szablonów dla serwletów Java Zapewnia separację kodu Java (serwlet) od kodu HTML (szablon) Torque do obsługi komunikacji z bazą danych Torque powstał jako część projektu Turbine i dalej stanowi naturalny wybór, ale wspierane inne rozwiązania np. Hibernate Torque jest technologią odwzorowania obiektowo-relacyjnego W odróżnieniu od konkurencyjnych rozwiązań, nie korzysta z mechanizmu Java reflection Generuje klasy Java w oparciu o opis schematu bazy danych w formie XML
Model MVC w Turbine 452 Kontroler aplikacji Turbine: serwlet TurbineServlet + Action Event Handlers Akcje uruchamiane są w odpowiedzi na wprowadzenie przez użytkownika danych, które wymagają interakcji z modelem Widok stanowi warstwa prezentacji oparta o Velocity lub JSP Model 2+1 Ulepszony (wg jego twórców) Model 2 Kontroler i widok ściślej ze sobą związane niż w innych implementacjach MVC
Środowiska do tworzenia aplikacji Turbine Typowe środowisko to Apache Maven + Maven Environment for Turbine Applications (M.E.T.A.) Maven = Ant na sterydach, Maven wykorzystuje wtyczki (plug-ins), jedną z nich jest M.E.T.A. Maven oparty o koncepcję repozytoriów archiwów JAR Archiwa zdalne (www.ibiblio.com & mirrors) i lokalne Przy pierwszej kompilacji biblioteki pobierane ze zdalnego repozytorium Konieczność ręcznego ściągnięcia bibliotek SUN-a (względy licencyjne) Istnieje możliwość korzystania z IDE Rozwiązanie testowane na Eclipse Maven generuje projekt dla Eclipse! 453
Tworzenie aplikacji startowej (1/3) Instalacja środowiska projektanckiego Instalacja Apache Maven Pobranie wtyczki M.E.T.A. dla narzędzia Maven maven-turbine-plugin-1.2.jar Biblioteki (JAR) Turbine i pomocnicze zostaną pobrane z sieci przy pierwszej kompilacji aplikacji Turbine Weryfikacja poprawności instalacji 454 maven -g \/ Apache \/ / _` \ V / -_) ' \ ~ intelligent projects ~ _ _\,_ \_/\ _ _ v. 1.0.2 Available [Plugins] / Goals ===========================... [turbine] ( NO DEFAULT GOAL ) deploy... Deploys the Application... install-libs... updates the libraries... setup... Setup a new Turbine web application sql... Build the SQL files... war... Generate a Turbine based Web application (war)
Tworzenie aplikacji startowej (2/3) 455 Utworzenie aplikacji startowej: maven -Dturbine.app.name=helloworld turbine:setup Drzewo katalogów aplikacji: Klasy Java przygotowujące Dane do prezentacji w szablonach Szablony Velocity dla stron aplikacji
Tworzenie aplikacji startowej (3/3) 456 Instalacja aplikacji na serwerze maven turbine:deploy (powoduje wcześniejszą kompilację, co za pierwszym razem może wiązać się ze ściąganiem bibliotek z sieci)
Rozbudowa aplikacji - Przykład 457 Dodanie nowego dynamicznego ekranu do aplikacji Klasa Java helloworld/src/java/org/apache/turbineapp/helloworld/modules/screens/witaj.java public class witaj extends VelocityScreen { public void dobuildtemplate( RunData data, Context context ) { try { context.put( "imie", "Marek" ); } catch( Exception e ) {} } } Szablon Velocity helloworld/src/templates/screens/witaj.vm <h1>witaj $imie!!!</h1> Dodanie linku do nowego ekranu na stronie powitalnej helloworld/src/templates/screens/index.vm <a href="$link.setpage( 'witaj.vm' )">Powitanie</a>
AppFuse 458
AppFuse 459 Zbiór szkieletów aplikacji J2EE opartych na różnych zestawach technologii Struts + Spring + Hibernate JSF + Spring + Hibernate Spring + Hibernate Tapestry + Spring + Hibernate WebWork + Spring + Hibernate Wykorzystanie AppFuse polega na pobraniu aplikacji "startowej" z http://appfuse.dev.java.net/, a następnie jej rozbudowa poprzez implementację własnego kodu Alternatywa dla narzędzi typu "wizard" Skrócenie czasu prototypowania Uproszczenie kompilacji i testowania aplikacji "Lekka" wersja: Equinox = Struts + Spring + Hibernate
460 Piątkowy wyjazd na ćwiczenia! Autokar o godz. 8:30 sprzed budynku ON PAN