Getting started with ZK CDI

From Documentation
DocumentationSmall Talks2010MarchGetting started with ZK CDI
Getting started with ZK CDI

Author
Ashish Dasnurkar, Engineer, Potix Corporation
Date
March 22, 2010
Version
ZK CDI 1.0RC

Download ZK CDI

Introduction

ZK CDI is based on the portable extension mechanism defined in JSR-299 of the Java EE 6 platform. It allows Java EE application developers to seamlessly leverage both ZK and CDI’s powerful set of features for developing enterprise applications.

In addition to the built in features of CDI, ZK CDI provides the following features:

  • Custom variable resolver/EL resolver
  • ZK custom scopes
  • ZK components as managed beans
  • UI event handlers using ZK custom annotation and CDI provided event notification model

Why ZK + CDI

ZK CDI provides seamless integration with CDI to expose CDI services within the ZK framework. It provides enterprise developers the ability to integrate CDI driven applications with a compressive and powerful Ajax front end supplied by ZK. Using CDI and ZK together makes bridging the gap between Java’s EE web tier and Java EE an effortless process.

Getting started with ZK CDI

HelloWorld using ZK CDI Demo

Variable resolver
--index.zul--

<?page title="HelloWorld" contentType="text/html;charset=UTF-8"?>
<?variable-resolver class="org.zkoss.zkplus.cdi.DelegatingVariableResolver"?>
<zk>
<window id="helloWindow" title="HelloWorld" border="normal" width="250px" apply="${helloWorld} ">
<textbox id="guestName" width="150px" />
<button id="sayHelloBtn" label="Say hello"/>
</window>
</zk>

ZK CDI extension provided variable resolver allows us to resolve CDI managed beans by their EL names. Here I use it to resolve HelloWorld controller by its EL name and apply to window component. Notice that HellowWorld is annotated with @Named annotation and according to JSR-299 CDI spec it will be by default resolved for "helloWorld" EL name.

Writing controller class by extending GenericComposer with CDI support

--HelloWorld.java--

@Named
@SessionScoped
public class HelloWorld extends GenericComposer implements Serializable {

	@Inject @ComponentId("guestName") Textbox guestName;
	@Inject @ComponentId("sayHelloBtn") Button sayHelloBtn;
	@Inject @ComponentId("helloWindow") Window helloWindow;
	
	public void sayHello(@Observes @Events("sayHelloBtn.onClick") MouseEvent evt) {
		helloWindow.setTitle("Hello " + guestName.getValue());
	}
}

ZK CDI extension comes with a abstract utility class which can be extended to write controller class that can leverage CDI injection of ZK components and event notification model to write intuitive event handler methods by observing specific event types.

ZK component injection in controller

In addition to EL resolver one can also use ZK CDI extension to inject child components into controller using @Inject annotation along with ZK CDI extension defined @ComponentId qualifier. In order to uniquely identify injection point for each child component ZK CDI extension needs to be provided with actual component ids as @CompoentId qualifier member value. In above example textbox, button and window components defined in index.zul file will be auto injected into HellowWorld controller bean instance. This is similar to GenericForwardComposer wiring composer variables with actual zul components.

Event handlers using ZK CDI custom qualifier
ZK CDI extension also defines @Events qualifier which allows us to define ZK UI event handlers by observing ZK Event types such as MouseEvent, SelectEvent etc. Here I defined onClick event handler for sayHelloBtn by observing on MouseEvent type. Whenever sayhellobtn is clicked ZK framework receives MouseEvent which is later published by ZK CDI extension using CDI event notification model. Any event handling method can @Observes this event type to receive notification and in turn be notified whenever this event type is published. Event handling methods are distinguished by @Events qualifier member values. Developers can also specify same event handler for multiple events separated by a comma in the @Events qualifier member value for example
@Events("btn1.onclick,btn2.onClick")
In above example whenever sayHelloBtn is clicked MouseEvent will be sent to ZK framework which later will be published by ZK CDI extension with correct @Events qualifier value mentioning component id and event name for example sayHelloBtn.onClick. CDI framework then will notify any method that is observing for MouseEvent type and also has the same @Events qualifier member value.

Setup development environment

Setup ZK web application with ZK CDI support

1. Create a ZK web application project by following ZK Installation Guide. Note: ZK CDI extension works with latest ZK 5.0.1 release
2. Download and copy zkcdi.jar to your WEB-INF/lib in the web root folder. Zkcdi.jar should be used as a web application library.
3. Download reflections-0.9.5-RC1.jar from Reflections google code project. Also download all dependant jar files for this project. Copy all files to your web root/WEB-INF/lib folder

Setup Weld with Tomcat

1. Download weld-servlet-1.0.1-Final.jar and copy to your web root/WEB-INF/lib
2. You also need to explicitly specify the servlet listener (used to boot Weld, and control its interaction with requests) in WEB-INF/web.xml in the web root:
<listener>
   <listener-class>org.jboss.weld.environment.servlet.Listener</listener-class>
</listener>
<listener>
   <listener-class>org.jboss.weld.el.WeldELContextListener</listener-class>
</listener>
3. Tomcat has a read-only JNDI, so Weld can't automatically bind the BeanManager extension SPI. To bind the BeanManager into JNDI, you should populate META-INF/context.xml in the web root with the following contents:
<Context>
		<Resource name="BeanManager"
		auth="Container"
		type="javax.enterprise.inject.spi.BeanManager"
		factory="org.jboss.weld.resources.ManagerObjectFactory"/>
</Context>
4. and make it available to your deployment by adding this to the bottom of web.xml
<resource-env-ref>
		<resource-env-ref-name>BeanManager</resource-env-ref-name>
		<resource-env-ref-type>javax.enterprise.inject.spi.BeanManager</resource-env-ref-type>
</resource-env-ref>
5. Add an empty beans.xml file under WEB-INF folder to enable dependency injection by CDI

Note: There are similar instructions available to setup Weld with other application servers & environments. Please refer to Using Weld in other application servers and environments for more information on this.

Real world example using ZK CDI

IBM Developerworks has published a comprehensive article on ZK CDI. The article talks about all ZK CDI features in depth and also guides developers through a real world example code using ZK CDI. You can read it here

References

1. ZK Installation Guide
2. ZK CDI Google Code Project Home
3. Weld Reference Implementation of JSR-299
4. Java EE 6 platform Introduction
5. Using Weld in other application servers and environments

Comments



Copyright © Potix Corporation. This article is licensed under GNU Free Documentation License.