0

Using Spring IOC with ZK

asked 2010-09-02 09:08:15 +0800

newguy2010 gravatar image newguy2010
36

updated 2010-09-02 09:09:44 +0800

I've read some tutorials (small talks) on how to use Spring Inversion of Control mechanism with ZK. However after a couple of days of trying I still can't get it work.

In my maven project webapp folder I have spring-config.xml, web.xml and zk.xml.
In spring-config.xml I specified the bean name, such as:

<bean id="example1" scope="session" class="example.com.ExampleService"></bean>
<bean id="someController" scope="prototype" class="example.com.ControllerClass">
   <constructor-arg ref="example1"/>
</bean>



In the web.xml file
<context-param>
  <param-name>contextConfigLocation</param-name>
  <param-value>classpath: spring-*.xml</param-value>
</context-param>


I've put ContextLoaderListener and RequestContextListener in web.xml file.

In index.zul,
<?variable-resolver class="org.zkoss.zkplus.spring.DelegatingVariableResolver"?>
<window id="window" apply="${someController}">
 <button id="test" />
</window>


In my controller class
I have event methods that correspond to the button.The class extends GenericForwardComposer.
ExampleService is a private field of the controller class, as well as the buttons.
The constructor of the controller class has a parameter ExampleService with the name example1.
I was expecting when I click test it should do something but it doesn't, seems the button is not getting the event. What's wrong with my configuration?

If I don't use Spring it works OK. The event fires correctly. But when I use Spring looks like spring beans and the components inside the page are messed together. Any suggestions to make them work together? Thank you.

delete flag offensive retag edit

11 Replies

Sort by ยป oldest newest

answered 2010-09-03 04:32:47 +0800

vergereau gravatar image vergereau
105 1 2

Hello NewGuy,
:)

Have you add listner for spring in the web.xml ?


Web.xml :

...
<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/spring-config.xml</param-value>
  </context-param>

  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>

  <listener>
    <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
  </listener>
...


Regards, V

link publish delete flag offensive edit

answered 2010-09-03 05:50:48 +0800

newguy2010 gravatar image newguy2010
36

Yes I've put that on.

link publish delete flag offensive edit

answered 2010-09-03 08:14:18 +0800

terrytornado gravatar image terrytornado flag of Germany
9393 3 7 16
http://www.oxitec.de/

updated 2010-09-03 08:17:12 +0800

Try to do it without constructor args


public class ControllerClass.java {


private Button btn;
private ExampleService sample1; // + getter/setter

. . .
}


	<bean id="articleMainCtrl" class="de.forsthaus.webui.article.ArticleMainCtrl" scope="prototype">
		<property name="articleService" ref="articleService" />
	</bean>


	<bean name="articleService" 	class="de.forsthaus.soolaar.backend.service.impl.ArticleServiceImpl">
		<property name="articleDAO" ref="articleDAO" />
	</bean>

	<!-- Articles / Artikelstamm -->
	<bean id="articleDAO" class="de.forsthaus.soolaar.backend.dao.impl.ArticleDAOImpl" />

link publish delete flag offensive edit

answered 2010-09-03 09:20:58 +0800

vergereau gravatar image vergereau
105 1 2

Plop,

It's seems to me for session scope you should add one more line in zk.xml if you have not done it.

<listener>
		<description>ThreadLocal varaibles synchronizer</description>
		<listener-class>org.zkoss.zkplus.util.ThreadLocalListener</listener-class>
	</listener>

	<preference>
		<name>ThreadLocal</name>
		<value>	org.springframework.web.context.request.RequestContextHolder=requestAttributesHolder,inheritableRequestAttributesHolder;
		    	</value>
		
	</preference>





see http://www.zkoss.org/javadoc/3.0.3/zkplus/org/zkoss/zkplus/util/ThreadLocalListener.html

link publish delete flag offensive edit

answered 2010-09-08 18:54:51 +0800

newguy2010 gravatar image newguy2010
36

None of the above works. Any other suggestions?

link publish delete flag offensive edit

answered 2010-09-09 00:25:32 +0800

vergereau gravatar image vergereau
105 1 2

Hy NewGuy2010,

1/ Can you Make a short sample (conf file + java file + zul file) in order to test it.
2/ Which version of zk and Spring did you use ?

link publish delete flag offensive edit

answered 2010-09-09 01:12:10 +0800

newguy2010 gravatar image newguy2010
36

I've resort to use the SpringUtil class but still doesn't work.

A simple example:

Here is my code for EventController

package au.com.zkproject.controller;

import java.util.ArrayList;
import java.util.Arrays;

import org.apache.commons.lang.StringUtils;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.util.GenericForwardComposer;
import org.zkoss.zkplus.spring.SpringUtil;
import org.zkoss.zul.Button;
import org.zkoss.zul.Combobox;
import org.zkoss.zul.Radiogroup;

import au.com.zkproject.service.ConnectionService;
import au.com.zkproject.service.ModelService;

public class EventController extends GenericForwardComposer {
  
 
  private Combobox cbServer; // database server
  private Radiogroup rgDbType;
  
  private transient ConnectionService connectionService;
  private transient ModelService modelService;
  
  public ConnectionService getConnectionService() {
    if (connectionService == null) {
      connectionService = (ConnectionService)SpringUtil.getBean("connectionService");
      setConnectionService(connectionService);
    }
    return connectionService;
  }
  
  public void setConnectionService(ConnectionService connectionService) {
    this.connectionService = connectionService;
  }
  
  public ModelService getModelService() {
    if (modelService == null) {
      modelService = (ModelService)SpringUtil.getBean("modelService");
      setModelService(modelService);
    }
    return modelService;
  }
  
  public void setModelService(ModelService modelService) {
    this.modelService = modelService;
  }
  
  public void onFocus$cbServer(Event evt) {
    final String dbType = rgDbType.getSelectedItem().getLabel();
    if (!StringUtils.isEmpty(dbType)) {
      ListModel model = getModelService().getServerListModel(dbType);
      cbServer.setModel(model);
    }
  }
}

and my index.zul file:

<?page id="mainPage" title="Database tool alpha"?>
<zk>
<window id="connectWindow" title="Welcome to Database Tool Alpha!!"
border="normal" width="100%" apply="au.com.zkproject.controller.EventController">
<hbox pack="end">
<label value="Please enter parameters to connect to a database"/>
<vbox width="360px">
<hbox>
<label value="Choose a driver:"/>
<radiogroup id="rgDbType">
      <radio id="rdMSSQL" label="Microsoft SQL Server" checked="true"/>
      <radio id="rdOracle" label="Oracle" />
</radiogroup>
</hbox>
<hbox>
<label value="Database Server:" />
<combobox id="cbServer" cols="20" buttonVisible="false" autodrop="true"/>
</hbox>
</vbox>
</hbox>
</window>
</zk>

link publish delete flag offensive edit

answered 2010-09-09 01:12:57 +0800

newguy2010 gravatar image newguy2010
36

web.xml:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
  <display-name>DatabaseTool</display-name>
  <listener>
  	<description>
  	Used to cleanup when a session is destroyed</description>
  	<display-name>ZK Session cleaner</display-name>
  	<listener-class>org.zkoss.zk.ui.http.HttpSessionListener</listener-class>
  </listener>
  <!-- INI SPRING -->
  <!--
    - Location of the XML file that defines the root application context.
    - Applied by ContextLoaderServlet.
  -->
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:spring-*.xml</param-value>
  </context-param>

  <!--
    - Loads the root application context of this web app at startup,
    - by default from "/WEB-INF/applicationContext.xml".
    - Note that you need to fall back to Spring's ContextLoaderServlet for
    - J2EE servers that do not follow the Servlet 2.4 initialization order.
    -
    - Use WebApplicationContextUtils.getWebApplicationContext(servletContext)
    - to access it anywhere in the web application, outside of the framework.
    -
    - The root context is the parent of all servlet-specific contexts.
    - This means that its beans are automatically available in these child contexts,
    - both for getBean(name) calls and (external) bean references.
  -->
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>
  
  <listener>
        <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
  </listener>
    <!-- END SPRING -->
  <servlet>
  	<description>
  	The ZK loader for ZUML pages</description>
  	<servlet-name>zkLoader</servlet-name>
  	<servlet-class>org.zkoss.zk.ui.http.DHtmlLayoutServlet</servlet-class>
  	<init-param>
  		<param-name>update-uri</param-name>
  		<param-value>/zkau</param-value>
  	</init-param>
  	<load-on-startup>2</load-on-startup>
  </servlet>
  <servlet>
  	<description>
  	The asynchronous update engine for ZK</description>
  	<servlet-name>auEngine</servlet-name>
  	<servlet-class>org.zkoss.zk.au.http.DHtmlUpdateServlet</servlet-class>
  </servlet>
  <servlet-mapping>
  	<servlet-name>zkLoader</servlet-name>
  	<url-pattern>*.zul</url-pattern>
  </servlet-mapping>
  <servlet-mapping>
  	<servlet-name>zkLoader</servlet-name>
  	<url-pattern>*.zhtml</url-pattern>
  </servlet-mapping>
  <servlet-mapping>
  	<servlet-name>auEngine</servlet-name>
  	<url-pattern>/zkau/*</url-pattern>
  </servlet-mapping>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
    <welcome-file>index.zul</welcome-file>
  </welcome-file-list>
</web-app>

spring-config.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xmlns:context="http://www.springframework.org/schema/context"
     xmlns:aop="http://www.springframework.org/schema/aop"
     xsi:schemaLocation="http://www.springframework.org/schema/beans
         http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
         http://www.springframework.org/schema/context
         http://www.springframework.org/schema/context/spring-context-3.0.xsd
         http://www.springframework.org/schema/aop
         http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
  <!-- services -->
  <bean id="connectionService" scope="session" class="au.com.zkproject.impl.ConnectionServiceImpl" >
  </bean>
  
  <bean id="modelService" scope="session" class="au.com.zkproject.impl.ModelServiceImpl">
  </bean> 

  <!-- controllers -->
</beans>  

link publish delete flag offensive edit

answered 2010-09-09 01:15:25 +0800

newguy2010 gravatar image newguy2010
36

I am using zk 5.0.4 and Springframework 3.0.2, maven 2 and maven-jetty-plugin as the web server.
Whenever I try to focus on the cbServer combox it throws a NullPointerException, which means the service bean is not created or it cannot locate the bean.

link publish delete flag offensive edit

answered 2010-09-09 03:04:23 +0800

vergereau gravatar image vergereau
105 1 2

Can you give us the stack trace ?

I think you should process this way :

1- Test a basic zul.file to display an inject bean (a basic one just to display a string).

zul file

<?variable-resolver class="org.zkoss.zkplus.spring.DelegatingVariableResolver"?>
<zk>
<label value="${beanTest.textVal} />
</zk>


2. According to this test if bean it's display then we can see what's wrong in you example and try to use a best approach ( ex: First of all I think you should put the event on radiobox and not on the combobox focus, Use databinding for your model , ...)

link publish delete flag offensive edit
Your reply
Please start posting your answer anonymously - your answer will be saved within the current session and published after you log in or create a new account. Please try to give a substantial answer, for discussions, please use comments and please do remember to vote (after you log in)!

[hide preview]

Question tools

Follow

RSS

Stats

Asked: 2010-09-02 09:08:15 +0800

Seen: 858 times

Last updated: Sep 09 '10

Support Options
  • Email Support
  • Training
  • Consulting
  • Outsourcing
Learn More