ZK is a great framework but the focus is on the GUI so other frameworks may be needed. This article by Hans-Jurgen Schumacher and Markus Staeuble discusses the integration of ZK with other frameworks. One of the most important frameworks is Spring. This is very often used together with Hibernate. As we will see, it is very easy to integrate ZK with other frameworks. Once it was difficult to use captchas but in the latest ZK versions, ZK supports captchas natively.
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 xmlns:p="http://www.zkoss.org/2005/zul"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
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"
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
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 xmlns:p="http://www.zkoss.org/2005/zul"
xmlns:h="http://www.w3.org/1999/xhtml"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
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.
Sign up for a Packt account to see the rest of this article
Now that you've read a few articles, you might want to consider signing up for a Packt account. It takes a matter of seconds, will give you access to all the articles on PacktPub.com, and once you've signed up you'll be returned here to carry on reading your article.
Furthermore, you'll gain access to nine free ebooks, and be offered a free trial of PacktLib, Packt's online library. Simply enter your details here, or log in to your existing account.




Post new comment