7 min read

Integration with the Spring Framework

Spring is one of the most complete lightweight containers, which provides centralized, automated configuration, and wiring of your application objects. It improves your application’s testability and scalability by allowing software components to be first developed and tested in isolation, then scaled up for deployment in any environment. This approach is called the POJO (Plain Old Java Object) approach and is gaining popularity because of its flexibility.

So, with all these advantages, it’s no wonder that Spring is one of the most used frameworks. Spring provides many nice features: however, it works mainly in the back end. Here ZK may provide support in the view layer. The benefit from this pairing is the flexible and maturity of Spring together with the easy and speed of ZK. Specify a Java class in the use attribute of a window ZUL page and the world of Spring will be yours. A sample ZUL looks like:

<?xml version="1.0" encoding="UTF-8"?>
<p:window

xsi_schemaLocation="http://www.zkoss.org/2005/zul
http://www.zkoss.org/2005/zul "
border="normal" title="Hello!"
use="com.myfoo.myapp.HelloController">

Thank you for using our Hello World Application.
</p:window>

The HelloController points directly to a Java class where you can use Spring features easily.

Normally, if a Java Controller is used for a ZUL page it becomes necessary sooner or later to call a Spring bean. Usually in Spring you would use the applicationContext like:

ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
UserDAO userDAO = (UserDAO) ctx.getBean("userDAO");

Then the userDAO is usable for any further access. In ZK there is a helper class SpringUtil. It wrapps the applicationContext and simplifies the code to:

UserDAO userDAO = (UserDAO) SpringUtil.getBean("userDAO");

Pretty easy, isn’t it? Let us examine an example.

Assume we have a small web application that gets flight data from a flight table. The web.xml file looks like:

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4"


xsi_schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<display-name>IRT-FLIGHTSAMPLE</display-name>

<filter>
<filter-name>hibernateFilter</filter-name>
<filter-class>
org.springframework.orm.hibernate3.support.OpenSessionInViewFilter
</filter-class>
</filter>
<filter-mapping>
<filter-name>
hibernateFilter
</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext-jdbc.xml
,classpath:applicationContext-dao.xml
,classpath:applicationContext-service.xml
,classpath:applicationContext.xml
</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>

<session-config>
<!-- Default to 30 minute session timeouts -->
<session-timeout>30</session-timeout>
</session-config>

<mime-mapping>
<extension>xsd</extension>
<mime-type>text/xml</mime-type>
</mime-mapping>

<servlet>
<description>
<![CDATA[The servlet loads the DSP pages.]]>
</description>
<servlet-name>dspLoader</servlet-name>
<servlet-class>
org.zkoss.web.servlet.dsp.InterpreterServlet
</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>dspLoader</servlet-name>
<url-pattern>*.dsp</url-pattern>
</servlet-mapping>

<!-- ZK -->
<listener>
<description>
Used to cleanup when a session is destroyed
</description>
<display-name>ZK Session Cleaner</display-name>
<listener-class>
org.zkoss.zk.ui.http.HttpSessionListener
</listener-class>
</listener>
<servlet>
<description>ZK loader for ZUML pages</description>
<servlet-name>zkLoader</servlet-name>
<servlet-class>
org.zkoss.zk.ui.http.DHtmlLayoutServlet
</servlet-class>
<!-- Must. Specifies URI of the update engine
(DHtmlUpdateServlet).
It must be the same as <url-pattern> for the update
engine.
-->
<init-param>
<param-name>update-uri</param-name>
<param-value>/zkau</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>zkLoader</servlet-name>
<url-pattern>*.zul</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>zkLoader</servlet-name>
<url-pattern>*.zhtml</url-pattern>
</servlet-mapping>
<servlet>
<description>The asynchronous update engine for ZK
</description>
<servlet-name>auEngine</servlet-name>
<servlet-class>
org.zkoss.zk.au.http.DHtmlUpdateServlet
</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>auEngine</servlet-name>
<url-pattern>/zkau/*</url-pattern>
</servlet-mapping>

<welcome-file-list id="WelcomeFileList">
<welcome-file>index.zul</welcome-file>
</welcome-file-list>

</web-app>

Furthermore let’s have a small ZUL page that has the interface to retrieve and show flight data:

<?xml version="1.0" encoding="UTF-8"?>
<p:window


xsi_schemaLocation="http://www.zkoss.org/2005/zul
http://www.zkoss.org/2005/zul "
id="query" use="com.myfoo.controller.SampleController">

<p:grid>
<p:rows>
<p:row>
Airline Code:
<p:textbox id="airlinecode"/>
</p:row>
<p:row>
Flightnumber:
<p:textbox id="flightnumber"/>
</p:row>
<p:row>
Flightdate:
<p:datebox id="flightdate"/>
</p:row>
<p:row>
<p:button label="Search" id="search"/>
<p:separator width="5px"/>
</p:row>
</p:rows>
</p:grid>

<p:listbox width="100%" id="resultlist" mold="paging" rows="21"
style="font-size: x-small;">
<p:listhead sizable="true">
<p:listheader label="Airline Code" sort="auto"
style="font-size: x-small;"/>
<p:listheader label="Flightnumber" sort="auto"
style="font-size: x-small;"/>
<p:listheader label="Flightdate" sort="auto"
style="font-size: x-small;"/>
<p:listheader label="Destination" sort="auto"
style="font-size: x-small;"/>
</p:listhead>
</p:listbox>
</p:window>

As you can see, the use attribute of the ZUL page is the link to the SampleController. The SampleController handles and controls the objects. Let’s have a short look at the SampleController sample code:

public class SampleController extends Window {

private Listbox resultlist;
private Textbox airlinecode;
private Textbox flightnumber;
private Datebox flightdate;
private Button search;
/**
* Initialize the page
*/
public void onCreate() {
// Components
resultlist = (Listbox)
this.getPage().getFellow("query").getFellow("resultlist");
airlinecode = (Textbox)
this.getPage().getFellow("query").getFellow("airlinecode");
flightnumber = (Textbox)
this.getPage().getFellow("query").getFellow("flightnumber");
flightdate = (Datebox)
this.getPage().getFellow("query").getFellow("flightdate");
search = (Button)
this.getPage().getFellow("query").getFellow("search");
search.addEventListener("onClick", new EventListener() {

public void onEvent(Event event) throws Exception {
performSearch();
}
});
}
/**
* Execute the search and fill the list
*/
private void performSearch() {
//(1) List<Flight> flightlist = ((FlightService)
SpringUtil.getBean("flightService")).
getFlightBySearch(airlinecode.getValue(),
flightnumber.getValue(),
flightdate.getValue(),"");
resultlist.getItems().clear();
for (Flight aFlightlist : flightlist) {
// add flights to list
}
}
}
/* (1)-shows the integration of the Spring Bean*/

Just for completion the context file for Spring is listed here with the bean that is called.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">

<beans>

<bean id="txProxyTemplate" abstract="true"
class="org.springframework.transaction.
interceptor.TransactionProxyFactoryBean">
<property name="transactionManager">
<ref bean="transactionManager"/>
</property>
<property name="transactionAttributes">
<props>
<prop key="save*">PROPAGATION_REQUIRED</prop>
<prop key="add*">PROPAGATION_REQUIRED</prop>
<prop key="remove*">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>

<bean id="flightService" parent="txProxyTemplate">
<property name="target">
<bean class="com.myfoo.services.impl.FlightServiceImpl">
<property name="flightDAO">
<ref bean="flightDao"/>
</property>
</bean>
</property>
</bean>

</beans>

In short we have learned how to use Spring with ZK and about the configurations. We have seen that the integration is quite smooth and also powerful.


Subscribe to the weekly Packt Hub newsletter

* indicates required

LEAVE A REPLY

Please enter your comment!
Please enter your name here