SlideShare a Scribd company logo
1 of 106
Download to read offline
Seam Framework w akcji
Szew
●   Miejsce zszycia kawałków tkaniny, futra itp.
    wraz z nićmi, którymi te kawałki zszyto.
●   Operacyjne zszycie tkanek miękkich.
●   Naturalne połączenie dwu przylegających do
    siebie kości spojonych tkanką łączną.
●   Połączenie brzegów przedmiotów metalowych
    za pomocą nitkowania lub spawania.
JSF
      EJB
AJAX
Facelets     JSF       ICEFaces
 GWT         RichFaces                             Drools
    Wicket                                     Spring WebBeans
                                                      JPA
                                                 EJB
                                                    Hibernate

                                                   Guice
                                                           Groovy
                                                 jBMP


               Seam
           one framework to rule them all...
Czym jest Seam?
Stos aplikacji
●   Integruje różne frameworki z różnych warstw
    JEE
    ●   Widoku (JSF, RichFaces, ICEFaces, Wicket)
    ●   Dostępu do danych (JPA, Hibernate)
    ●   i więcej ...
Kontener komponentów
●   Integruje komponenty JPA, EJB, POJO oraz
    JSF w taki sposób, że zaciera granice
    pomiędzy poszczególnymi warstwami i daje
    wrażenie korzystania z jednego kontenera
Komponenty i kontenery


         Kontener                Tworzenie komponentu
EJB                  @Stateful, @Stateless, @MessageDriven, ejb-
                     jar.xml
JSF                  faces-config.xml
Spring               applicationContext.xml
Kontener servletów   web.xml
Komponenty i kontenery


        Kontener                Tworzenie komponentu
EJB                  @Stateful, @Stateless, @MessageDriven, ejb-
                     jar.xml
JSF                  faces-config.xml
Spring               applicationContext.xml
Kontener servletów   web.xml
Seam                 @Name, components.xml
Facelets / RichFaces / JSP



            JSF



           Seam



EJB / Spring / JPA / Hibernate


          Seam context variable
Definiowanie komponentu Seam



1. @Name("foo")
2. @Scope(ScopeType.CONVERSATION)
3. public class Foo { }
Wstrzykiwanie zależności


1. @Name("bar")
2. public class Bar {
3.
4.   @In
5.   private Foo foo;
6.
7. }
Wstrzykiwanie zależności cd...


1. @Name("bar")
2. public class Bar {
3.
4.   @In(create = true)
5.   private Foo foo;
6.
7. }
Wstrzykiwanie zależności cd...


1. @Name("bar")
2. public class Bar {
3.
4.   @In("#{foo}")
5.   private Foo foo;
6.
7. }
Inversion of Control
●   Wzorzec projektowy „rozluźniający” powiązania
    pomiędzy komponentami
●   Pozwala komponentom na skupienie się na
    wykorzystywaniu innych komponentów
    (serwisów) niż ich wyszukiwaniu
●   Wszyscy go dobrze znają...
Inversion of Control
●   Zwykle ludzie mówiąc o IoC mają na myśli
    dependency injection (DI), jeden z przypadków
    użycia IoC
●   Jednakże IoC > DI
DI jest zbyt statyczne

Problem z klasycznym podejściem do DI jest taki,
że wstrzykiwanie zależności odbywa się tylko raz,
tuż po stworzeniu instancji komponentu.
Komponent jest przywiązany do referencji
obiektów wstrzykniętych mu w czasie tworzenia.

Komponenty powinny być świadome swojego
istnienia w kontekście i powinny brać aktywny
udział w zarządzaniu komponentami.
IoC w Seam
●   W Seam mamy do czynienia z dependency
    bijection
●   W Seam zależności są wstrzykiwane
    dynamicznie w czasie życia komponentu, a nie
    tylko podczas jego tworzenia
●   Dependency bijection pozwala na
    wstrzykiwanie zależności do komponentu, jak i
    umieszczanie komponentów w kontekście
●   Bijection = injection + outjection
Bijection
●   Bijection jest to kombinacja injection i outjection
●   Bijection zachodzi w momencie wywołania
    metody (a nie tworzenia komponentu)
    ●   Injection w momencie wywołania metody
    ●   Outjection po powrocie metody
Disinjection
●   Wszystkie pola komponentów do których
    zostały wstrzyknięte zależności otrzymują
    wartość null.
●   Zapobiega wyciekom pamięci
●   Rozwiązuje problem serializacji obiektów
Bijection interceptor
                 Komponent wywołujący
                       metodę



   Interceptor

            Wstrzykiwanie zależności
         w pola oznaczone adnotacją @In




                  Wywołanie metody




        Outjection na polach oznaczonych
                 adnotacją @Out



              Disinjection na polach
           oznaczonych adnotacją @In




                  Powrót z metody
Bijection w akcji
1. @Name("authenticator")
2. public class Authenticator {
3.     @In
4.     private Credentials credentials;
5.
6.     @Out(scope = ScopeType.SESSION, required = false)
7.     private Long currentUserId;
8.
9.     @In(create = true)
10.    private UserQuery userQuery;
11.
12.    public boolean authenticate() {
13.        userQuery.setUsername(credentials.getUsername());
14.        User user = userQuery.getSingleResult();
15.        if (isPasswordValid(credentials.getPassword(), user)) {
16.           currentUserId = user.getId();
17.        }
18.    }
19.
20.    // pozostałe metody
21. }
Inne formy wstrzykiwania zależności
●   @RequestParameter
●   @PersistenceContext
●   @DataModelSelection
●   @DataModelSelectionIndex
Inne formy dependency outjection
●   @DataModel
●   @Factory
●   @Unwrap
Omijanie bijection
●   Wewnętrzne wywołania metod
●   @BypassInterceptors
Generowanie zdarzeń
Zdarzenia
●   Seam posiada wbudowane wsparcie dla
    wzorca observer, który w znacznym stopniu
    pozwala redukować zależności między
    komponentami (budować luźne powiązania)
●   Seam pozwala na generowanie zdarzeń z
    metod jak i ich obsługę z metod komponentów
●   Zdarzenia mogą być generowane na wiele
    sposobów, jak i można generować wiele typów
    zdarzeń (synchroniczne, asynchroniczne,
    czasowe, transakcyjne)
Generowanie zdarzeń



1.   public String register() {
2.       // registration action
3.       Events.instance().raiseEvent("registered");
4.       return "success";
5.   }
Generowanie zdarzeń


1.   @In private Events events;
2.
3.   public String register() {
4.       // registration action
5.       entityManager.persist(newUser);
6.       events.raiseTransactionSuccessEvent(
7.         "registered", newUser);
8.       return "success";
9.   }
Generowanie zdarzeń



1.   @RaiseEvent("registered")
2.   public String register() {
3.       // registration action
4.       return "success";
5.   }
Generowanie zdarzeń


1. <page view-id="/register.xhtml">
2.      <navigation
3.        from-action="#{userManager.register}">
5.          <rule if-outcome="success">
6.              <raise-event type="registered" />
7.              <redirect
8.                view-id="/registered.xhtml" />
9.          </rule>
10.     </navigation>
11. </page>
Obserwowanie zdarzeń

1. @Name("registrationObserver")
2. public class RegistrationObserver {
3.     @Logger private Log logger;
4.
5.     @Observer(value="registered", create=true)
6.     public void onRegisteredEvent(User newUser) {
7.         logger.info("Registered new user: "
8.             + newUser.getUsername());
9.     }
10.
11. }
Obserwowanie zdarzeń



1. <event type="registered">
2.   <action
3.      execute=
4.      "#{registrationObserver.onRegisterEvent(newUser)}"
5.   />
6. </event>
Wbudowane zdarzenia
●   Inicjalizacja kontenera seamowego
●   Przypisanie zmiennej kontekstowej (added,
    removed)
●   Zdarzenia cyklu życia komponentów (created,
    destroyed)
●   Zdarzenia związane z autentykacją
●   Zdarzenia związane z transakcją
●   i wiele innych...
Metody fabrykujące
Metody fabrukujące w Seam
●   Seam posiada wbudowane wsparcie dla
    wzorca factory method
●   Fabryka ma na celu dostarczenie konkretnych
    danych zamiast instancji komponentu
●   Metody fabrykujące oznacza się adnotacją
    @Factory lub w deskryptorze komponentów
●   Metody fabrykujące z założenia mają wypierać
    użycie „getterów”
Metoda fabrykująca jest wykonywana tylko
 raz, kolejne wywołania zwracają utworzoną i
umieszczoną w kontekście wcześniej wartość.
Rezultat wywołania fabryki
●   Rezultat metody fabrykującej może być
    przekazany na trzy sposoby:
    ●   Przez zwrócenie wartości z metody
    ●   Przez outjection (jako, że metoda fabrykująca
        znajduje się w komponencie to działa na nim
        bijection)
    ●   Przez umieszczenie wartości bezpośrednio w
        kontekście
Przykład metody fabrykujacej


1. @Name("currentUserFactory")
2. public void CurrentUserHome {
3.     @In private EntityManager em;
4.
5.     @In private Long currentUserId;
6.
7.     @Factory("currentUser")
8.     public User getCurrentUser() {
9.         return em.find(User.class, currentUserId);
10.    }
11. }
Przykład metody fabrykujacej

1. @Name("currentUserFactory")
2. public void CurrentUserHome {
3.     @In private EntityManager em;
4.
5.     @In private Long currentUserId;
6.
7.     @Out private User currentUser;
8.
9.     @Factory("currentUser")
10.    public User getCurrentUser() {
11.        currentUser =
12.            em.find(User.class, currentUserId);
13.    }
14. }
Unwrap
Unwrap
●   Seam pozwala dostarczać dane do kontekstu
    za pomocą metody oznaczonej adnotacją
    @Unwrap
●   W odróżnieniu od metody fabrykującej taka
    metoda jest wywoływana za każdym razem,
    kiedy komponent pod konkretną nazwą jest
    żądany
@Unwrap a @Factory
●   Jest prawdziwym komponentem
    ●   Można konfigurować w components.xml
    ●   Można używać adnotacji @Create i @Destroy
●   Metoda oznaczona @Unwrap jest wywoływana
    zawsze
●   Komponent może przechowywać stan i
    obserwować zdarzenia
Metody oznaczone @Unwrap można używać jako
               swoisty alias.
@Unwrap w akcji



1.   @Name("org.jboss.seam.faces.facesContext")
2.   @Scope(ScopeType.APPLICATION)
3.   public class FacesContext {
4.       @Unwrap public FacesContext getContext() {
5.           return FacesContext.getCurrentInstance();
6.       }
7.   }
Method interceptors
Interceptory w Seam
●   Seam rozszerza funkcjonalność interceptorów z
    EJB
    ●   Przenosi ją ze świata Java EE to świata POJO
●   Pozwala w deklaratywny sposób dodawać
    logikę AOP
Definiowanie interceptora



1.   @AroundInvoke
2.   public Object methodName(InvocationContext ctx)
3.   throws Exception {
4.       // interceptor logic...
5.       return ctx.proceed();
6.   }
Definiowanie interceptora

1. @Interceptor(stateless = true,
2.     type = InterceptorType.CLIENT
3. public class StatelessInterceptor {
4.
5.     @AroundInvoke
6.     public Object methodName(InvocationContext ctx)
7.     throws Exception {
8.         // interceptor logic...
9.         return ctx.proceed();
10.    }
11.
12. }
Cechy interceptora w Seam
●   Interceptor może być stateful-owy lub stateless-
    owy
●   Interceptory mogą być przypisywane do
    komponentów zarówno po stronie serwera jak i
    klienta
●   Interceptory mogą być przypisywane do klas
    deklaratywnie (stereotypes)
Przypisywanie interceptorów
●   @Interceptors
Przypisywanie interceptorów
●   @Interceptors
●   W Seamie, w odróżnieniu od EJB, adnotacja
    @Interceptors nie jest nakładana na klasy
    komponentów, które chcemy interceptować
●   Adnotacja ta to meta adnotacja którą nakłada
    się na inne adnotacje
Przypisywanie interceptorów


1.   @Target(TYPE)
2.   @Retention(RUNTIME)
3.   @Interceptors(CurrentUserAccessInterceptor.class)
4.   public @interface VerifyCurrentUserAccess {}
5.
6.   @Name("offerAddAction")
7.   @VerifyCurrentUserAccess
8.   public class OfferAddAction { }
Model kontekstowy w Seam
Konteksty w Java Servlet API
●   Request
●   Session
●   Application
Konteksty w Seam
●   Event (request)
●   Page
●   Conversation
●   Session
●   Application
●   Business process
Konteksty w Seam
                       Przeglądarka




Strona 1       Strona 1          Strona 2     Strona 3




event          event             event        event

        page                     page         page

           conversation                     conversation

                       session
Konwersacja
Konwersacja w Seam
●   Pozwala przechowywać stan komponentów
    pomiędzy kolejnymi żądaniami (nawet w
    przypadku występowania przekierowań)
●   Jest bardziej ziarnista niż kontekst sesji
●   W deklaratywny sposób można kontrolować
    zakresy konwersacji (oraz jej propagacje)
●   Na czas konwersacji Seam rozpina transakcje
    (utrzymywana jest sesja połączenia z bazą
    danych)
Konwersacja w Seam została pomyślana jako
     kontekst, który przechowuje stan
   komponentów w ramach konkretnego
            przypadku użycia.
A czemu nie w sesji?
●   Sesja jest zbyt długa i przechowywanie danych
    w tym kontekście może prowadzić do wycieków
    pamięci
●   Sesja jest dzielona pomiędzy karty przeglądarki
●   Sesja nie posiada żadnych mechanizmów
    obronnych przed współbieżnym dostępem do
    danych
●   Błędy występujące przez nieprawidłowe
    wykorzystywanie kontekstu sesji mogą być
    trudne do reprodukcji w środowisku testowym
Mimo wszystko rozwiązanie leży w... sesji. Trzeba
   ją tylko odpowiednio podzielić i zarządzać.
Konwersacja to wydzielony segment
               sesji


           cid = 1   cid = 2




           cid = 3   cid = 4




                         Sesja HTTP
Seam zarządza konwersacją
●   Każda konwersacja posiada określony czas
    trwania (timeout)
●   Każda konwersacja toczy się w izolacji (nie
    trzeba się przejmować synchronizacją)
Wymagania konwersacji
●   Komponenty muszą implementować interfejs
    java.io.Serializable
●   Czas trwania sesji musi być dłuższy niż czas
    trwania konwersacji
Stany konwersacji
●   Tymczasowa (temporary conversation)
●   Długa (long-running conversation)
●   Zagnieżdżona (nested conversation)
Stany konwersacji
●   Tymczasowa (temporary conversation)
●   Długa (long-running conversation)
●   Zagnieżdżona (nested conversation)
Przejścia stanów konwersacji
        brak konwersacji           kontynuacja konwersacji




                           begin


        Temporary                     Long-running


                           end
koniec żądania                        sesja lub konwersacja
                                      wygasła



    Zniszczona                            Zniszczona
Stany długiej konwersacji

        Long-running

             resumed
                   concurrent conversation resumed

begin

                             resumed
            Foreground                     Background


end

         session timeout                   conversation or
                                           session timeout

                           Zniszczona
Definiowanie zakresów długiej konwersacji
Za pomocą adnotacji
1.    @Name("bookingAction")
2.    @Restrict("#{s:hasRole('Customer')}")
3.    public class BookingAction {
4.
5.        @Begin(join = true)
6.        public void fetchRooms() {
7.            // fetching rooms...
8.        }
9.
10.       @End(beforeRedirect = true)
11.       public void confirm() {
12.           // confirm booking...
13.       }
14.
15.       @End(beforeRedirect = true)
16.       public void cancel() {
17.           // cancel booking...
18.       }
19.
20.   }
Za pomocą adnotacji
1.    @Name("roomsFactory")
2.    public void RoomsFactory {
3.        @Begin(join = true)
4.        public void fetchRooms() {
5.            // fetching rooms...
6.        }
7.    }
8.
9.    @Name("bookingAction")
10.   public void BookingAction {
11.       @End(beforeRedirect = true)
12.       public void confirm() {
13.           // confirmation action...
14.       }
15.   }
W deskryptorze strony



1. <page view-id="/booking.xhtml">
2.     <begin-conversation join="true" />
3. </page>
W definicjach nawigacji


1. <page view-id="/booking.xhtml">
2.      <navigation
3.        from-action="#{roomsFactory.fetchRooms}">
4.          <begin-conversation join="true" />
5.      </navigation>
6.
7.      <navigation from-action="#{bookingAction.confirm}">
8.          <end-conversation before-redirect="true" />
9.      </navigation>
10. </page>
Za pomocą komponentów JSF


1.   <s:link view-id="/booking.xhtml" propagation="begin" />
2.
3.   <s:button action="#{bookingAction.confirm}"
4.      propagation="end" />
5.
6.   <h:commandButton action="#{bookingAction.confirm}">
7.       <s:conversationPropagation type="end" />
8.   </h:commandButton>
Zaawansowane zarządzanie stronami w Seam
Cykl JSF


                    JSF Servlet



 Render                                    Restore
Response                                    View


  Invoke                               Apply Request
Application                                Values



           Update Model       Process
              Values         Validations
Cykl JSF (initial request)
                    Przeglądarka



                     JSF Servlet



  Render                                    Restore
 Response                                    View


  Invoke                                Apply Request
Application                                 Values



            Update Model       Process
               Values         Validations
Cykl JSF (postback)
                   Przeglądarka



                    JSF Servlet



 Render                                    Restore
Response                                    View


  Invoke                               Apply Request
Application                                Values



           Update Model       Process
              Values         Validations
Nawigacja w JSF

1. <navigation-rule>
2.    <from-view-id>/login.xhtml</from-view-id>
3.    <navigation-case>
4.      <from-action>
5.        #{authenticator.login}
6.      </from-action>
7.      <from-outcome>loggedIn</from-outcome>
8.      <to-view-id>/home.xhtml</to-view-id>
9.      <redirect/>
10.   </navigation-case>
11. </navigation-rule>
Problemy z JSF
●   Skrócony cykl JSF
    ●   Służy jako dostawca strony
    ●   Zakłada, że nie potrzeba wykonywania żadnej logiki
        przed wyrenderowaniem strony
    ●   Zakłada, że użytkownik posiada uprawnienia do
        żądanego zasobu
●   Zorientowanie na żądania typu POST
●   Mało rozwinięte reguły nawigacji
    ●   Brak możliwości wykorzystania EL w regułach
Seam page descriptor
Do czego służy deskryptor strony
●   Definiowania reguł nawigacji
●   Generowania komunikatów (FacesMessages)
●   Mapowania parametrów URL
●   Dodawania parametrów URL (dla
    przekierowań)
●   Uruchamiania akcji zanim widok zostanie
    wyrenderowany
Do czego służy deskryptor strony
                 cd...
●   Sprawdzania reguł bezpieczeństwa
●   Kontrolowania zakresów konwersacji
●   Kontrolowania zakresów page flow
●   Kontrolowania zakresów procesów
    biznesowych i zadań
●   Wywoływanie eventów
●   Obsługa wyjątków
Deskryptor jest świadomy kontekstu aplikacji
Inteligentna nawigacja w Seam
●   Pozwala użyć dowolnej wartości (dostępnej za
    pomocą EL) do definiowania przekierowań
●   Reguły nawigacji są warunkowe
●   Definiuje jak powinna być propagowana
    konwersacja, czy proces biznesowy
●   Pozwala dodawać komunikaty JSF przed
    wyrenderowaniem strony bądź przekierowaniem
●   Pozwala dodawać parametry URL
●   Pozwala wywoływać eventy
Definiowanie nawigacji


1. <page view-id="/login.xhtml" scheme="https">
2.     <navigation>
3.         <rule if="#{identity.loggedIn}">
4.             <redirect view-id="/home.xhtml" />
5.         </rule>
6.     </navigation>
7. </page>
Definiowanie nawigacji
1. <page view-id="/offer/add.xhtml" login-required="true">
2.      <navigation from-action="#{offerManager.addOffer}">
3.
4.          <rule if-outcome="offerAdded"
5.                if="#{offerManager.addNext}">
                                                         1
6.              <redirect view-id="/offer/add.xhtml" />
7.          </rule>
8.
9.          <rule if-outcome="offerAdded">
10.             <redirect view-id="/offer/list.xhtml">
11.                 <param name="userId"                  2
12.                         value="#{currentUserId}" />
13.             </redirect>
14.         </rule>
15.
16.     </navigation>
17. </page>
Definiowanie nawigacji
1. <page view-id="*">
2.      <navigation from-action="#{identity.logout}">
3.          <end-conversation before-redirect="true" />     1
4.          <redirect view-id="/home.xhtml" />
5.      </navigation>
6.
7.      <navigation
8.        from-action="#{quickSearchAction.performSearch}">
                                                            2
9.          <redirect view-id="/offers/index.xhtml" />
10.     </navigation>
11.
12.     <navigation>
13.         <rule if-outcome="accessDenied">
14.             <redirect view-id="/denied.xhtml" />        3
15.         </rule>
16.     </navigation>
17. </page>
Definiowanie nawigacji

1. <pages login-view-id="/login.xhtml"
2.    no-conversation-view-id="/home.xhtml">
3.
4.      <exception
5.        class="org.jboss.seam.ConcurrentRequestTimeoutException">
6.           <http-error error-code="503" />                                 1
7.      </exception>
8.
9.      <exception class="org.jboss.seam.security.AuthorizationException">
10.          <redirect view-id="/denied.xhtml" />                            2
11.     </exception>
12.
13.     <exception class="javax.persistence.OptimisticLockException">
14.          <end-conversation />                                            3
15.          <redirect view-id="/error.xhtml" />
16.     </exception>
17.
18. </pages>
Definiowanie nawigacji




1. public String goToHome() {
2.     return "/home.xhtml";
3. }
Mapowanie parametrów strony
●   Seam pozwala na ustawianie wartości pól
    komponentu w skróconym cyklu JSF (JSF
    pozwala tylko w postbacku)
●   Parametrem strony może być wartość z
    formularza (POST) jak i parametr URL (GET)
●   Parametry mogą być przypisane do dowolnych
    pól każdego komponentu Seam (osiągalnego
    za pomocą EL)
Mapowanie parametrów URL



http://localhost:8080/profile.seam?userId=1

1. <page view-id="/profile.xhtml" login-required="true">
2.   <param name="userId" value="#{userManager.userId}" />
3. </page>
Właściwości parametrów
●   Do każdego parametru można zdefiniować
    JSF-owe walidatory i konwertery takie jak
    definiuje się dla normalnego postbackowego
    cyklu
●   Można zdefiniować, że parametr jest
    wymagany bądź opcjonalny
●   Parametrów nie trzeba przypisywać do
    konkretnych pól komponentu, takie parametry
    mogą po prostu przechowywać dane między
    kolejnymi żądaniami
URL rewrite
●   Seam pozwala na przepisywanie adresów URL
    zgodnie z szablonem zdefiniowanym w
    deskryptorze strony
●   Seam przepisuje URL-e zarówno żądań
    przychodzących jak i odpowiedzi aplikacji
URL rewrite



http://localhost:8080/users/1/profile

1. <page view-id="/profile.xhtml" login-required="true">
2.   <rewrite pattern="/users/{userId}/profile" />
3.   <param name="userId" value="#{userManager.userId}" />
4. </page>
Komponenty przepisujące URL-e
●   <s:link> (<h:commandLink>)
●   <s:button> (<h:commandButton>)
Komponenty przepisujące URL-e
●   <s:link> (<h:commandLink>)
●   <s:button> (<h:commandButton>)
●   <s:form>
Akcje strony
●   Seam pozwala na wykonywanie akcji dla danej
    strony (view-id) tuż przed jej wyrenderowaniem
    (nawet w skróconym przebiegu JSF)
●   Są to standardowe akcje dla których można
    definiować reguły nawigacji (wywoływane
    jednak przed szóstą fazą JSF a nie w piątej!)
●   Akcje te mogą służyć do zainicjalizowania
    widoku – załadowania danych potrzebnych do
    wyrenderowania strony
    ●   Pozwala to na implementacje RESTful-owych URL-i
Akcje strony



http://localhost:8080/users/1/profile

1. <page view-id="/profile.xhtml" login-required="true">
2.   <rewrite pattern="/users/{userId}/profile" />
3.   <param name="userId" value="#{userManager.userId}" />
4.   <action execute="#{userManager.fetchUser}" />
5. </page>
Czego Seam nie poprawia
●   Komunikatów JSF
●   Walidacja i konwersja dotyczą tylko
    pojedynczych wartości, nie jest łatwo
    zaimplementować tych operacji na zależnych
    polach (i trzeba przenosić ten proces do piątej
    fazy)
●   Wstrzykiwanie zależności do walidatorów i
    konwerterów (można je pobierać za pomocą
    metod statycznych)
Czego nie omówiono w prezentacji?
●   Deskryptor komponentów components.xml
●   Seam-gen
●   WebBeans (JSR-299)
●   Workspace i pageflow w kontekście konwersacji
●   Wsparcia Seam dla warstwy widoku
    ●   Komponenty seamowe
    ●   Wsparcie dla AJAX
●   Testowanie integracyjne
    ●   Symulacja cyklu JSF
●   Kontekstu business process
Czy Seam daje radę?
Do poduszki
Q&A
Dziękuję za uwagę

More Related Content

Viewers also liked

Strefa PMI nr 2, wrzesień 2013
Strefa PMI nr 2, wrzesień 2013Strefa PMI nr 2, wrzesień 2013
Strefa PMI nr 2, wrzesień 2013Strefa PMI
 
PRINCE2 - Directing a Project
PRINCE2 - Directing a ProjectPRINCE2 - Directing a Project
PRINCE2 - Directing a ProjectMichał Orman
 
Kwantowe struktury półprzewodnikowe
Kwantowe struktury półprzewodnikoweKwantowe struktury półprzewodnikowe
Kwantowe struktury półprzewodnikoweMikołaj Olszewski
 
Strefa PMI nr 6, wrzesień 2014
Strefa PMI nr 6, wrzesień 2014Strefa PMI nr 6, wrzesień 2014
Strefa PMI nr 6, wrzesień 2014Strefa PMI
 
Podstawy java server faces
Podstawy java server facesPodstawy java server faces
Podstawy java server facesPROSKAR
 
Optoelektroniczne sieci neuronowe
Optoelektroniczne sieci neuronoweOptoelektroniczne sieci neuronowe
Optoelektroniczne sieci neuronoweMikołaj Olszewski
 
Strefa PMI nr 11, grudzień 2015
Strefa PMI nr 11, grudzień 2015Strefa PMI nr 11, grudzień 2015
Strefa PMI nr 11, grudzień 2015Strefa PMI
 
Strefa PMI nr 9, czerwiec 2015
Strefa PMI nr 9, czerwiec 2015Strefa PMI nr 9, czerwiec 2015
Strefa PMI nr 9, czerwiec 2015Strefa PMI
 

Viewers also liked (12)

Strefa PMI nr 2, wrzesień 2013
Strefa PMI nr 2, wrzesień 2013Strefa PMI nr 2, wrzesień 2013
Strefa PMI nr 2, wrzesień 2013
 
PRINCE2 - Directing a Project
PRINCE2 - Directing a ProjectPRINCE2 - Directing a Project
PRINCE2 - Directing a Project
 
Kwantowe struktury półprzewodnikowe
Kwantowe struktury półprzewodnikoweKwantowe struktury półprzewodnikowe
Kwantowe struktury półprzewodnikowe
 
Strefa PMI nr 6, wrzesień 2014
Strefa PMI nr 6, wrzesień 2014Strefa PMI nr 6, wrzesień 2014
Strefa PMI nr 6, wrzesień 2014
 
Podstawy java server faces
Podstawy java server facesPodstawy java server faces
Podstawy java server faces
 
Optoelektroniczne sieci neuronowe
Optoelektroniczne sieci neuronoweOptoelektroniczne sieci neuronowe
Optoelektroniczne sieci neuronowe
 
Strefa PMI nr 11, grudzień 2015
Strefa PMI nr 11, grudzień 2015Strefa PMI nr 11, grudzień 2015
Strefa PMI nr 11, grudzień 2015
 
The Rails Way
The Rails WayThe Rails Way
The Rails Way
 
PRINCE2 - Start Up
PRINCE2 - Start UpPRINCE2 - Start Up
PRINCE2 - Start Up
 
Architektura heksagonalna
Architektura heksagonalnaArchitektura heksagonalna
Architektura heksagonalna
 
Piszemy sklep java
Piszemy sklep javaPiszemy sklep java
Piszemy sklep java
 
Strefa PMI nr 9, czerwiec 2015
Strefa PMI nr 9, czerwiec 2015Strefa PMI nr 9, czerwiec 2015
Strefa PMI nr 9, czerwiec 2015
 

Similar to Seam framework in_action

4Developers 2015: Przejrzysty i testowalny kod na Androidzie? Spróbujmy z Cle...
4Developers 2015: Przejrzysty i testowalny kod na Androidzie? Spróbujmy z Cle...4Developers 2015: Przejrzysty i testowalny kod na Androidzie? Spróbujmy z Cle...
4Developers 2015: Przejrzysty i testowalny kod na Androidzie? Spróbujmy z Cle...PROIDEA
 
JDD2014: JAVA.util.concurrent czyli wielowątkowość z różnych perspektyw, tych...
JDD2014: JAVA.util.concurrent czyli wielowątkowość z różnych perspektyw, tych...JDD2014: JAVA.util.concurrent czyli wielowątkowość z różnych perspektyw, tych...
JDD2014: JAVA.util.concurrent czyli wielowątkowość z różnych perspektyw, tych...PROIDEA
 
Testy funkcjonalne
Testy funkcjonalneTesty funkcjonalne
Testy funkcjonalnePROSKAR
 
Blokada wykonywania wielu akcji z jednego widoku
Blokada wykonywania wielu akcji z jednego widokuBlokada wykonywania wielu akcji z jednego widoku
Blokada wykonywania wielu akcji z jednego widokuPROSKAR
 
NK API - Przykłady
NK API - PrzykładyNK API - Przykłady
NK API - Przykładynasza-klasa
 
Exam: 70-511 Enhancing Usability - Windows Application
Exam: 70-511 Enhancing Usability - Windows ApplicationExam: 70-511 Enhancing Usability - Windows Application
Exam: 70-511 Enhancing Usability - Windows ApplicationMaciej Zbrzezny
 
Professional Javascript for Developers
Professional  Javascript for DevelopersProfessional  Javascript for Developers
Professional Javascript for DevelopersRule_Financial
 
Jak stworzyć udany system informatyczny
Jak stworzyć udany system informatycznyJak stworzyć udany system informatyczny
Jak stworzyć udany system informatycznyqbeuek
 
Patronage 2016 Windows 10 Warsztaty
Patronage 2016 Windows 10 WarsztatyPatronage 2016 Windows 10 Warsztaty
Patronage 2016 Windows 10 Warsztatyintive
 
Wprowadzenie do React
Wprowadzenie do ReactWprowadzenie do React
Wprowadzenie do ReactBrainhub
 
4Developers 2015: Orleans - aplikacje, które skalują i dystrybuują się same -...
4Developers 2015: Orleans - aplikacje, które skalują i dystrybuują się same -...4Developers 2015: Orleans - aplikacje, które skalują i dystrybuują się same -...
4Developers 2015: Orleans - aplikacje, które skalują i dystrybuują się same -...PROIDEA
 
AngularJS - podstawy
AngularJS - podstawyAngularJS - podstawy
AngularJS - podstawyApptension
 
#3 Frontend Meetup - RequireJS
#3 Frontend Meetup - RequireJS#3 Frontend Meetup - RequireJS
#3 Frontend Meetup - RequireJSMaciej Grajcarek
 
Ganymede - nowoczesne technologie w grach przeglądarkowych i mobilnych
Ganymede - nowoczesne technologie w grach przeglądarkowych i mobilnychGanymede - nowoczesne technologie w grach przeglądarkowych i mobilnych
Ganymede - nowoczesne technologie w grach przeglądarkowych i mobilnychSKN Shader
 
Aplikacje internetowe real-time w oparciu o React/Redux
Aplikacje internetowe real-time w oparciu o React/ReduxAplikacje internetowe real-time w oparciu o React/Redux
Aplikacje internetowe real-time w oparciu o React/ReduxDawid Rusnak
 

Similar to Seam framework in_action (20)

4Developers 2015: Przejrzysty i testowalny kod na Androidzie? Spróbujmy z Cle...
4Developers 2015: Przejrzysty i testowalny kod na Androidzie? Spróbujmy z Cle...4Developers 2015: Przejrzysty i testowalny kod na Androidzie? Spróbujmy z Cle...
4Developers 2015: Przejrzysty i testowalny kod na Androidzie? Spróbujmy z Cle...
 
Grok Artykul
Grok ArtykulGrok Artykul
Grok Artykul
 
JDD2014: JAVA.util.concurrent czyli wielowątkowość z różnych perspektyw, tych...
JDD2014: JAVA.util.concurrent czyli wielowątkowość z różnych perspektyw, tych...JDD2014: JAVA.util.concurrent czyli wielowątkowość z różnych perspektyw, tych...
JDD2014: JAVA.util.concurrent czyli wielowątkowość z różnych perspektyw, tych...
 
Testy funkcjonalne
Testy funkcjonalneTesty funkcjonalne
Testy funkcjonalne
 
Pure MVC - Mediovski
Pure MVC - MediovskiPure MVC - Mediovski
Pure MVC - Mediovski
 
Behat
BehatBehat
Behat
 
Blokada wykonywania wielu akcji z jednego widoku
Blokada wykonywania wielu akcji z jednego widokuBlokada wykonywania wielu akcji z jednego widoku
Blokada wykonywania wielu akcji z jednego widoku
 
NK API - Przykłady
NK API - PrzykładyNK API - Przykłady
NK API - Przykłady
 
Exam: 70-511 Enhancing Usability - Windows Application
Exam: 70-511 Enhancing Usability - Windows ApplicationExam: 70-511 Enhancing Usability - Windows Application
Exam: 70-511 Enhancing Usability - Windows Application
 
Professional Javascript for Developers
Professional  Javascript for DevelopersProfessional  Javascript for Developers
Professional Javascript for Developers
 
Jak stworzyć udany system informatyczny
Jak stworzyć udany system informatycznyJak stworzyć udany system informatyczny
Jak stworzyć udany system informatyczny
 
Patronage 2016 Windows 10 Warsztaty
Patronage 2016 Windows 10 WarsztatyPatronage 2016 Windows 10 Warsztaty
Patronage 2016 Windows 10 Warsztaty
 
Torquebox
TorqueboxTorquebox
Torquebox
 
Wprowadzenie do React
Wprowadzenie do ReactWprowadzenie do React
Wprowadzenie do React
 
4Developers 2015: Orleans - aplikacje, które skalują i dystrybuują się same -...
4Developers 2015: Orleans - aplikacje, które skalują i dystrybuują się same -...4Developers 2015: Orleans - aplikacje, które skalują i dystrybuują się same -...
4Developers 2015: Orleans - aplikacje, które skalują i dystrybuują się same -...
 
AngularJS - podstawy
AngularJS - podstawyAngularJS - podstawy
AngularJS - podstawy
 
JavaScript, Moduły
JavaScript, ModułyJavaScript, Moduły
JavaScript, Moduły
 
#3 Frontend Meetup - RequireJS
#3 Frontend Meetup - RequireJS#3 Frontend Meetup - RequireJS
#3 Frontend Meetup - RequireJS
 
Ganymede - nowoczesne technologie w grach przeglądarkowych i mobilnych
Ganymede - nowoczesne technologie w grach przeglądarkowych i mobilnychGanymede - nowoczesne technologie w grach przeglądarkowych i mobilnych
Ganymede - nowoczesne technologie w grach przeglądarkowych i mobilnych
 
Aplikacje internetowe real-time w oparciu o React/Redux
Aplikacje internetowe real-time w oparciu o React/ReduxAplikacje internetowe real-time w oparciu o React/Redux
Aplikacje internetowe real-time w oparciu o React/Redux
 

More from Michał Orman

Integration of Backbone.js with Spring 3.1
Integration of Backbone.js with Spring 3.1Integration of Backbone.js with Spring 3.1
Integration of Backbone.js with Spring 3.1Michał Orman
 
PRINCE2 - Managing a Stage Boundary
PRINCE2 - Managing a Stage BoundaryPRINCE2 - Managing a Stage Boundary
PRINCE2 - Managing a Stage BoundaryMichał Orman
 
Prince2 Controlling a Stage
Prince2 Controlling a StagePrince2 Controlling a Stage
Prince2 Controlling a StageMichał Orman
 
PRINCE2 - Closing a Project
PRINCE2 - Closing a ProjectPRINCE2 - Closing a Project
PRINCE2 - Closing a ProjectMichał Orman
 
PRINCE2 - Managing Product Delivery
PRINCE2 - Managing Product DeliveryPRINCE2 - Managing Product Delivery
PRINCE2 - Managing Product DeliveryMichał Orman
 
PRINCE2 - Project Initiation
PRINCE2 - Project InitiationPRINCE2 - Project Initiation
PRINCE2 - Project InitiationMichał Orman
 

More from Michał Orman (6)

Integration of Backbone.js with Spring 3.1
Integration of Backbone.js with Spring 3.1Integration of Backbone.js with Spring 3.1
Integration of Backbone.js with Spring 3.1
 
PRINCE2 - Managing a Stage Boundary
PRINCE2 - Managing a Stage BoundaryPRINCE2 - Managing a Stage Boundary
PRINCE2 - Managing a Stage Boundary
 
Prince2 Controlling a Stage
Prince2 Controlling a StagePrince2 Controlling a Stage
Prince2 Controlling a Stage
 
PRINCE2 - Closing a Project
PRINCE2 - Closing a ProjectPRINCE2 - Closing a Project
PRINCE2 - Closing a Project
 
PRINCE2 - Managing Product Delivery
PRINCE2 - Managing Product DeliveryPRINCE2 - Managing Product Delivery
PRINCE2 - Managing Product Delivery
 
PRINCE2 - Project Initiation
PRINCE2 - Project InitiationPRINCE2 - Project Initiation
PRINCE2 - Project Initiation
 

Seam framework in_action

  • 2. Szew ● Miejsce zszycia kawałków tkaniny, futra itp. wraz z nićmi, którymi te kawałki zszyto. ● Operacyjne zszycie tkanek miękkich. ● Naturalne połączenie dwu przylegających do siebie kości spojonych tkanką łączną. ● Połączenie brzegów przedmiotów metalowych za pomocą nitkowania lub spawania.
  • 3. JSF EJB
  • 4. AJAX Facelets JSF ICEFaces GWT RichFaces Drools Wicket Spring WebBeans JPA EJB Hibernate Guice Groovy jBMP Seam one framework to rule them all...
  • 6. Stos aplikacji ● Integruje różne frameworki z różnych warstw JEE ● Widoku (JSF, RichFaces, ICEFaces, Wicket) ● Dostępu do danych (JPA, Hibernate) ● i więcej ...
  • 7. Kontener komponentów ● Integruje komponenty JPA, EJB, POJO oraz JSF w taki sposób, że zaciera granice pomiędzy poszczególnymi warstwami i daje wrażenie korzystania z jednego kontenera
  • 8. Komponenty i kontenery Kontener Tworzenie komponentu EJB @Stateful, @Stateless, @MessageDriven, ejb- jar.xml JSF faces-config.xml Spring applicationContext.xml Kontener servletów web.xml
  • 9. Komponenty i kontenery Kontener Tworzenie komponentu EJB @Stateful, @Stateless, @MessageDriven, ejb- jar.xml JSF faces-config.xml Spring applicationContext.xml Kontener servletów web.xml Seam @Name, components.xml
  • 10. Facelets / RichFaces / JSP JSF Seam EJB / Spring / JPA / Hibernate Seam context variable
  • 11. Definiowanie komponentu Seam 1. @Name("foo") 2. @Scope(ScopeType.CONVERSATION) 3. public class Foo { }
  • 12. Wstrzykiwanie zależności 1. @Name("bar") 2. public class Bar { 3. 4. @In 5. private Foo foo; 6. 7. }
  • 13. Wstrzykiwanie zależności cd... 1. @Name("bar") 2. public class Bar { 3. 4. @In(create = true) 5. private Foo foo; 6. 7. }
  • 14. Wstrzykiwanie zależności cd... 1. @Name("bar") 2. public class Bar { 3. 4. @In("#{foo}") 5. private Foo foo; 6. 7. }
  • 15. Inversion of Control ● Wzorzec projektowy „rozluźniający” powiązania pomiędzy komponentami ● Pozwala komponentom na skupienie się na wykorzystywaniu innych komponentów (serwisów) niż ich wyszukiwaniu ● Wszyscy go dobrze znają...
  • 16. Inversion of Control ● Zwykle ludzie mówiąc o IoC mają na myśli dependency injection (DI), jeden z przypadków użycia IoC ● Jednakże IoC > DI
  • 17. DI jest zbyt statyczne Problem z klasycznym podejściem do DI jest taki, że wstrzykiwanie zależności odbywa się tylko raz, tuż po stworzeniu instancji komponentu. Komponent jest przywiązany do referencji obiektów wstrzykniętych mu w czasie tworzenia. Komponenty powinny być świadome swojego istnienia w kontekście i powinny brać aktywny udział w zarządzaniu komponentami.
  • 18. IoC w Seam ● W Seam mamy do czynienia z dependency bijection ● W Seam zależności są wstrzykiwane dynamicznie w czasie życia komponentu, a nie tylko podczas jego tworzenia ● Dependency bijection pozwala na wstrzykiwanie zależności do komponentu, jak i umieszczanie komponentów w kontekście ● Bijection = injection + outjection
  • 19. Bijection ● Bijection jest to kombinacja injection i outjection ● Bijection zachodzi w momencie wywołania metody (a nie tworzenia komponentu) ● Injection w momencie wywołania metody ● Outjection po powrocie metody
  • 20. Disinjection ● Wszystkie pola komponentów do których zostały wstrzyknięte zależności otrzymują wartość null. ● Zapobiega wyciekom pamięci ● Rozwiązuje problem serializacji obiektów
  • 21. Bijection interceptor Komponent wywołujący metodę Interceptor Wstrzykiwanie zależności w pola oznaczone adnotacją @In Wywołanie metody Outjection na polach oznaczonych adnotacją @Out Disinjection na polach oznaczonych adnotacją @In Powrót z metody
  • 22. Bijection w akcji 1. @Name("authenticator") 2. public class Authenticator { 3. @In 4. private Credentials credentials; 5. 6. @Out(scope = ScopeType.SESSION, required = false) 7. private Long currentUserId; 8. 9. @In(create = true) 10. private UserQuery userQuery; 11. 12. public boolean authenticate() { 13. userQuery.setUsername(credentials.getUsername()); 14. User user = userQuery.getSingleResult(); 15. if (isPasswordValid(credentials.getPassword(), user)) { 16. currentUserId = user.getId(); 17. } 18. } 19. 20. // pozostałe metody 21. }
  • 23. Inne formy wstrzykiwania zależności ● @RequestParameter ● @PersistenceContext ● @DataModelSelection ● @DataModelSelectionIndex
  • 24. Inne formy dependency outjection ● @DataModel ● @Factory ● @Unwrap
  • 25. Omijanie bijection ● Wewnętrzne wywołania metod ● @BypassInterceptors
  • 27. Zdarzenia ● Seam posiada wbudowane wsparcie dla wzorca observer, który w znacznym stopniu pozwala redukować zależności między komponentami (budować luźne powiązania) ● Seam pozwala na generowanie zdarzeń z metod jak i ich obsługę z metod komponentów ● Zdarzenia mogą być generowane na wiele sposobów, jak i można generować wiele typów zdarzeń (synchroniczne, asynchroniczne, czasowe, transakcyjne)
  • 28. Generowanie zdarzeń 1. public String register() { 2. // registration action 3. Events.instance().raiseEvent("registered"); 4. return "success"; 5. }
  • 29. Generowanie zdarzeń 1. @In private Events events; 2. 3. public String register() { 4. // registration action 5. entityManager.persist(newUser); 6. events.raiseTransactionSuccessEvent( 7. "registered", newUser); 8. return "success"; 9. }
  • 30. Generowanie zdarzeń 1. @RaiseEvent("registered") 2. public String register() { 3. // registration action 4. return "success"; 5. }
  • 31. Generowanie zdarzeń 1. <page view-id="/register.xhtml"> 2. <navigation 3. from-action="#{userManager.register}"> 5. <rule if-outcome="success"> 6. <raise-event type="registered" /> 7. <redirect 8. view-id="/registered.xhtml" /> 9. </rule> 10. </navigation> 11. </page>
  • 32. Obserwowanie zdarzeń 1. @Name("registrationObserver") 2. public class RegistrationObserver { 3. @Logger private Log logger; 4. 5. @Observer(value="registered", create=true) 6. public void onRegisteredEvent(User newUser) { 7. logger.info("Registered new user: " 8. + newUser.getUsername()); 9. } 10. 11. }
  • 33. Obserwowanie zdarzeń 1. <event type="registered"> 2. <action 3. execute= 4. "#{registrationObserver.onRegisterEvent(newUser)}" 5. /> 6. </event>
  • 34. Wbudowane zdarzenia ● Inicjalizacja kontenera seamowego ● Przypisanie zmiennej kontekstowej (added, removed) ● Zdarzenia cyklu życia komponentów (created, destroyed) ● Zdarzenia związane z autentykacją ● Zdarzenia związane z transakcją ● i wiele innych...
  • 36. Metody fabrukujące w Seam ● Seam posiada wbudowane wsparcie dla wzorca factory method ● Fabryka ma na celu dostarczenie konkretnych danych zamiast instancji komponentu ● Metody fabrykujące oznacza się adnotacją @Factory lub w deskryptorze komponentów ● Metody fabrykujące z założenia mają wypierać użycie „getterów”
  • 37. Metoda fabrykująca jest wykonywana tylko raz, kolejne wywołania zwracają utworzoną i umieszczoną w kontekście wcześniej wartość.
  • 38. Rezultat wywołania fabryki ● Rezultat metody fabrykującej może być przekazany na trzy sposoby: ● Przez zwrócenie wartości z metody ● Przez outjection (jako, że metoda fabrykująca znajduje się w komponencie to działa na nim bijection) ● Przez umieszczenie wartości bezpośrednio w kontekście
  • 39. Przykład metody fabrykujacej 1. @Name("currentUserFactory") 2. public void CurrentUserHome { 3. @In private EntityManager em; 4. 5. @In private Long currentUserId; 6. 7. @Factory("currentUser") 8. public User getCurrentUser() { 9. return em.find(User.class, currentUserId); 10. } 11. }
  • 40. Przykład metody fabrykujacej 1. @Name("currentUserFactory") 2. public void CurrentUserHome { 3. @In private EntityManager em; 4. 5. @In private Long currentUserId; 6. 7. @Out private User currentUser; 8. 9. @Factory("currentUser") 10. public User getCurrentUser() { 11. currentUser = 12. em.find(User.class, currentUserId); 13. } 14. }
  • 42. Unwrap ● Seam pozwala dostarczać dane do kontekstu za pomocą metody oznaczonej adnotacją @Unwrap ● W odróżnieniu od metody fabrykującej taka metoda jest wywoływana za każdym razem, kiedy komponent pod konkretną nazwą jest żądany
  • 43. @Unwrap a @Factory ● Jest prawdziwym komponentem ● Można konfigurować w components.xml ● Można używać adnotacji @Create i @Destroy ● Metoda oznaczona @Unwrap jest wywoływana zawsze ● Komponent może przechowywać stan i obserwować zdarzenia
  • 44. Metody oznaczone @Unwrap można używać jako swoisty alias.
  • 45. @Unwrap w akcji 1. @Name("org.jboss.seam.faces.facesContext") 2. @Scope(ScopeType.APPLICATION) 3. public class FacesContext { 4. @Unwrap public FacesContext getContext() { 5. return FacesContext.getCurrentInstance(); 6. } 7. }
  • 47. Interceptory w Seam ● Seam rozszerza funkcjonalność interceptorów z EJB ● Przenosi ją ze świata Java EE to świata POJO ● Pozwala w deklaratywny sposób dodawać logikę AOP
  • 48. Definiowanie interceptora 1. @AroundInvoke 2. public Object methodName(InvocationContext ctx) 3. throws Exception { 4. // interceptor logic... 5. return ctx.proceed(); 6. }
  • 49. Definiowanie interceptora 1. @Interceptor(stateless = true, 2. type = InterceptorType.CLIENT 3. public class StatelessInterceptor { 4. 5. @AroundInvoke 6. public Object methodName(InvocationContext ctx) 7. throws Exception { 8. // interceptor logic... 9. return ctx.proceed(); 10. } 11. 12. }
  • 50. Cechy interceptora w Seam ● Interceptor może być stateful-owy lub stateless- owy ● Interceptory mogą być przypisywane do komponentów zarówno po stronie serwera jak i klienta ● Interceptory mogą być przypisywane do klas deklaratywnie (stereotypes)
  • 52. Przypisywanie interceptorów ● @Interceptors ● W Seamie, w odróżnieniu od EJB, adnotacja @Interceptors nie jest nakładana na klasy komponentów, które chcemy interceptować ● Adnotacja ta to meta adnotacja którą nakłada się na inne adnotacje
  • 53. Przypisywanie interceptorów 1. @Target(TYPE) 2. @Retention(RUNTIME) 3. @Interceptors(CurrentUserAccessInterceptor.class) 4. public @interface VerifyCurrentUserAccess {} 5. 6. @Name("offerAddAction") 7. @VerifyCurrentUserAccess 8. public class OfferAddAction { }
  • 55. Konteksty w Java Servlet API ● Request ● Session ● Application
  • 56. Konteksty w Seam ● Event (request) ● Page ● Conversation ● Session ● Application ● Business process
  • 57. Konteksty w Seam Przeglądarka Strona 1 Strona 1 Strona 2 Strona 3 event event event event page page page conversation conversation session
  • 59. Konwersacja w Seam ● Pozwala przechowywać stan komponentów pomiędzy kolejnymi żądaniami (nawet w przypadku występowania przekierowań) ● Jest bardziej ziarnista niż kontekst sesji ● W deklaratywny sposób można kontrolować zakresy konwersacji (oraz jej propagacje) ● Na czas konwersacji Seam rozpina transakcje (utrzymywana jest sesja połączenia z bazą danych)
  • 60. Konwersacja w Seam została pomyślana jako kontekst, który przechowuje stan komponentów w ramach konkretnego przypadku użycia.
  • 61. A czemu nie w sesji? ● Sesja jest zbyt długa i przechowywanie danych w tym kontekście może prowadzić do wycieków pamięci ● Sesja jest dzielona pomiędzy karty przeglądarki ● Sesja nie posiada żadnych mechanizmów obronnych przed współbieżnym dostępem do danych ● Błędy występujące przez nieprawidłowe wykorzystywanie kontekstu sesji mogą być trudne do reprodukcji w środowisku testowym
  • 62. Mimo wszystko rozwiązanie leży w... sesji. Trzeba ją tylko odpowiednio podzielić i zarządzać.
  • 63. Konwersacja to wydzielony segment sesji cid = 1 cid = 2 cid = 3 cid = 4 Sesja HTTP
  • 64. Seam zarządza konwersacją ● Każda konwersacja posiada określony czas trwania (timeout) ● Każda konwersacja toczy się w izolacji (nie trzeba się przejmować synchronizacją)
  • 65. Wymagania konwersacji ● Komponenty muszą implementować interfejs java.io.Serializable ● Czas trwania sesji musi być dłuższy niż czas trwania konwersacji
  • 66. Stany konwersacji ● Tymczasowa (temporary conversation) ● Długa (long-running conversation) ● Zagnieżdżona (nested conversation)
  • 67. Stany konwersacji ● Tymczasowa (temporary conversation) ● Długa (long-running conversation) ● Zagnieżdżona (nested conversation)
  • 68. Przejścia stanów konwersacji brak konwersacji kontynuacja konwersacji begin Temporary Long-running end koniec żądania sesja lub konwersacja wygasła Zniszczona Zniszczona
  • 69. Stany długiej konwersacji Long-running resumed concurrent conversation resumed begin resumed Foreground Background end session timeout conversation or session timeout Zniszczona
  • 71. Za pomocą adnotacji 1. @Name("bookingAction") 2. @Restrict("#{s:hasRole('Customer')}") 3. public class BookingAction { 4. 5. @Begin(join = true) 6. public void fetchRooms() { 7. // fetching rooms... 8. } 9. 10. @End(beforeRedirect = true) 11. public void confirm() { 12. // confirm booking... 13. } 14. 15. @End(beforeRedirect = true) 16. public void cancel() { 17. // cancel booking... 18. } 19. 20. }
  • 72. Za pomocą adnotacji 1. @Name("roomsFactory") 2. public void RoomsFactory { 3. @Begin(join = true) 4. public void fetchRooms() { 5. // fetching rooms... 6. } 7. } 8. 9. @Name("bookingAction") 10. public void BookingAction { 11. @End(beforeRedirect = true) 12. public void confirm() { 13. // confirmation action... 14. } 15. }
  • 73. W deskryptorze strony 1. <page view-id="/booking.xhtml"> 2. <begin-conversation join="true" /> 3. </page>
  • 74. W definicjach nawigacji 1. <page view-id="/booking.xhtml"> 2. <navigation 3. from-action="#{roomsFactory.fetchRooms}"> 4. <begin-conversation join="true" /> 5. </navigation> 6. 7. <navigation from-action="#{bookingAction.confirm}"> 8. <end-conversation before-redirect="true" /> 9. </navigation> 10. </page>
  • 75. Za pomocą komponentów JSF 1. <s:link view-id="/booking.xhtml" propagation="begin" /> 2. 3. <s:button action="#{bookingAction.confirm}" 4. propagation="end" /> 5. 6. <h:commandButton action="#{bookingAction.confirm}"> 7. <s:conversationPropagation type="end" /> 8. </h:commandButton>
  • 77. Cykl JSF JSF Servlet Render Restore Response View Invoke Apply Request Application Values Update Model Process Values Validations
  • 78. Cykl JSF (initial request) Przeglądarka JSF Servlet Render Restore Response View Invoke Apply Request Application Values Update Model Process Values Validations
  • 79. Cykl JSF (postback) Przeglądarka JSF Servlet Render Restore Response View Invoke Apply Request Application Values Update Model Process Values Validations
  • 80. Nawigacja w JSF 1. <navigation-rule> 2. <from-view-id>/login.xhtml</from-view-id> 3. <navigation-case> 4. <from-action> 5. #{authenticator.login} 6. </from-action> 7. <from-outcome>loggedIn</from-outcome> 8. <to-view-id>/home.xhtml</to-view-id> 9. <redirect/> 10. </navigation-case> 11. </navigation-rule>
  • 81. Problemy z JSF ● Skrócony cykl JSF ● Służy jako dostawca strony ● Zakłada, że nie potrzeba wykonywania żadnej logiki przed wyrenderowaniem strony ● Zakłada, że użytkownik posiada uprawnienia do żądanego zasobu ● Zorientowanie na żądania typu POST ● Mało rozwinięte reguły nawigacji ● Brak możliwości wykorzystania EL w regułach
  • 83. Do czego służy deskryptor strony ● Definiowania reguł nawigacji ● Generowania komunikatów (FacesMessages) ● Mapowania parametrów URL ● Dodawania parametrów URL (dla przekierowań) ● Uruchamiania akcji zanim widok zostanie wyrenderowany
  • 84. Do czego służy deskryptor strony cd... ● Sprawdzania reguł bezpieczeństwa ● Kontrolowania zakresów konwersacji ● Kontrolowania zakresów page flow ● Kontrolowania zakresów procesów biznesowych i zadań ● Wywoływanie eventów ● Obsługa wyjątków
  • 85. Deskryptor jest świadomy kontekstu aplikacji
  • 86. Inteligentna nawigacja w Seam ● Pozwala użyć dowolnej wartości (dostępnej za pomocą EL) do definiowania przekierowań ● Reguły nawigacji są warunkowe ● Definiuje jak powinna być propagowana konwersacja, czy proces biznesowy ● Pozwala dodawać komunikaty JSF przed wyrenderowaniem strony bądź przekierowaniem ● Pozwala dodawać parametry URL ● Pozwala wywoływać eventy
  • 87. Definiowanie nawigacji 1. <page view-id="/login.xhtml" scheme="https"> 2. <navigation> 3. <rule if="#{identity.loggedIn}"> 4. <redirect view-id="/home.xhtml" /> 5. </rule> 6. </navigation> 7. </page>
  • 88. Definiowanie nawigacji 1. <page view-id="/offer/add.xhtml" login-required="true"> 2. <navigation from-action="#{offerManager.addOffer}"> 3. 4. <rule if-outcome="offerAdded" 5. if="#{offerManager.addNext}"> 1 6. <redirect view-id="/offer/add.xhtml" /> 7. </rule> 8. 9. <rule if-outcome="offerAdded"> 10. <redirect view-id="/offer/list.xhtml"> 11. <param name="userId" 2 12. value="#{currentUserId}" /> 13. </redirect> 14. </rule> 15. 16. </navigation> 17. </page>
  • 89. Definiowanie nawigacji 1. <page view-id="*"> 2. <navigation from-action="#{identity.logout}"> 3. <end-conversation before-redirect="true" /> 1 4. <redirect view-id="/home.xhtml" /> 5. </navigation> 6. 7. <navigation 8. from-action="#{quickSearchAction.performSearch}"> 2 9. <redirect view-id="/offers/index.xhtml" /> 10. </navigation> 11. 12. <navigation> 13. <rule if-outcome="accessDenied"> 14. <redirect view-id="/denied.xhtml" /> 3 15. </rule> 16. </navigation> 17. </page>
  • 90. Definiowanie nawigacji 1. <pages login-view-id="/login.xhtml" 2. no-conversation-view-id="/home.xhtml"> 3. 4. <exception 5. class="org.jboss.seam.ConcurrentRequestTimeoutException"> 6. <http-error error-code="503" /> 1 7. </exception> 8. 9. <exception class="org.jboss.seam.security.AuthorizationException"> 10. <redirect view-id="/denied.xhtml" /> 2 11. </exception> 12. 13. <exception class="javax.persistence.OptimisticLockException"> 14. <end-conversation /> 3 15. <redirect view-id="/error.xhtml" /> 16. </exception> 17. 18. </pages>
  • 91. Definiowanie nawigacji 1. public String goToHome() { 2. return "/home.xhtml"; 3. }
  • 92. Mapowanie parametrów strony ● Seam pozwala na ustawianie wartości pól komponentu w skróconym cyklu JSF (JSF pozwala tylko w postbacku) ● Parametrem strony może być wartość z formularza (POST) jak i parametr URL (GET) ● Parametry mogą być przypisane do dowolnych pól każdego komponentu Seam (osiągalnego za pomocą EL)
  • 93. Mapowanie parametrów URL http://localhost:8080/profile.seam?userId=1 1. <page view-id="/profile.xhtml" login-required="true"> 2. <param name="userId" value="#{userManager.userId}" /> 3. </page>
  • 94. Właściwości parametrów ● Do każdego parametru można zdefiniować JSF-owe walidatory i konwertery takie jak definiuje się dla normalnego postbackowego cyklu ● Można zdefiniować, że parametr jest wymagany bądź opcjonalny ● Parametrów nie trzeba przypisywać do konkretnych pól komponentu, takie parametry mogą po prostu przechowywać dane między kolejnymi żądaniami
  • 95. URL rewrite ● Seam pozwala na przepisywanie adresów URL zgodnie z szablonem zdefiniowanym w deskryptorze strony ● Seam przepisuje URL-e zarówno żądań przychodzących jak i odpowiedzi aplikacji
  • 96. URL rewrite http://localhost:8080/users/1/profile 1. <page view-id="/profile.xhtml" login-required="true"> 2. <rewrite pattern="/users/{userId}/profile" /> 3. <param name="userId" value="#{userManager.userId}" /> 4. </page>
  • 97. Komponenty przepisujące URL-e ● <s:link> (<h:commandLink>) ● <s:button> (<h:commandButton>)
  • 98. Komponenty przepisujące URL-e ● <s:link> (<h:commandLink>) ● <s:button> (<h:commandButton>) ● <s:form>
  • 99. Akcje strony ● Seam pozwala na wykonywanie akcji dla danej strony (view-id) tuż przed jej wyrenderowaniem (nawet w skróconym przebiegu JSF) ● Są to standardowe akcje dla których można definiować reguły nawigacji (wywoływane jednak przed szóstą fazą JSF a nie w piątej!) ● Akcje te mogą służyć do zainicjalizowania widoku – załadowania danych potrzebnych do wyrenderowania strony ● Pozwala to na implementacje RESTful-owych URL-i
  • 100. Akcje strony http://localhost:8080/users/1/profile 1. <page view-id="/profile.xhtml" login-required="true"> 2. <rewrite pattern="/users/{userId}/profile" /> 3. <param name="userId" value="#{userManager.userId}" /> 4. <action execute="#{userManager.fetchUser}" /> 5. </page>
  • 101. Czego Seam nie poprawia ● Komunikatów JSF ● Walidacja i konwersja dotyczą tylko pojedynczych wartości, nie jest łatwo zaimplementować tych operacji na zależnych polach (i trzeba przenosić ten proces do piątej fazy) ● Wstrzykiwanie zależności do walidatorów i konwerterów (można je pobierać za pomocą metod statycznych)
  • 102. Czego nie omówiono w prezentacji? ● Deskryptor komponentów components.xml ● Seam-gen ● WebBeans (JSR-299) ● Workspace i pageflow w kontekście konwersacji ● Wsparcia Seam dla warstwy widoku ● Komponenty seamowe ● Wsparcie dla AJAX ● Testowanie integracyjne ● Symulacja cyklu JSF ● Kontekstu business process
  • 103. Czy Seam daje radę?
  • 105. Q&A