4 września 2007

Integracja JSF 1.2 i Spring z pomocą Red Hat Developer Studio

Artykuł ten jest właściwie nieco rozwlekłym komentarzem do artykułu "Próba połączenia JSF i Spring" napisanego przez Mariusza Wójcika. Mariusz pokazał w nim jak zintegrować ze Springiem JSF 1.1, jednak trochę się pozmieniało i integracja z JSF 1.2 wymaga pewnego komentarza. Przy okazji pokaże pewne dobroci nowego IDE ze stajni Red Hat. W zasadzie wystarczyło by powiedzieć, że tak jak w przypadku JSF 1.1 należało w pliku faces-config.xml umieścić konfigurację:

<application>
<variable-resolver>
org.springframework.web.jsf.DelegatingVariableResolver
</variable-resolver>
</application>

tak w przypadku JSF 1.2 trzeba użyć Spring’a w wersji co najmniej 2.1 i zamiast powyższego umieścić tam:

<application>
<el-resolver>
org.springframework.web.jsf.el.DelegatingFacesELResolver
</el-resolver>
</application>

ale przydałoby się jeszcze przetestować że to działa. Przetestujemy to poprzez modyfikację przykładowego projektu dostępnego w Ret Hat Developer Studio, o którym napisałem w artykule "Już jest Red Hat Developer Studio". Zaczynamy więc od utworzenia projektu JSF 1.2. Uruchamiamy kreatora New > Project > JSF Project. Wybieramy opcje jak na poniższej ilustracji i klikamy Next:



Upewnijmy się teraz, że jako Runtime wybraliśmy serwer Tomcat (który wcześniej należało zdefiniować) a nie JBoss. Klikamy Finish i mamy działający projekt JSF 1.2 + Facelets. Zanim przejdziemy do integracji ze Spring’iem upewnijmy się, że projekt działa. W tym celu najwygodniej jest użyć specjalnego guziczka dostępnego w naszym IDE. Kliknięcie go powoduje odpalenie wbudowanej w Eclipse przeglądarki z URL’em aktywnego (otwartego w drzewie zasobów) projektu. Widać to na poniższej ilustracji:



Ponieważ chcemy, aby nasz przykład był możliwie prosty ograniczymy się do przeniesienia elementu zarządzanego (ang. managed bean) z zakresu JSF do zakresu Spring. Z pliku faces-config.xml usuwamy więc fragment:

<managed-bean>
<managed-bean-name>person</managed-bean-name>
<managed-bean-class>demo.Person</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
<managed-property>
<property-name>name</property-name>
<value />
</managed-property>
</managed-bean>

Odpowiadającą definicję będziemy musieli umieścić w kontekście Spring’a, tworzymy więc odpowiedni plik definujący ten kontekst. Klikamy prawym guzikiem na katalogu WEB-INF i wybieramy New > Other > Spring Bean Definition > Next. Teraz podajemy nazwę pliku. Standardowo powinno to być applicationContext.xml, ale może być też cokolwiek innego. Ja wybieram spring.xml. Klikamy Finish. Uwaga! Plik się utworzył poprawnie, ale okienko kreatora się nie zamknęło (taki mały błąd), aby je zamknąć możemy kliknać Cancel. Do nowo utworzonego pliku dodajemy definicję elementu zarządzanego Spring, odpowiadającą temu, co usunęliśmy z JSF:

<bean id="person" class="demo.Person">
<property name="name" value="Name" />
</bean>

Aby plik kontekstu Spring został wczytany dodajemy do pliku web.xml odpowiednią konfigurację pokazaną poniżej. Jeśli nasz plik znajduje się w katalogu WEB-INF i nazywa się applicationContext.xml to pokazany element context-param nie jest konieczny:

<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>

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

Musimy jeszcze do projektu dodać bibliotekę Spring (spring.jar) w wersji co najmniej 2.1 oraz do pliku faces-config.xml dodać, o ile jeszcze tego nie zrobiliśmy, element el-resolver pokazany na początku artykułu i gotowe. O tym, że działa przekonujemy się widząc jako proponowane imię wartość "Name" zdefiniowaną w konfiguracji Spring’a: