Contact List with ZK and Spring

From Documentation
DocumentationSmall Talks2006OctoberContact List with ZK and Spring
Contact List with ZK and Spring

Author
Minjie Zha, Student, Software Institute specialising Software Engineering at Nanjing University, China.
Date
October 30, 2006
Version
Applicable to ZK 2.1.1 and later.


Purpose

In this article, I want to show you a small project called Contact List implemented with ZK and Spring. This Online Contact List stores users' contact lists, and provides functions like adding and deleting contact items. I wrote it to help me study the ZK framework. In order to highlight the essential ways of using ZK, I only keep its main part here.

The sample project use NetBeans5.0 as programming environment and Tomcat5.5 as Web Server. MySQL5.0 is the database system to store data. And about how to set up the environment for Tomcat, Spring, MySQL and JDBC, please refer ZK with Spring DAO and JDBC by Andrew Ho.

Design Database

The user information and contact list data need to be persisted in the database. So we need two database tables: users and items. Simply, we created the two tables using the following DDL codes:

CREATE TABLE `users` (
  `id` int(10) unsigned NOT NULL auto_increment,
  `username` char(30) NOT NULL,
  `password` char(50) NOT NULL,
  PRIMARY KEY  (`id`)
) ;
CREATE TABLE `items` (
  `id` int(10) unsigned NOT NULL auto_increment,
  `user_id` int(10) unsigned NOT NULL,
  `name` char(30) NOT NULL,
  `phone` char(15) default NULL,
  `email` char(30) default NULL,
  PRIMARY KEY  (`id`)
) ;


Domain Objects

Corresponding to the tables, we need two classes to represent rows in them. They are User.java and Item.java defined like this:

public class User {
    private int id;
    private String username;
    private String password;

    public User(){}
    //getters/setters are omitted
}
public class Item {
    private int id;
    private int userId;
    private String name;
    private String phone;
    private String email;
    
    public Item(){}
    // getters/ setters are omitted
}


DAOs using JdbcTemplate

Now that we have set up the database, we are going to write some DAOs which handle the boring database operations.

For each table, one DAO is required. We define the following interfaces:

public interface UserDAO {
    public User insert(User user);  // add user
    public List findByUsername(String username);
}
public interface ItemDAO {
    public Item insert(Item item);  // add new item
    public Item update(Item item);  // update item
    public void delete(Item item);  //  delete item
    public Item findById(int id);
    public List findAll();    // get all items
    public List findAllByUser(int user_id);
}
<source lang="xml" >


Then, we implement two concrete classes, UserDAOImpl and ItemDAOImpl, which do the actual functions provided by DAOs. Here, we use JdbcTemplate as provided by Spring to access the database. The JdbcTemplate requires a datasource to connect to the database. We give a DriverManagerDataSource to it. So, we have to put these lines in Spring configuration file contact-config.xml.

<source lang="xml" >
<bean id="dataSource"
    class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="driverClassName">
        <value>com.mysql.jdbc.Driver</value>
    </property>
    <property name="url">
        <value>jdbc:mysql://localhost:3306/contact_list</value>
    </property>
    <property name="username">
        <value>contact</value>
    </property>
    <property name="password">
        <value>contact</value>
    </property>
</bean>

<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
    <constructor-arg>
        <ref bean="dataSource"/>
    </constructor-arg>
</bean>

Now, we can use jdbcTemplate in DAOs. Because the codes are too boring, I won't list them here. Please read the source code if you want to know more.


User Interaction Pages

Till now, we have finished all the tasks related to database. Then, we are going to write pages which interact with users. First, let's consider the process that user may use this Contact List. They need to register to the system first, then login, and then they will see their own contact list. So, we need three pages, one for Login window, one for Register window, and the other for Contact List window.

Now, let's write the ZUL files.

  • login.zul
  <?xml version="1.0" encoding="UTF-8"?>
  <?page title="Contact List" ?>
  <window id="loginWnd" title="User Login" border="normal" 
	  width="350px" use="hysteria.contact.ui.LoginWindow" >
	  <grid>
		  <rows>
			  <row>Username: <textbox id="username"/></row>
			  <row>Password: <textbox id="password" type="password"/></row>
			  <row>
				  <button label="Register" onClick="loginWnd.onRegister()" />
				  <button label="Login" onClick="loginWnd.onLogin()" />
			  </row>
		  </rows>
	  </grid>
  </window>


  • register.zul
  <?xml version="1.0" encoding="UTF-8"?>
  <window id="registerWnd" title="User Registeration" border="normal" 
	  width="400px" use="hysteria.contact.ui.RegisterWindow">
	  <zscript>
		  void reset(){
			  ...
		  }
		  void register(){
			  ...
		  }
	  </zscript>
	  <grid>
		  <rows>
			  <row>Username: <textbox id="username" />*,a-zA-Z,0-9</row>
			  <row>Password: <textbox id="password" type="password"/>*</row>
			  <row>Confirm Password: <textbox id="con_password" type="password"/>*</row>
			  <row>
				  <button label="Reset" onClick="reset()"/>
				  <button label="Register" onClick="register()"/>
				  <button label="Back to Login" onClick="registerWnd.back()"/> 
			  </row>
		  </rows>
	  </grid>
  </window>


  • myContact.zul
  <?xml version="1.0" encoding="UTF-8"?>
  <window id="contactWnd" title="Contact List" border="normal"
	  use="hysteria.contact.ui.ContactWindow">
	  <zscript>
		  void reset(){...}
		  void add(){...}
		  void delete(){...}
	  </zscript>
	  <tabbox width="900px">
		  <tabs><tab label="Item List"/><tab label="New Item"/></tabs>
		  <tabpanels width="400px">
			  <tabpanel>
				  Contacts:
				  <listbox id="items" width="700px" onCreate="contactWnd.showList()">
					  <listhead>
						  <listheader label="Name"/>
						  <listheader label="Phone"/>
						  <listheader label="Email"/>
					  </listhead>
				  </listbox><separator/>
				  <button label="Delete" onClick="delete()"/>
			  </tabpanel>
			  <tabpanel>
				  <grid>
					  <rows>
						  <row>Name: <textbox id="name"/>*</row>
						  <row>Phone:<textbox id="phone"/></row>
						  <row>Email:<textbox id="email"/></row>
						  <row>
							  <button label="Reset" onClick="reset()"/>
							  <button label="Add" onClick="add()"/>
						  </row>
					  </rows>
				  </grid>
			  </tabpanel>
		  </tabpanels>
	  </tabbox>
  </window>

Note that we use tabpanel component in myContact.zul. And this provides both add item function and delete item function to the user at the same time.

With the use attribution in each ZUL file, we create one JAVA file for each of them. In these JAVA files, we will write codes to handle events fired by users.


Business Layer

Now, we have set up persistent layer and presentation layer. Next, we will write a business layer to connect them. In the Contact List , we have register, login, add items, delete items, and view items functions. So, in the business layer interface, we will have these methods:

public interface ContactBusiness {
    public boolean register(User user);
    public int login(User user);
    public boolean addItem(Item item);
    public List getAllItem(int user_id);
    public boolean deleteItem(Item item);
}

The concrete class for this interface will interact with persistent layer to finish the above functions. And the JAVA classes in presentation layer will invoke its methods in order to achieve the users' requests. This class will be treated as a bean in Spring configuration file.


ZK with Spring Beans

We have implemented presentation layer with ZK and business and persistent layer with Spring. But we still don't know how to integrate the two frameworks. How can we access Spring beans in ZK?

ZK provides an easy way to access Spring beans. We only need to put these lines in zscript element or JAVA files:

ApplicationContext ctx = 
    WebApplicationContextUtils.getRequiredWebApplicationContext(
      (ServletContext)getDesktop().getWebApp().getNativeContext());
    ContactBusiness contact = (ContactBusiness)ctx.getBean("contactBusiness");

So, we can access Spring beans in JAVA files for each of the ZUL files, and finish what users want to do.


Editor's Note: Since version 2.1.1, ZK has provided a SpringUtil utility class. The above codes can be simplified as follows:

ContactBusiness contact = (ContactBusiness)SpringUtil.getBean("contactBusiness");


Sample

  • You can download the source files: ContactList.zip or ContactList_hibernate.zip: Source code with hibernate layer written by Ricardo Soares
  • Unzip it, and put “web” in the webapps directory under Tomcat.
  • MySQL database script is the contact.sql file. After create the database, you should give privileges to a new user called “contact”, with password “contact”. Here is the command:
  grant all on contact_list.* to 'contact'@'localhost' identified by 'contact';
  • Launch tomcat and type in http://localhost:8080/contact/ in your browser. (Note: don't forget to put ZK libraries, Spring libraries and JDBC libraries in Tomcat common/lib directory)
  • Now, you can register a new user and add your contact list.
  • Sample web application:

Screenshot10.png


Further Development

Add function to the program which will let user modify items.


Reference

  1. ZK with Spring DAO and JDBC by Andrew Ho
  2. ZK Developer's Reference


Ruler.gif


Minjie Zha is a bachelor's student in Software Institute specialising Software Engineering at Nanjing University, China. He did several projects with J2ME and J2EE. He is interested in new technologies and open source projects such as Tapestry, Spring, Lucene, Ruby, and also ZK.




Copyright © Minjie Zha. This article is licensed under GNU Free Documentation License.