Springowe portlety JSR-168 - JBoss Portal

Przed przystąpieniem do realizacji spójrz na mój poprzedni post.

Krok 1: Przygotowanie środowiska
Przygotowanie środowiska polega na rozpakowaniu na dysku pliku zip ze sciągniętym, prekonfigurowanym pod kątem używania go w portalu serwera JBoss i zarejestrowania go w NetBeans.

  1. Należy rozpakować serwer
  2. Uruchomić NetBeans
    Następne kroki należy wykonać w NetBeans:
  3. Tools->Server Manager
  4. Add Server
  5. 5. Z górnej listy rozwijanej należy wybrać opcję "JBoss Application Server 4", w dolnym polu tekstowym należy wpisać nazwę pod jaką ma być widziany nasz serwer i kliknąć Next
  6. Należy wskazać katalog główny naszego rozpakowanego serwera i wcisnąć przycisk Next

  7. W następnym oknie wszystkie opcje należy pozostawić niezmienione i naisnąć przycisk Finish

  8. Nowo dodany serwer powinien pojawić się na liście serwerów.
  9. Jeśli wszystko jest w porządku należy zamknąć okno Server Manager.
Krok 2: Założenie pustego projektu WEB
  1. File -> New Project
  2. W oknie dialogowym "Categories" należy wybrać Web, a w oknie "Projects" - Web Application i wcisnąć przycisk Next
  3. Należy wpisać nazwę projektu (spring-portlets) a listę "Source Structure" ustawić na Jakarta - reszta opcji bez zmian i wcisnąć przycisk Finish

  4. Okno ulegnie zamknięciu i zostanie utworzony nowy projekt o nazwie (spring-portlets)
Krok 3: Przekopiowanie źródeł przykładu do nowo utworzonego projektu
  1. Należy pobrać plik spring-portlets.zip
  2. Zawartość katalogu spring-portlet-sample (bez samego katalogu!!!) należy rozpakować i umieścić w katalogu NetBeans_Workspace/spring-portlets/web
  3. Istnienie domyślnych plików zakładanych standardowo, przy tworzeniu projektu przez NetBeans będzie generowało ostrzeżenia podczas kopiowania- nie trzeba się tym przejmować - przy pierwszym ostrzeżeniu należy kliknąć "Zamień wszystkie" - lub zamieniać każdy plik po kolei.
  4. Ponieważ wprowadziłem kilka drobnych modyfikacji do oryginalnego, dostarczanego z przykładami skryptu "/web/build.xml" najprościej będzie go podmienić przez ten zmodyfikowany, pobrany stąd.
  5. Po uruchomieniu NetBeans drzewo projektu powinno wyglądać mniej więcej tak:

  6. Dołączenie do projektu wymaganych bibliotek.
    Przede wszystkim konieczne jest dodanie do projektu biblioteki /lib/portlet-api.jar . W tym celu należy:
    1. Kliknąć prawym przyciskiem na nazwie projektu.
    2. Z menu kontekstowego wybrać opcję Properties
    3. W nowo otwartym oknie dialogowym, w polu "Categories" wskazać opcję "Libraries"
    4. Wybrać przycisk "Add JAR/Folder"
    5. Wskazać katalog NetBeans_Workspace/spring-portlets/web/lib, w którym znajduje się plik portlet-api.jar zawierający implementację tagów potrzebnych do obsługi portletów przeznaczoną dla serwera JBoss. W oknie dialogowym należy wyprać plik portlet-api.jar i potwierdzić wybór. Do projektu zostanie dodana nowa biblioteka.


      Analogiczne kroki należy powtórzyć dla wszystkich bibliotek z katalogu NetBeans_Workspace/spring-portlets/web/WEB-INF/lib . Dodanie bibliotek umożliwi ponowną kompilację całego projektu.

  7. Przedefiniowanie katalogu zawierającego pliki źródłowe Java.
    1. W oknie właściwości projektu w polu "Categories" należy wskazać opcję "Sources"
    2. W oknie "Source Packages Folders" należy wskazać katalog "src" i usunąć go.
    3. Należy dodać nowy katalog przez użycie przycisku "Add Folder" i wskazać katalog NetBeans_Workspace/spring-portlets/web/WEB-INF/src . Wynik powinien być mniej więcej następujący:

    4. Teraz należy można zamknąć okno właściwości projektu - projekt jest przygotowany do tworzenia nowego portletu.

Tworzenie nowego portletu

Aby zaprezentować kroki które należy wykonać aby stworzyć portlet WSRP napisany przy wykorzystaniu frameworku Spring Portlet MVC posłuże się banalną mutacją portletu HelloWorld.

Stworzenie klas kontrolerów Spring
Na początek stwórzmy dwie zwykłe klasy - jedna niech nazywa się GreetingController i GoodByeController - ja umieściłem je w pakiecie mw.firstspringportlet:


Konstrukcja kontrolerów opartych na Spring Portlet MVC jest bardzo zbliżona do analogicznych kontrolerów wchodzących w skład Spring Web MVC.

W najprostszym przypadku (a przecież o taki nam tu chodzi ) nasz dowolny kontroler dziedziczy z klasy AbstractController . Programista musi nadpisać metodę

ModelAndView handleRenderRequestInternal(RenderRequest request, RenderResponse response)

Służy ona do implementacji logiki i zwraca obiekt ModelAndView, który zawiera informacje pozwalające na przekazanie sterowania do odpowiedniego widoku.

Dla GreetingController wygląda ona następująco:

public ModelAndView handleRenderRequestInternal(RenderRequest request, RenderResponse response) throws Exception {
return new ModelAndView("greetingView");
}


Dla klasy GoodByeController postać metody jest prawie identyczna - jedyną różnicą jest to, że w parametrze konstruktora obiektu ModelAndView podana zostaje inna nazwa widoku: goodByeView.

Konfiguracja głównego kontekstu springowego

Główna część konfiguracji kontekstu springowego znajduje się w pliku
NetBeans_Workspace/spring-portlets/web/WEB-INF/context
/applicationContext.xml


Plik ten zawiera informacje wspólne dla wszystkich aplikacji (portletów) działających w kontekście Springa. Konfiguracja kontekstu w obrębie każdego z portletów jest umiejscowiona w pliku konfiguracyjnym dedykowanemu poszczególnym portletom. Informacja o lokalizacji głównego pliku konfiguracyjnego zawarta jest w pliku web.xml - deskryptorze rozmieszczenia.

<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/context/applicationContext.xml</param-value>
</context-param>

Bardzo ważnym elementem konfiguracji głównego kontekstu springowego jest definicja resolvera (sic! ale nie po polskiemu) widoku. Jego zadaniem jest przekształcanie logicznych nazw podawanych we wnętrzu obiektu ModelAndView zwracanego z kontrolerów na konkretne zasoby jsp. W definicji tego beana podaje się klasę widoku, która będzie odpowiedzialna za obsługę stron JSP z wykorzystaniem tagów JSTL.

<!-- Default View Resolver -->
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="cache" value="false"/>
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>

Właściwości prefix i suffix powodują, że każda logiczna nazwa zwrócona z kontrolera poprzedzona zostanie wartością prefix i uzupełniona wartością suffix.

Jeśli w kodzie kontrolera wystąpi następujący kod:

return new ModelAndView("greetingView");

to będzie on znaczył, że w wyniku działania resolvera widoku (przy jego powyższej konfiguracji) nastąpi próba odwołania się do zasobu:

/WEB-INF/jsp/greetingView.jsp

Dla potrzeb tej prezentacji predefiniowana zawartość pliku konfiguracji kontekstu jest wystarczająca i nie wymaga nanoszenia w nim jakichkolwiek zmian. Konieczne będzie tylko stworzenie pliku konfiguracji kontekstu dedykowanego do obslugi naszego portletu.


Konfiguracja kontekstu springowego dla portletu

Springowy kontekst portletów może być przechowywany w dowolnym podkatalogu katalogu WEB-INF. W naszym przypadku pliki konfiguracyjne umiejscowione są w katalogu /WEB-INF/context/portlet .
Pierwszym krokiem będzie założenie pliku firstspringportlet.xml umiejscowionego w tymże katalogu.


W pliku tym musi zostać zdefiniowanych kilka bardzo istotnych elementów.

W pierwszej jego części definiowane są dwa beany

<bean name="greetingController" class="mw.firstspringportlet.GreetingController"/>
<bean name="goodByeController" class="mw.firstspringportlet.GoodByeController"/>

Parametr "name" określa logiczną nazwę beana, a "class" wskazanie na klasy kontrolerów, które zdefiniowane zostały w jednym z poprzednich kroków.

Każdy portlet może występować w trzech alternatywnych stanach "edit", "help" i "view". W najprostszym przypadku portlet występuje w trybie widoku "view" .

W pliku konfiguracyjnym kotekstu springowego portletu definiuje się prosty obiekt przechwytujący
PortletModeHandlerMapping którego zadaniem jest zdefiniowanie kontrolera domyślnego, który skojarzony będzie z danym trybem portletu.

<bean id="portletModeHandlerMapping" class="org.springframework.web.portlet.handler
.PortletModeHandlerMapping">

<property name="portletModeMap">
<map>
<entry key="view"><ref bean="greetingController"/></entry>
</map>
</property>
</bean>


Powyższy wpis określa, że w przypadku przełączenia portletu w tryb widoku (lub zainicjalizowania go) jako domyślny uruchomiony powinien zostać kontroler "greetingController".

Jeżeli zaistnieje potrzeba odwoływania się do różnych kontrolerów ( w zależności od parametru ), przy założeniu że stan portletu nie ulega zmianie należy zdefiniować nowy obiekt przechwytujący - PortletModeParameterHandlerMapping . Wpis dotyczący tej sytuacji wygląda następująco:

<bean id="portletModeParameterHandlerMapping" class="org.springframework.web.portlet.handler.
PortletModeParameterHandlerMapping">
<property name="portletModeParameterMap">
<map>
<entry key="view">
<map>
<entry key="bye"><ref bean="goodByeController"/></entry>
</map>
</entry>
</map>
</property>
</bean>

Taka definicja oznacza, że w przypadku gdy w żądaniu znajdzie się parameter o wartości "bye" to sterowanie należy przekazać do kontrolera o logicznej nazwie "goodByeController".

Utworzenie plików widoku

W katalogu /WEB-INF/jsp konieczne jest utworzenie dwóch plików : greetingView.jsp i goodByeView.jsp.



W treści pliku znajdował się będzie krótki komunikat tekstowy i link powodujący wysłanie do kontrolera żądania z odpowiednim parametrem. Link umieszczony we wnętrzu portletu musi mieć specjalną konstrukcję, dlatego musi on zostać wygenerowany przy wykorzystaniu dedykowanych do tego celu tagów:

<a href=" <portlet:renderURL portletMode="view">
<portlet:param name="action" value="bye"/>
</portlet:renderURL>">Say Good Bye</a>


Definiowanie portletu

Definicja portletu ma miejsce w pliku konfiguracyjnym /WEB-INF/portlet.xml . Należy dodać w nim następującą sekcję:

<portlet>
<portlet-name>firstspringportlet</portlet-name>
<portlet-class>org.springframework.web.portlet.DispatcherPortlet</portlet-class>
<init-param>
<name>contextConfigLocation</name>
<value>/WEB-INF/context/portlet/firstspringportlet.xml</value>
</init-param>
<supports>
<mime-type>text/html</mime-type>
<portlet-mode>view</portlet-mode>
</supports>
<portlet-info>
<title>This is the first portlet in Spring Technology.</title>
</portlet-info>
</portlet>

Definiuje ona portlet, a następnie jako parametr podaje lokalizację pliku z definicją kontekstu springowego portletu.

Definiowanie instancji portletu

Specyfikacja dopuszcza istnienie wielu instancji tego samego portletu. Definicja instancji odbywa się w pliku /WEB-INF/portlet-instances.xml . Jest to plik związany z kontenerem JBoss.

Należy dodać w nim następującą sekcję:

<deployment> <instance> <instance-id>FirstSpringPortletInstance</instance-id> <portlet-ref>firstspringportlet</portlet-ref> </instance> </deployment>

Zdefiniowana została instancja portletu i odwołanie do definicji portletu przez jego nazwę.

Definiowanie ułożenia instancji portletu na stronie

Każda instancja portletu może zostać w różny sposób umieszczona na stronie. Za definicję strony odpowiada plik /WEB-INF/springportlet-objects.xml

Należy w nim dodać sekcję informującą gdzie ma leżeć dana instancja portletu - odwołanie następuje przez nazwę instancji.

<window> <window-name>SpringHellowWorldPortletWindow<
/window-name>
<instance-ref>FirstSpringPortletInstance
</instance-ref>
<region>left</region> <height>3</height> </window>

Uruchomienie serwera aplikacji

Przed przeniesieniem aplikacji na serwer należy go uruchomić. W tym celu w środowisku NetBeans należy wybrać Window->Runtime, a następnie w oknie Runtime odnaleźć nazwę serwera JBoss, wskazać go myszką, kliknąć prawym przyciskiem, a z otwartego menu kontekstowego należy wybrać opcję Start.



Deploy aplikacji
Po wystartowaniu aplikacji należy najechać na plik /web/build.xml, kliknąć prawym przyciskiem, z menu kontekstowego wybrać opcję Run Target i potem deployAll. Cały projekt zostanie skomilowany spakowany do jednego pliku war i przekopiowany na serwer aplikacji.


Wyniki:

Po wpisaniu adresu:

http://localhost:3333/portal

otrzymujemy stronę główną portalu. Należy zwrócić uwagę na podanie odpowiedniego portu - 3333 nie jest opcją standardową.

Po wyświetleniu okna portalu, w portlecie Pages znajduje się link do naszej strony: Spring Portlets Sample Page

Po kliknięciu na link ukazuje się strona z naszym portletem.


Materiały:

Zarchiwizowany projekt NetBeans


5 komentarzy:

Anonimowy pisze...

Ciekawy post - i korzystasz ze slusznej technologii :)

Watpliwosci jednak budzi termin "WSRP" - oznacza on Web Services for Remote Portlets ( http://en.wikipedia.org/wiki/WSRP ) - a ja tutaj wcale tej technolgii nie widze uzytej :).

Moze chodzilo ci o Portlet JSR-168 ?

mario pisze...

Dzięki za komentarz - co do WSRP to masz rację - rzeczywiście mylnie sądziłem że określenia Portlet WSRP i Portlet JSR-168 są tożsame. Już poprawiam.

Mariusz Lipiński pisze...

Rzeczywiście post jak i cały blog ciekawe. Teraz niestety nie mam na to czasu, ale kiedyś z pewnością wrócę do tego tekstu, jako że i Spring i Portale żywo mnie interesują. Póki co dodaje link do twojego bloga do sekcji polecanych na moim blogu... www.mariuszlipinski.pl.

Pozdrawiam

Anonimowy pisze...

"Zarchiwizowany projekt NetBeans" - to archiwum jest chyba uszkodzone. Czy można by je jeszcze raz udostępnić?

Anonimowy pisze...

Dzięki za bardzo ciekawe materiały :)
Artykuł bardzo pomocny