Using Spring IOC with ZK
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
Yes I've put that on.
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" />
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
None of the above works. Any other suggestions?
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 ?
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>
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>
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.
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 , ...)
Thanks vergereau. That test doesn't work so I guess it couldn't resolve the bean.
The radiogroup used to be a textbox so what I wanted is to get the model after I enter something in the textbox but avoid leaving a blank textbox. The event was previously coded for the old design and I forgot to modify the codes after I changed my design.
ZK - Open Source Ajax Java Framework
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:
In the web.xml file
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.