Integrate ZK with Spring MVC 3
Vincent Jian, Engineer, Potix Corporation
November 06, 2012
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.
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.
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
- 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. |