Przegląd innych rozwiązań szkieletowych dla J2EE

Transkrypt

Przegląd innych rozwiązań szkieletowych dla J2EE
420
Przegląd innych rozwiązań
szkieletowych dla J2EE
421
Plan prezentacji
•
•
•
•
WebWork
Tapestry
Turbine
AppFuse
422
WebWork
423
WebWork
• 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
424
Architektura WebWork
odbiera żądania
przeglądarki
(element gotowy)
przekazuje odpowiedź
do przeglądarki
ServletDispatcher
Result View
WebWork2
przechwytuje żądanie
i odpowiedź
Interceptor1
Interceptor2
obsługuje żądanie,
generuje
odpowiedź
Action
xwork.xml
plik konfiguracyjny, opis ścieżek nawigacyjnych
XWork
425
Architektura WebWork: Action
•
•
•
•
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
426
Architektura WebWork: Action
• 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
String greeting;
dostęp do
danych modelu
public String getGreeting() {
return greeting;
}
metoda obsługi
żądania
public String execute() throws Exception {
greeting = "Hello World!";
return SUCCESS;
}
}
sygnał nawigacyjny
427
Architektura WebWork: Action
• 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 class Akcja1 implements Action {
public Pracownik getPracownik(){}
public setLastName(...){}
public setPracownik(...){}
}
}
public class Pracownik {
public String getFirstName(){}
public setFirstName(...){}
public String getLastName(){}
public setLastName(...){}
}
428
Architektura WebWork: Result View
• 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>
greetings.jsp
biblioteka znaczników
WebWork do użycia
w JSP
wyświetla dane modelu powiązanego
z obsługą żądania
429
Architektura WebWork: Result View
• 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.
430
Architektura WebWork: Interceptor
• 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()
431
Architektura WebWork: Interceptor
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
432
Architektura WebWork: Interceptor
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
433
Architektura WebWork: plik xwork.xml
• 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
http://.../hello.action
ServletDispatcher
xwork.xml
LoggingInterceptor.before()
HelloWorldAction.execute()
HelloWorldAction.getGreetings()
success
LoggingInterceptor.after()
success
greetings.jsp
434
435
Walidacja parametrów wywołania
• 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
436
Walidacja parametrów wywołania
Deklaratywna walidacja parametrów wywołania
<validators>
nazwa parametru wywołania
<field name="username">
<field-validator type="requiredstring">
<message>Podaj nazwę użytkownika!</message>
reguła walidacji
</field-validator>
</field>
komunikat
<field name="confirm">
wyświetlany w
<field-validator type="fieldexpression">
przypadku
<param name="expression">
naruszenia
confirm == password.equals(confirm)
reguły walidacji
</param>
<message>Niepoprawne hasło!</message>
</field-validator>
</field>
</validators>
<nazwa_klasy_Action>-validation.xml
437
Język wyrażeń OGNL
• OGNL: Object Graph Navigation Language
• Język wyrażeń opracowywany w ramach projektu Open
Source - www.ognl.org
• Przykłady:
Wyrażenie OGNL
Wynik
employee.name
getEmployee().getName()
name.toString
getName().toString()
employee.categories[0]
Pierwszy element kolekcji categories
stanowiącej atrybut obiektu employee
name in {null, "abc"}
name ma warość nul lub "abc"
categories.{name}
na każdym elemencie kolekcji categories
wywołuje metodę getName(), zwraca
nową kolekcję wyników
438
Tapestry
439
Tapestry
• 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
440
Elementy Model-View-Controller
• 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)
441
Przykładowa aplikacja
Strona formularza
Strona wyników
442
Przykładowa aplikacja
V
specyfikacja
strony
V
strona
formularza
C
specyfikacja
strony
strona
wyniku
C
M
klasa obsługi
strony wyniku
klasa modelu dla
strony wyniku
M
klasa obsługi
strony formularza
zintegrowana z modelem
443
Przykładowa aplikacja
Kod źródłowy strony formularza
<html>
<body>
Wyrażenie warunkowe w języku OGNL
<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
Nazwy typów komponentów
wbudowanych
</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>
Nazwa właściwości strony
skojarzonej z polem
444
Przykładowa aplikacja
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)
445
Przykładowa aplikacja
Klasa obsługi strony formularza
public abstract class Gielda extends BasePage {
public abstract String getError();
public abstract void setError(String error);
public abstract String getSymbol();
public abstract void setSymbol(String symbol);
Metody dostępowe
dla właściwości
strony (abstract wygeneruje je
Tapestry)
public void formSubmit(IRequestCycle cycle) {
String symbol = getSymbol();
if (symbol == null || symbol.trim().length() == 0) {
setError("Wprowadź symbol waloru");
return; }
try {
<form jwcid="@Form"
listener="ognl:listeners.formSubmit">
Walor quote = ...;
PokazWalor pokazWalor = (PokazWalor)
cycle.getPage("PokazWalor");
pokazWalor.setQuote(quote);
cycle.activate(pokazWalor);
Przygotowanie i skok do strony
wyświetlającej wyniki
} catch (Exception e) {setError("Niepoprawny kod waloru");}
}
446
Przykładowa aplikacja
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>
447
Przykładowa aplikacja
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);
}
448
Tapestry - pozostałe własności
• 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)
449
Jakarta Turbine
Jakarta Turbine
Web Application Framework
450
• 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
451
Technologie składowe Turbine
• 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
452
Model MVC w Turbine
• 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
453
• 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!
454
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
maven -g
__ __
| \/ |__ _Apache__ ___
| |\/| / _` \ V / -_) ' \ ~ intelligent projects ~
|_| |_\__,_|\_/\___|_||_| v. 1.0.2
Available [Plugins] / Goals
===========================
...
[turbine]
deploy ......................
install-libs ................
setup .......................
sql .........................
war .........................
( NO DEFAULT GOAL )
Deploys the Application ...
updates the libraries ...
Setup a new Turbine web application
Build the SQL files ...
Generate a Turbine based Web application (war)
455
Tworzenie aplikacji startowej (2/3)
• 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
456
Tworzenie aplikacji startowej (3/3)
• 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)
457
Rozbudowa aplikacji - Przykład
• 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>
458
AppFuse
459
AppFuse
• 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

Podobne dokumenty