Reputation: 3015
I want to integrate Struts 2, Hibernate and Spring. I made a previous example project with Hibernate, Spring, Spring MVC. And it worked fine. Now I want to replace Spring MVC with Struts 2. And I have following problem. I have LoginAction class with field @Autowired private UserService userService
. UserService class contains as a field UserDAO field that also annotated as Autowired. UserDAO contains SessionFactory that annotated too. I'm sure that struts confiration is right. And applicationContext.xml also right. Because when I make some changes in this file, I got an exceptions. Tomcat starts without errors and shows me login page. But when I tried to call methods of UserService class, I got a NPE, because this object is null. Why Spring did not set this object? My code:
applicationContext.xml:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.2.xsd">
<tx:annotation-driven transaction-manager="transactionManager" />
<context:annotation-config />
<context:component-scan base-package="com"/>
<bean id="userDAO" class="com.example.dao.impl.hibernate.HibernateUserDAO" />
<bean id="userService" class="com.example.service.impl.UserServiceImpl" />
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="org.h2.Driver" />
<property name="url" value="jdbc:h2:~/database" />
<property name="username" value="user" />
<property name="password" value="user" />
</bean>
<bean name="sessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="annotatedClasses">
<list>
<value>com.example.entity.User</value>
</list>
</property>
<property name="hibernateProperties">
<value>
hibernate.dialect=org.hibernate.dialect.H2Dialect
hibernate.show_sql=true
</value>
</property>
</bean>
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
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" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">
<welcome-file-list>
<welcome-file>/WEB-INF/pages/login.jsp</welcome-file>
</welcome-file-list>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<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>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/applicationContext.xml
</param-value>
</context-param>
</web-app>
LoginAction class:
@Controller
public class LoginAction extends ActionSupport {
private String login;
private String password;
@Autowired
private UserService userService;
@Override
public String execute() throws Exception {
User user = null;
try {
user = userService.findByLogin(login);
} catch (Exception e) {
e.printStackTrace();
}
if (user != null) {
return user.getPassword().equals(password) ? SUCCESS : ERROR;
}
return ERROR;
}
// getters and setters
}
UserService implementation class:
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserDAO userDAO;
@Override
@Transactional
public User findByLogin(String login) throws SQLException {
return userDAO.findByLogin(login);
} }
And UserDAO impl class:
@Repository
public class HibernateUserDAO implements UserDAO {
@Autowired
public SessionFactory sessionFactory;
@Override
public User findByLogin(String login) throws SQLException {
return sessionFactory.getCurrentSession().createCriteria(User.class)
.add(Restrictions.eq("login", login)).list().get(0);
} }
Struts confiration is fine, because it react correctly. Why Spring did not set fields? Any ideas?
<struts>
<constant name="struts.devMode" value="true" />
<package name="default" namespace="/" extends="struts-default">
<action name="login" class="com.example.web.action.LoginAction">
<result name="success">/WEB-INF/pages/cabinet.jsp</result>
<result name="error">/WEB-INF/pages/login.jsp</result>
<result name="input">/WEB-INF/pages/login.jsp</result>
</action>
</package>
Upvotes: 0
Views: 1523
Reputation: 10017
Just like @SotiriosDelimanolis said, you are mixing
things. Here is you do:
struts2-spring-plugin
in your classpath. NOTE:
The version of the plugin should be as same as your strut2 version.application-context.xml
, whatever explicit or over component-scan.check if there is
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
defined in your web.xml
have fun! Here is the link
of the REFERENCE
Upvotes: 1
Reputation: 475
You are not using spring MVC (by not using dispatcher servlet in web.xml); yet you are trying to use MVC api annotations like @Controller in the Action servlet. How is that supposed to work?
Upvotes: 0
Reputation: 279970
You're mixing things. Spring will create a context because you've declared a ContextLoaderListener
, but Struts
will create its own stack of Action
(ActionSupport
) classes from your struts.xml configuration file. In other words, it's instantiating its own LoginAction
object.
Upvotes: 1