Integrate ZK with Spring MVC 3

From Documentation
Revision as of 09:21, 7 November 2012 by Vincent (talk | contribs)

WarningTriangle-32x32.png This page is under construction, so we cannot guarantee the accuracy of the content!

DocumentationSmall Talks2012NovemberIntegrate ZK with Spring MVC 3
Integrate ZK with Spring MVC 3

Author
Vincent Jian, Engineer, Potix Corporation
Date
November 06, 2012
Version
ZK 6.0.2/6.5.0 , Spring MVC 3.1.2

Introduction

Spring MVC is a request-based Model-View-Controller web framework. It is easy to define page flow with Spring MVC. However, when the website is getting complex, it is hard to maintain the page flows. Thus, it is not a bad idea to implement some part of functions by component-based (ajax-based) framework like ZK framework to reduce the page flows. This article will demonstrate how to communite between Spring MVC to ZK MVVM with a simple shopping cart sample.

Page flow of sample project

The typical shopping cart page flow is showen below.

Zkspringmvc-flow1.png

Here we can replace the loop part (buy one product -> view cart -> buy another product -> view cart) with ZK to simplify the process as showed below.

Zkspringmvc-flow2.png

Setup the sample project

In this article, we use Eclipse with m2eclipse plugin to create a new ZK Maven project, check the installation guide here.

  • First, we need to add Spring MVC dependency in the pom.xml file.
<!-- Spring MVC dependency -->
<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-webmvc</artifactId>
	<version>3.1.2.RELEASE</version>
</dependency>
<!-- ZK dependency -->
<!-- ommitted -->
  • Then, define Spring MVC DispatherServlet in web.xml file.
<!-- Spring MVC servlet -->
<servlet>
	<servlet-name>springmvc</servlet-name>
	<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
	<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
	<servlet-name>springmvc</servlet-name>
	<url-pattern>/</url-pattern>
</servlet-mapping>
<!-- ZK servlet -->
<!-- ommitted -->
  • Finally, create a [servlet-name]-servlet.xml file under WEB-INF folder. Note that the file name pattern must match the servlet name defined in web.xml, in this sample the file name is springmvc-servlet.xml. In this file we can define the ViewResolver.
<beans ...>
	<mvc:annotation-driven />
	<mvc:resources location="/images/" mapping="/img/**" />
	
	<context:component-scan base-package="demo.controller.springmvc" />
	<context:component-scan base-package="demo.data.service" />
	
	<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<property name="prefix" value="/WEB-INF/" />
		<property name="suffix" value="" />
	</bean>
</beans>

Project Structure

Zkspringmvc-project.png

  • package demo.controller.springmvc
    • FormController.java - put all form action submit here.
    • PageFlowController.java - define the page flows here.
  • package demo.view.zk
    • CartViewModel.java - the cart view model used in cart.zul file.
    • ProductViewModel.java - the product view model used in product.zul file.

Communiation between Spring MVC and ZK MVVM

The scenario we are trying to do is after user login, we dispatch the path to zul page in Spring MVC controller class. In the zul page we can operate the add product to shopping cart by ZK easily without complex form submit procedure. Finally, we can pass the items in shopping cart to Spring MVC controller class with a single form submit operation.

Spring MVC Controller to ZK MVVM

First, if user is login successful, we will redirect the path to shop (use redirect instead of forward to avoid duplicate form submission problem when user refresh browser page). Here is the code snippet of PageFlowController.java that handle the request.

@RequestMapping(value = "/shop", method = RequestMethod.GET)
public String shop(ModelMap model, HttpSession session) {
	if (isLogged(session)) {
		model.addAttribute("productList", prodDao.findAll());
		return "zul/shopping.zul";
	}
	return "redirect:index";
}

Here you can see line 4 the product list has been stored in request scope, and will forward the request to shopping.zul page which include product.zul and cart.zul page in line 5.

<!-- shopping.zul -->
<?page title="Shopping Cart Sample - Purchase" ?>
<zk>
	<borderlayout>
		<center title="Product List">
			<include hflex="1" src="product.zul" />
		</center>
		<south size="35%" title="Shopping Cart">
			<include hflex="1" src="cart.zul" />
		</south>
	</borderlayout>
</zk>
<!-- product.zul -->
<zk>
	<grid model="@bind(vm.productList)" vflex="1" 
		apply="org.zkoss.bind.BindComposer" viewModel="@id('vm') @init('demo.view.zk.ProductViewModel')">
		<columns>
			<column width="212px" />
			<column label="Name" />
			<column label="Price" />
			<column label="Add to Cart" />
		</columns>
		<template name="model">
			<row>
				<image src="/img/noimage.png" />
				<label value="@load(each.name)" />
				<label value="@load(each.price) @converter('formattedNumber', format='$ #,###,###')" />
				<cell>
					<spinner value="@bind(each.quantity)" constraint="no negative" />
					<button label="Add" onClick="@global-command('addCart', product=each)" />
				</cell>
			</row>
		</template>
	</grid>
</zk>

In product.zul, we can display product list with MVVM pattern. Here is how we get the product list in ProductViewModel.

public class ProductViewModel {
	
	private List<Product> productList;
	
	@Init
	public void init(@ExecutionParam("productList") List<Product> productList) {
		this.productList = productList;
	}
	
	public List<Product> getProductList() {
		return productList;
	}
}

Since the product is stored in request scope, thus we can retrieve the data from ZK Execution scope in line 6. Now, we have successfully pass required data from Spring MVC to ZK MVVM.

ZK MVVM to Spring MVC Controller

Conclusion

Download

Comments



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