From Documentation

Jump to: navigation, search




  • Author
    Robbie Cheng, Engineer, Potix Corporation
  • Date
    May 18, 2007
  • Version
    Applicable to ZK 2.3.1 and later.
Applicable to zreg 0.8 and later.
Applicable to Java 5.0 and later.
Applicable to Hibernate 3.2.2.ga and later.
Applicable to HSQLDB 1.8.0 and later.


Contents

Introduction

Sign-on system is common used in variety of websites,and it is on-going trend to support multi-languages of web application in the future. This article introduces you how to integrate a multi-languages sign-on system to your existing websites with three of the following marco components,

  • login, used to verify user's account
  • signup, used to sign up an new account
  • pwdrecovery, used to recover user's password


To simplify the job of database management, a default database enviorment is constructed. Hibernate, and connection pool are used for better database resource management. As for database, I adopt Hypersonic database which is easy to config, and easy to use.


Prerequisites

Download Required jar files

To use this sign-on system requires jar files of Hibernate and HSQLDB, but all of required jar files are included in the following file

  • unzip this file
  • put zreg.jar file under \lib\ directory to $TOMCAT_HOME\shared\lib
  • put all of jar files under \lib\ext\hibernate directory to $TOMCAT_HOME\shared\lib or the webroot\WEB-INF\lib
  • put hsqldb.jar file under \lib\ext\hsqldb to the directory of $TOMCAT_HOME\common\lib

Prepare Database Enviorment

Please follow the following steps to create a database for sign-on system.

1. Copy the following lines into a file, ex. account.sql

  create table account(
	  accountid INT NOT NULL,
	  firstname VARCHAR(20) NOT NULL,
	  lastname VARCHAR(20) NOT NULL,
	  username VARCHAR(20) NOT NULL,
	  password VARCHAR(20) NOT NULL,
	  email VARCHAR(20)NOT NULL,
	  question VARCHAR(100) NOT NULL,
	  confirmanswer VARCHAR(20) NOT NULL,
	  regtime TIMESTAMP NOT NULL,
	  primary key (accountId)
  );

  CREATE TABLE id_gen (
   gen_key VARCHAR(20) NOT NULL,
   gen_value INTEGER NOT NULL,
   primary key (gen_key)
  );

  INSERT INTO id_gen VALUES('accountId',1);

2. Open a command line program and change directory to $TOMCAT_HOME\common\lib

3. Execute the following command to activate a client program of database management

  java -cp hsqldb.jar org.hsqldb.util.DatabaseManager

4. Fill in the table with the following attributes

  • Type:HSQL Database Engine Standalone
  • Driver:org.hsqldb.jdbcDriver
  • URL:jdbc:hsqldb:file:/hsql/account
  • User:sa
  • Password:

5. File -> Open Script

6. Load the sql file ex.account.sql, and Press Execute button

7. If this SQL script is executed successfully, you should see the result shown in Figure 1

Hsqldb.gif

Figure 1: Successful Message


8. File -> Exit

Configuration of Hibernate and Connection Pool

1. Enable the following definitions of listener in zk.xml

  <!-- Configure the Hibernate SessionFactory Lifecycle.-->
  <listener>
	<description>Hibernate SessionFactory Lifecycle</description>
	<listener-class>org.zkoss.zkplus.hibernate.HibernateSessionFactoryListener</listener-class>
  </listener>
	
  <!-- Configure the Hibernate "Open Session In View" Session Lifecycle -->
  <listener>
	<description>Hibernate "Open Session In View" Session Lifecycle</description>
	<listener-class>org.zkoss.zkplus.hibernate.OpenSessionInViewListener</listener-class>
  </listener>

  <!-- Hibernate thread session context handler -->	
  <listener>
	<description>Hibernate thread session context handler</description>
	<listener-class>
		org.zkoss.zkplus.hibernate.HibernateSessionContextListener
	</listener-class>
  </listener>


2. These listeners are used for using open-session-in-view of Hibernate in ZK (detail) . Add JNDI definition of Connection pool to context.xml under $TOMCAT_HOME/conf as follows

<Resource name="jdbc/hsql" username="sa" password=""
url="jdbc:hsqldb:file:/hsqldb/account"
auth="Container" defaultAutoCommit="false"
driverClassName="org.hsqldb.jdbcDriver" maxActive="20"
timeBetweenEvictionRunsMillis="60000"
type="javax.sql.DataSource"/>


How to Embedded a Sign-On System to Your Existing Web Application

Next,I am going to demonstrate you how to integrate this sign-on system into your application by giving an example. The state chart of this demo system is shown in Figure 2 which is composed of four pages, including login.zul, signup.zul, pwdrecovery.zul and the fake target of this demo, hello.zul. hello.zul will display two different kinds of message for two situations, visiting with successfully login, and visiting withou login.

Statechart.gif

Figure 2: State Chart of Sign-on System


In the following paragraph, I am going to introduce functions of these three macro components independently, and how they interact with each other.

  • Create login.zul page as follows,
  <?taglib uri="http://www.zkoss.org/dsp/web/core" prefix="c"?>
  <window width="300px" title="${c:l('app.login')} ZK" border="normal" 
  style="text-align: center" onOK="login.verifyAccount()">
	<login id="login" signupURL="signup.zul" pwdrecoveryURL="pwdrecovery.zul" 
	onLogin="redirect(event.data)">

	 <zscript><![CDATA[
	   void redirect(String username){
		  Executions.sendRedirect("hello.zul?username=" + username);
	   }
	  ]]></zscript>

  </login>
  </window>
  • signupURL: to specify URL of singup button, if not specified, "sign-up" button wont' appear
  • pwdrecoveryURL: to specify URL of password recovery button, if not specified, "password-recovery" button wont' appear
  • onLogin: to register an onLogin event listener to get username after successful verification


In the above example, we declare a redirect method to transfer this page to "hello.zul" along with the username if the user pass the verification. Figure 3 shows the login page.

Login.gif

Figure 3: Login page


  • Create signup.zul page as follows,
  <?taglib uri="http://www.zkoss.org/dsp/web/core" prefix="c"?>
  <window width="400px" title="${c:l('app.pwdrecovery')} ZK" border="true" 
  style="text-align: center" onOK="signup.validateAll()">
	<signup id="signup" targetURL="login.zul"/>
  </window>
  • targetURL: to specify which page to redirect to after user's submission, default is "login.zul"


In Figure 4, there is a CAPTCHA to determine whether the subscriptor is a human or not, and a password strength status with progressbar will appear after the user type his/her password.

Signup.gif

Figure 4: Sign-up page


  • Create pwdrecovery.zul page as follows,
<?taglib uri="http://www.zkoss.org/dsp/web/core" prefix="c"?>
<window width="300px" title="${c:l('app.pwdrecovery')} ZK" border="true" 
style="text-align: center" onOK="pwd.verifyAccount()">
<pwdrecovery id="pwd"/>
</window>


The user could recover his/her password by answering the question which is submitted after registration. Figure 5 shows the password recovery page.

Pwdrecovery.gif

Figure 5: Password Recovery page


  • Create a target page, ex.hello.zul page as follows,
  <window title="Sign-on demo" border="normal" width="200px">
	 <label value="Hi {param.username}" if="{param.username != null}"/>
	 <label value="Please login first." if="{param.username == null}"/>
  </window>


In hello.zul page, two messages are prepared, one for sucessful login, and the other for visitor without login. Figure 6 shows the result when the user login successfully.

Hello2.gif

Figure 6: Successful login message


Figure 7 shows the result when the user go to hello.zul without login.

Hello1.gif

Figure 7: Withou login message


  • Feature of Multi-Language

All of these three macro components support three kinds of language, English, simplified Chinese, and traditional Chinese. If you change your language preference of browser to zh_TW, the result of password recovery is shown in Figure 8.


Zh tw.gif

Figure 8: pwdrecovery.zul of traditional Chinese version

Example Code

Download the example code here.


Summary

Sign-on system is basic but indispensable for web applications. This article introduce you how to build a sign-on system with macro components. However, in order to simplify the job of database management and due to the destiny of data model which is not easy for flexible requirements, these macro components is bundled with a pre-defined data model. In the future, we might figure out a way to separate data model from the macro components.




Copyright © Potix Corporation. This article is licensed under GNU Free Documentation License.
You got stuck here?
Let us know why!
For questions please use the forum