Struts 2 + Spring integration example

In this tutorial, it shows the integration between Struts 2 and Spring.

1. Project Structure

Here’s the project folder structure of this tutorials.

Struts 2 Spring integration example

2. Struts 2 + Spring Plugin

To integrate Struts 2 and Spring, get and include the “struts2-spring-plugin-xxx.jar” library into your project classpath.

pom.xml


        <!-- Struts 2 -->
        <dependency>
                <groupId>org.apache.struts</groupId>
	        <artifactId>struts2-core</artifactId>
	        <version>2.1.8</version>
        </dependency>

	<!-- Spring framework --> 
	<dependency>
		<groupId>org.springframework</groupId>
		<artifactId>spring</artifactId>
		<version>2.5.6</version>
	</dependency>

	<dependency>
		<groupId>org.springframework</groupId>
		<artifactId>spring-web</artifactId>
		<version>2.5.6</version>
	</dependency>

	<!-- Struts 2 + Spring plugins -->
	<dependency>
                 <groupId>org.apache.struts</groupId>
	         <artifactId>struts2-spring-plugin</artifactId>
	         <version>2.1.8</version>
         </dependency>

3. Spring Listener

Configure the Spring listener “org.springframework.web.context.ContextLoaderListener” in web.xml file.

web.xml


<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>
  <display-name>Struts 2 Web Application</display-name>
  
  <filter>
	<filter-name>struts2</filter-name>
	<filter-class>
         org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter
        </filter-class>
  </filter>
  
  <filter-mapping>
	<filter-name>struts2</filter-name>
	<url-pattern>/*</url-pattern>
  </filter-mapping>
 
  <listener>
    <listener-class>
      org.springframework.web.context.ContextLoaderListener
    </listener-class>
  </listener>
  
</web-app>

3. Register Spring Bean

Register all the Spring’s Beans in the applicationContext.xml file, the Spring listener will locate this xml file automatically.

applicationContext.xml


<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
 
	<bean id="userBo" class="com.mkyong.user.bo.impl.UserBoImpl" />
	
	<bean id="userSpringAction" class="com.mkyong.user.action.UserSpringAction">
		<property name="userBo" ref="userBo" />	
	</bean>
 
</beans>

UserBo.java


package com.mkyong.user.bo;

public interface UserBo{

	public void printUser();
	
}

UserBoImpl.java


package com.mkyong.user.bo.impl;

import com.mkyong.user.bo.UserBo;

public class UserBoImpl implements UserBo{

	public void printUser(){
		System.out.println("printUser() is executed...");
	}
	
}

UserSpringAction.java


package com.mkyong.user.action;

import com.mkyong.user.bo.UserBo;

public class UserSpringAction{

	//DI via Spring
	UserBo userBo;
	
	public UserBo getUserBo() {
		return userBo;
	}

	public void setUserBo(UserBo userBo) {
		this.userBo = userBo;
	}

	public String execute() throws Exception {
		
		userBo.printUser();
		return "success";
		
	}
}

5. Struts.xml

Declared all the relationship here.


<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
 
<struts>
 	<constant name="struts.devMode" value="true" />
 	
	<package name="default" namespace="/" extends="struts-default">
		
		<action name="userAction" 
			class="com.mkyong.user.action.UserAction" >
			<result name="success">pages/user.jsp</result>
		</action>
		
		<action name="userSpringAction" 
			class="userSpringAction" >
			<result name="success">pages/user.jsp</result>
		</action>
		
	</package>
	
</struts>

6. Demo

Now, all the Struts 2 and Spring integration work is done, now see the following use case to access the Spring’s “userBo” bean.

  • Case 1 : Make Spring act as the Struts 2 Action class, and access the Spring’s bean.
  • Case 2 : Access the Spring’s bean in Struts 2 Action class.

Case 1

In this example, the userSpringAction is act as the Struts 2 Action class, and you can DI the Spring’s userBo bean with normal Spring’s way.


//struts.xml
<action name="userSpringAction" 
	class="userSpringAction" >
	<result name="success">pages/user.jsp</result>
</action>

//applicationContext.xml
<bean id="userSpringAction" class="com.mkyong.user.action.UserSpringAction">
	<property name="userBo" ref="userBo" />	
</bean>

To access this action, use the URL : http://localhost:8080/Struts2Example/userSpringAction

Case 2

By default, Spring listener enables “autowiring by matching the bean name“. So, it will pass the Spring’s “userBo” bean into the UserAction via setUserBo() automatically. See below Struts 2 Action :

The Spring’s autowiring feature can change to name(default), type, auto or constructor, you may need to consult this Struts 2 Spring plugin documentation.

UserAction.java


package com.mkyong.user.action;

import com.mkyong.user.bo.UserBo;
import com.opensymphony.xwork2.ActionSupport;
 
public class UserAction extends ActionSupport{

	//DI via Spring
	UserBo userBo;
	
	public UserBo getUserBo() {
		return userBo;
	}

	public void setUserBo(UserBo userBo) {
		this.userBo = userBo;
	}

	public String execute() throws Exception {
		
		userBo.printUser();
		return SUCCESS;
		
	}
}

To access this action, use the URL : http://localhost:8080/Struts2Example/userAction

WebApplicationContextUtils
Alternatively, you can use the Spring’s generic WebApplicationContextUtils class to get the Spring’s bean directly.


package com.mkyong.user.action;

import org.apache.struts2.ServletActionContext;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

import com.mkyong.user.bo.UserBo;
import com.opensymphony.xwork2.ActionSupport;
 
public class UserAction extends ActionSupport{

	public String execute() throws Exception {
		
		WebApplicationContext context =
			WebApplicationContextUtils.getRequiredWebApplicationContext(
                                    ServletActionContext.getServletContext()
                        );
		
		UserBo userBo1 = (UserBo)context.getBean("userBo");
		userBo1.printUser();

		return SUCCESS;
		
	}
}

A really long and tedious article, make sure you download the full project source code for practice.

Reference

  1. Struts 2 Spring plugin documentation
  2. Struts + Spring integration example

About the Author

author image
mkyong
Founder of Mkyong.com, love Java and open source stuff. Follow him on Twitter. If you like my tutorials, consider make a donation to these charities.

Comments

avatar
20 Comment threads
18 Thread replies
1 Followers
 
Most reacted comment
Hottest comment thread
27 Comment authors
Ricardo VallejoPisay NityanandggmAndrea LigiosSamB Recent comment authors
newest oldest most voted
Andrea Ligios
Guest
Andrea Ligios

You must use scope=”prototype” on the Action bean otherwise it becomes scope=”singleton” that is the default scope for Spring. And you don’t want an Action (that should be ThreadLocal) to be a Singleton… weird, thread-unsafe things will happens otherwise. This is a really important information missing in the article

Pisay Nityanand
Guest
Pisay Nityanand

thanks for your suggestion, its really helped me.

Rob
Guest
Rob

Hi after importing project to eclipse and update all dependencies im getting an error:
SEVERE: Context initialization failed
org.springframework.beans.factory.CannotLoadBeanClassException: Cannot find class [com.mkyong.user.bo.impl.UserBoImpl] for bean with name ‘userBo’ defined in ServletContext resource [/WEB-INF/applicationContext.xml]; nested exception is java.lang.ClassNotFoundException: com.mkyong.user.bo.impl.UserBoImpl

Rob
Guest
Rob

Ok i solved my problem. This thread helps me a lot http://stackoverflow.com/questions/4706893/spring-cant-find-a-lib-and-webapp-doesnt-start-up-in-tomcat-6 . Basically Eclipse hadn`t compiled classes in %ECLIPSE_HOME%\workspaces\default\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\

Ricardo Vallejo
Guest
Ricardo Vallejo

It works with struts 1?

SamB
Guest
SamB

Hi I used the above code and I got this

org.apache.catalina.core.StandardContext listenerStart

SEVERE: Error configuring application listener of class org.springframework.web.context.ContextLoaderListener

java.lang.ClassNotFoundException: org.springframework.web.context.ContextLoaderListener

at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1720)

at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1571)

at org.apache.catalina.core.DefaultInstanceManager.loadClass(DefaultInstanceManager.java:529)

at org.apache.catalina.core.DefaultInstanceManager.loadClassMaybePrivileged(DefaultInstanceManager.java:511)

at org.apache.catalina.core.DefaultInstanceManager.newInstance(DefaultInstanceManager.java:139)

at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4888)

at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5467)

at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)

at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1559)

at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1549)

at java.util.concurrent.FutureTask.run(Unknown Source)

at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)

at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)

at java.lang.Thread.run(Unknown Source)

panchanan
Guest
panchanan

hi
mkyong can you elaborate the flow of the application

PleaseHelp
Guest
PleaseHelp

Hi All. Can anyone tell why need to use interface (eg from this sample application we can see it using UserBo interface)? Can we do without using of interface of Bo?

ggm
Guest
ggm

hi because of polymorphism.

ggm
Guest
ggm

ya u can do it without interface but better use interface(polymorphism). And let say you want make changes on the code, you just need to make change on implementation code

Deepesh
Guest
Deepesh

Hi,

<bean id="userSpringAction" class="com.mkyong.user.action.UserSpringAction">
		<property name="userBo" ref="userBo" />	
	</bean>

I think, here the wiring is done byName, but not byType. Right?

C.O.
Guest
C.O.

you think

Prasun
Guest
Prasun

Hi,

I tried following the example with Case 1, where in we are trying to add the Spring bean Id as the Struts Action class. Somehow, I am getting an error saying “userSpringAction” not found while parsing struts.xml.

I have followed the exact steps you have mentioned.

Struts.xml

		<action name="userLoginAction" class="userLoginAction">
			<result name="success">user/pages/welcome_user.jsp</result>
			<result name="input">index.jsp</result>
		</action>
applicationContext.xml

	<bean id="userLoginAction" class="com.prasun.action.UserLoginAction">
 		<property name="userBO" ref="userBO" />
	</bean>
	
	<bean id="userBO" class="com.prasun.bo.impl.UserBOImpl"/>

Error is:

Caused by: Action class [userLoginAction] not found - action - file:/D:/Projects/EclipseWorkspace/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps/MyWebApplication/WEB-INF/classes/struts.xml:11:58
	at com.opensymphony.xwork2.config.providers.XmlConfigurationProvider.verifyAction(XmlConfigurationProvider.java:480)
	at com.opensymphony.xwork2.config.providers.XmlConfigurationProvider.addAction(XmlConfigurationProvider.java:424)
	at com.opensymphony.xwork2.config.providers.XmlConfigurationProvider.addPackage(XmlConfigurationProvider.java:541)
	at com.opensymphony.xwork2.config.providers.XmlConfigurationProvider.loadPackages(XmlConfigurationProvider.java:290)
	at org.apache.struts2.config.StrutsXmlConfigurationProvider.loadPackages(StrutsXmlConfigurationProvider.java:112)
	at com.opensymphony.xwork2.config.impl.DefaultConfiguration.reloadContainer(DefaultConfiguration.java:239)
	at com.opensymphony.xwork2.config.ConfigurationManager.getConfiguration(ConfigurationManager.java:68)
	... 22 more

please help.

Thanks,
Prasun

Prasun
Guest
Prasun

This worked fine after adding Struts-Spring plugin jar in classpath. Though not sure what is the dependency.

Any pointers to this would be appreciated.

Thanks,
Prasun

ADITYA
Guest
ADITYA

i have problem while deploying the war: SEVERE: Context initialization failed org.springframework.beans.factory.BeanCreationException: Error creating bean wit h name ‘sessionFactory’ defined in ServletContext resource [/WEB-INF/classes/con fig/spring/HibernateSessionFactory.xml]: Invocation of init method failed; neste d exception is org.hibernate.HibernateException: Unable to instantiate default t uplizer [org.hibernate.tuple.entity.PojoEntityTuplizer] at org.springframework.beans.factory.support.AbstractAutowireCapableBean Factory.initializeBean(AbstractAutowireCapableBeanFactory.java:1338) at org.springframework.beans.factory.support.AbstractAutowireCapableBean Factory.doCreateBean(AbstractAutowireCapableBeanFactory.java:473) at org.springframework.beans.factory.support.AbstractAutowireCapableBean Factory$1.run(AbstractAutowireCapableBeanFactory.java:409) at java.security.AccessController.doPrivileged(Native Method) at org.springframework.beans.factory.support.AbstractAutowireCapableBean Factory.createBean(AbstractAutowireCapableBeanFactory.java:380) at org.springframework.beans.factory.support.AbstractBeanFactory$1.getOb ject(AbstractBeanFactory.java:264) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistr y.getSingleton(DefaultSingletonBeanRegistry.java:222) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBe an(AbstractBeanFactory.java:261) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean (AbstractBeanFactory.java:185) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean (AbstractBeanFactory.java:164) at org.springframework.beans.factory.support.DefaultListableBeanFactory. preInstantiateSingletons(DefaultListableBeanFactory.java:423) at org.springframework.context.support.AbstractApplicationContext.finish BeanFactoryInitialization(AbstractApplicationContext.java:728) at org.springframework.context.support.AbstractApplicationContext.refres h(AbstractApplicationContext.java:380) at org.springframework.web.context.ContextLoader.createWebApplicationCon text(ContextLoader.java:255) at org.springframework.web.context.ContextLoader.initWebApplicationConte xt(ContextLoader.java:199) at org.springframework.web.context.ContextLoaderListener.contextInitiali zed(ContextLoaderListener.java:45) at org.apache.catalina.core.StandardContext.listenerStart(StandardContex t.java:4790) at org.apache.catalina.core.StandardContext.startInternal(StandardContex t.java:5284) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150) at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase… Read more »

vasu
Guest
vasu

Unable to load configuration. - bean - jar:file:/D:/Program%20Files/Apache%20Software%20Foundation/Apache%20Tomcat%206.0.26/webapps/springstruts/WEB-INF/lib/struts2-gxp-plugin-2.3.3.jar!/struts-plugin.xml:8:162 at com.opensymphony.xwork2.config.ConfigurationManager.getConfiguration(ConfigurationManager.java:69) at org.apache.struts2.dispatcher.Dispatcher.init_PreloadConfiguration(Dispatcher.java:390) at org.apache.struts2.dispatcher.Dispatcher.init(Dispatcher.java:436) at org.apache.struts2.dispatcher.ng.InitOperations.initDispatcher(InitOperations.java:74) at org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter.init(StrutsPrepareAndExecuteFilter.java:51) at org.apache.catalina.core.ApplicationFilterConfig.getFilter(ApplicationFilterConfig.java:295) at org.apache.catalina.core.ApplicationFilterConfig.setFilterDef(ApplicationFilterConfig.java:422) at org.apache.catalina.core.ApplicationFilterConfig.(ApplicationFilterConfig.java:115) at org.apache.catalina.core.StandardContext.filterStart(StandardContext.java:3838) at org.apache.catalina.core.StandardContext.start(StandardContext.java:4488) at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:791) at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:771) at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:546) at org.apache.catalina.startup.HostConfig.deployDirectory(HostConfig.java:1041) at org.apache.catalina.startup.HostConfig.deployDirectories(HostConfig.java:964) at org.apache.catalina.startup.HostConfig.deployApps(HostConfig.java:502) at org.apache.catalina.startup.HostConfig.start(HostConfig.java:1277) at org.apache.catalina.startup.HostConfig.lifecycleEvent(HostConfig.java:321) at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:119) at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1053) at org.apache.catalina.core.StandardHost.start(StandardHost.java:785) at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1045) at org.apache.catalina.core.StandardEngine.start(StandardEngine.java:443) at org.apache.catalina.core.StandardService.start(StandardService.java:519) at org.apache.catalina.core.StandardServer.start(StandardServer.java:710) at org.apache.catalina.startup.Catalina.start(Catalina.java:581) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.lang.reflect.Method.invoke(Unknown Source) at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:289) at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:414) Caused by: Unable to load bean: type:org.apache.struts2.views.gxp.inject.InjectedObjectContainer class:org.apache.struts2.views.gxp.inject.InjectedObjectContainer - bean - jar:file:/D:/Program%20Files/Apache%20Software%20Foundation/Apache%20Tomcat%206.0.26/webapps/springstruts/WEB-INF/lib/struts2-gxp-plugin-2.3.3.jar!/struts-plugin.xml:8:162 at com.opensymphony.xwork2.config.providers.XmlConfigurationProvider.register(XmlConfigurationProvider.java:235) at org.apache.struts2.config.StrutsXmlConfigurationProvider.register(StrutsXmlConfigurationProvider.java:102) at com.opensymphony.xwork2.config.impl.DefaultConfiguration.reloadContainer(DefaultConfiguration.java:206) at com.opensymphony.xwork2.config.ConfigurationManager.getConfiguration(ConfigurationManager.java:66) ... 31 more Caused… Read more »

trackback
Struts 2 + Spring 3 + Quartz 1.8 Scheduler Example

[…] To integrate Struts 2 + Spring, just put the org.springframework.web.context.ContextLoaderListener listener class in the web.xml file. Note For detail, please read this Struts 2 + Spring integration example. […]

dany
Guest
dany

hi Mkyong, what this tutorial can to use with spring 3 ?

nitin
Guest
nitin

HI Mkyong,

Your blog is awesome and always helps me when i need to learn something new in java.

I am new to Struts 2, in my application i need to integrate Struts 2 and Spring Security 3. I was able to do integration of Struts 1 and Spring security 3. but while trying integration with spring security 3 i am getting some difficulties. Do you have any idea of integration for both Struts 2 and Spring Security 3.

Can you please post it if you have done work on it. I will be really thankful to you.

siju
Guest
siju

Hi mkyong,

I’m getting below error while starting the server.Please advise.

Caused by: java.lang.ClassNotFoundException: com.opensymphony.xwork2.util.classloader.ReloadingClassLoader

siju
Guest
siju

Thanks.I was using a Xwork2 older version.Changed to latest version.

Siregar
Guest
Siregar

Hi mkyong, thank you for your tutorial. I’ve download 3 your example project. But when i import the project to my eclipse.,all of it get error like this in pom.xml

– Failure to transfer org.codehaus.plexus:plexus-archiver:jar:1.2 from http://repo1.maven.org/maven2 was cached in the local repository, resolution will not be reattempted until the update interval of central has elapsed or updates are forced. Original error: Could not transfer artifact org.codehaus.plexus:plexus-archiver:jar:1.2 from/to central (http://repo1.maven.org/maven2): No route to host: no further information to http://repo1.maven.org/maven2/org/codehaus/plexus/plexus-archiver/1.2/plexus-archiver-1.2.jar

– Missing artifact com.sun:tools:jar:1.5.0
– Missing artifact javax.transaction:jta:jar:1.0.1B

Why i got this error.,could you tell me how to resolve this?
Thank you..,

marouane
Guest
marouane

Hello
do you find any solution to this problem

phasthal
Guest
phasthal

Get the latest version from maven repository and try adding like below in pom.xml

org.codehaus.plexus
plexus-archiver
2.1.1

phasthal
Guest
phasthal

re-sending in xml format

    <dependency>
	<groupId>org.codehaus.plexus</groupId>
	<artifactId>plexus-archiver</artifactId>
	<version>2.1.1</version>
   </dependency>
khaled
Guest
khaled

Hi mkyong ,

thanx alot for your fantastic work.I have a question can i inject a bean in the bao without inject bao in Action ?

trackback
Spring Tutorial

[…] web framework.Struts + Spring integration Example to integrate Spring with Struts 1.x framework.Struts 2 + Spring integration example Example to integrate Spring with Struts 2 framework.JSF 2.0 + Spring integration example Example to […]

Arun.R.U
Guest
Arun.R.U

Hi mkyong,

I always like your blogs on Struts and Spring, really useful. i need your small help, do you have Struts2.2.1 and Spring3.0.5 integrated application ? if you have then please send it to my mail id.

Thanks..

A.R.U

trackback
Struts 2 + Spring + Hibernate integration example

[…] Struts 2 + Spring integration example […]

trackback
Struts 2 + Spring + Quartz scheduler integration example

[…] In this tutorial, it shows how to integrate Struts 2 + Spring + Quartz scheduler together. The relationship as following : Struts 2 <–Struts2 Spring Plugin –> Spring <–(Spring-Helper)–> Quartz <—> Scheduler task This article will do a little explanation on the Struts 2 and Spring integration, for details, please access this Struts 2 + Spring integration example. […]