This is part 3 of the Java Technologies Integration tutorial

Sping Beans

Having user entity create it is finally the time to write some code! We are going to create two Spring Beans: Bussiness Object (BO) to providing interface for bussiness operations and Data Access Object (DAO) to communicate with database using entity User. To do so, we create two interfaces (UserBo and UserDao) and their implementations (UserBoImpl and UserDaoImpl) in package com.frogdroid.integration.user. The content of the files is listed below.

UserBo.java

package com.frogdroid.integration.user;
 
import java.util.List;
 
import com.frogdroid.integration.user.entity.User;
 
public interface UserBo {
 
    void add(User user);
 
    void update(User user);
 
    void delete(User user);
 
    List findAll();
 
    List findById(int id);
 
    List findByUsername(String username);
}

UserBoImpl.java

package com.frogdroid.integration.user;
 
import java.util.List;
 
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
 
import com.frogdroid.integration.user.entity.User;
 
@Transactional
public class UserBoImpl implements UserBo {
 
    private static final Logger LOGGER = Logger.getLogger(UserBoImpl.class.getName());
 
    @Autowired
    private UserDao userDao;
 
    public UserDao getUserDao() {
        return userDao;
    }
 
    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }
 
    public void add(User user) {
        if (user == null) {
            return;
        }
        LOGGER.debug("Adding the following user: " + user.getUsername() + ", " + user.getPassword());
        userDao.add(user);
    }
 
    public void delete(User user) {
        if (user == null) {
            return;
        }
        LOGGER.debug("Deleteting the following user: " + user.getId() + ", " + user.getUsername() + ", " + user.getPassword());
        userDao.delete(user);
    }
 
    public List findAll() {
        LOGGER.debug("Getting all users");
        return userDao.findAll();
    }
 
    public List findById(int id) {
        return userDao.findById(id);
    }
 
    public List findByUsername(String username) {
        return userDao.findByUsername(username);
    }
 
    public void update(User user) {
        if (user == null) {
            return;
        }
        userDao.update(user);
    }
}

UserDao.java

package com.frogdroid.integration.user;
 
import java.util.List;
 
import com.frogdroid.integration.user.entity.User;
 
public interface UserDao {
 
    void add(User user);
 
    void update(User user);
 
    void delete(User user);
 
    List findAll();
 
    List findById(int id);
 
    List findByUsername(String username);
}

UserDaoImpl.java

package com.frogdroid.integration.user;
 
import java.util.List;
 
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
 
import com.frogdroid.integration.user.entity.User;
 
public class UserDaoImpl extends HibernateDaoSupport implements UserDao {
 
    public void add(User user) {
        getHibernateTemplate().save(user);
    }
 
    public void delete(User user) {
        getHibernateTemplate().delete(user);
    }
 
    public List findAll() {
        return getHibernateTemplate().find("from User");
    }
 
    public List findById(int id) {
        return getHibernateTemplate().find("from User where id=?", id);
    }
 
    public List findByUsername(String username) {
        return getHibernateTemplate().find("from User where username=?", username);
    }
 
    public void update(User user) {
        getHibernateTemplate().update(user);
    }
}

Following that we create appropriate bean definitions and put them in src/main/resources/resources/spring/UserBean.xml file.

UserBean.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.frogdroid.integration.user.UserBoImpl">
        <property name="userDao" ref="userDao" />
    </bean>
 
    <bean id="userDao" class="com.frogdroid.integration.user.UserDaoImpl">
        <property name="sessionFactory" ref="sessionFactory" />
    </bean>
 
</beans>

In addition we include UserBean.xml file in src/main/webapp/WEB-INF/applicationContext.xml file as follows:

<!-- Beans Declaration -->
<import resource="classes/resources/spring/UserBean.xml" />

Structure of the project after changes is presented in Figure 10.


Figure 10: Project with BOs, DAOs and their configuration.

Integration with Struts2

To use Struts2 in our project we have to add filter to web.xml file. The filter will be mapped, so each request to *.action and struts/* will be executed through StrutsPrepareAndExecuteFilter. The part to be added to web-app section in web.xml is presented below.

<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>*.action</url-pattern>
</filter-mapping>
 
<filter-mapping>
    <filter-name>struts2</filter-name>
    <url-pattern>/struts/*</url-pattern>
</filter-mapping>

Following that we have to create UserAction class that runs appropriate actions and return input to StrutsPrepareAndExecuteFilter. The class is put in src/main/java/com/frogdroid/integration/user/action/UserAction.java and its content is listed below.

UserAction.java

package com.frogdroid.integration.user.action;
 
import java.util.List;
 
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
 
import com.frogdroid.integration.user.UserBo;
import com.frogdroid.integration.user.entity.User;
import com.opensymphony.xwork2.Action;
import com.opensymphony.xwork2.Preparable;
 
public class UserAction implements Preparable {
 
    private static final Logger LOGGER = Logger.getLogger(UserAction.class.getName());
 
    private List users;
 
    private Integer id;
    private String username;
    private String password;
 
    @Autowired
    private UserBo userBo;
 
    public UserBo getUserBo() {
        return userBo;
    }
 
    public void setUserBo(UserBo userBo) {
        this.userBo = userBo;
    }
 
    public List getUsers() {
        return users;
    }
 
    public void setUsers(List users) {
        this.users = users;
    }
 
    public Integer getId() {
        return id;
    }
 
    public void setId(Integer id) {
        this.id = id;
    }
 
    public String getUsername() {
        return username;
    }
 
    public void setUsername(String username) {
        this.username = username;
    }
 
    public String getPassword() {
        return password;
    }
 
    public void setPassword(String password) {
        this.password = password;
    }
 
    public String listAll() {
        if (userBo == null) {
            return Action.ERROR;
        }
        LOGGER.debug("Get all users");
        users = userBo.findAll();
        LOGGER.debug("Users number = " + users.size());
        return Action.SUCCESS;
    }
 
    public String delete() {
        if (userBo == null) {
            return Action.ERROR;
        }
 
        User user = getUser(id);
        if (user == null) {
            return Action.ERROR;
        }
 
        LOGGER.debug("Delete user " + user.getUsername() + " with id " + user.getId());
        userBo.delete(user);
        return Action.SUCCESS;
    }
 
    public String add() {
        if (userBo == null) {
            return Action.ERROR;
        }
 
        User user = new User();
        user.setUsername(username);
        user.setPassword(password);
        LOGGER.debug("Add user: " + user.getUsername());
        userBo.add(user);
        return Action.SUCCESS;
    }
 
    public String execute() {
        return Action.SUCCESS;
    }
 
    public void prepare() throws Exception {
 
    }
 
    private User getUser(Integer id) {
        LOGGER.debug("Get user with id = " + id);
        if (id != null) {
            List users = userBo.findById(id);
            LOGGER.debug("Number of users with id = " + id + ": " + users.size());
            if (users.size() == 1) {
                return (User) users.get(0);
            }
        }
        return null;
    }
}

We add the following action bean definition to UserBean.xml file, so it can be used in struts action file.

<bean id="userAction" class="com.frogdroid.integration.user.action.UserAction">
    <property name="userBo" ref="userBo" />
</bean>

Following that we have to create file with struts actions. The file should be placed in WEB-INF/classes/struts.xml in final war structure, which indicates that it should be created in src/main/resources/struts.xml. If you use different location struts actions will not be mapped. The file mapps actions invoked by the user to appropriate java classes/beans and its content is presented below. Depending on action appropriate methods (listAll, delete, add) from UserAction class are invoked. Our application has the functionality to list, add, and delete users from database.

struts.xml

<!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" extends="struts-default">
 
        <action name="listAllUsers" method="listAll" class="userAction">
            <result name="success">WEB-INF/content/user/list.jsp</result>
        </action>
 
        <action name="deleteUser" method="delete" class="userAction">
            <result type="redirect">listAllUsers.action</result>
        </action>
 
        <action name="addUserForm" class="userAction">
            <result>WEB-INF/content/user/addForm.jsp</result>
        </action>
 
        <action name="addUser" method="add" class="userAction">
            <result type="redirect">listAllUsers.action</result>
        </action>
 
    </package>
</struts>

To show add user form we have to create WEB-INF/content/user/addForm.jsp file and to list all users we have to create WEB-INF/content/user/list.jsp. The content of the files is presented below.

addForm.jsp

<%@ taglib prefix="s" uri="/struts-tags"%>
 
<html>
<head>
<title>Add User</title>
</head>
<body>
 
<p>Add User</p>
 
<s:form name="addForm" method="post" action="addUser.action">
 
    <s:textfield name="username" label="User" />
    <s:password name="password" label="Password" />
 
    <s:submit type="button" name="Add" />
 
</s:form>
 
</body>
</html>

Make sure that the names of the fields correspond to properties in your UserAction class.

list.jsp

<%@ taglib prefix="s" uri="/struts-tags"%>
<%@ taglib prefix="sx" uri="/struts-dojo-tags"%>
 
<html>
<head>
<title>User List</title>
<sx:head debug="true" cache="false" compressed="false" />
</head>
<body>
 
<p>User List</p>
<div><s:url id="addUser" value="addUserForm.action">
</s:url><s:a href="%{addUser}">Add</s:a></div>
<s:if test="users.size > 0">
    <table id="users">
        <s:iterator value="users">
            <tr>
                <td><s:property value="username" /></td>
                <td><s:property value="password" /></td>
                <td><s:url id="deleteUser" value="deleteUser.action">
                    <s:param name="id" value="id" />
                </s:url> <s:a href="%{deleteUser}">Delete</s:a></td>
            </tr>
        </s:iterator>
    </table>
</s:if>
 
</body>
</html>

Make sure that the names of the properties correspond to properties in your User entity. In addition, iterator uses property (‘users’) that should be defined in UserAction class.

The structure of the project after changes is presented in Figure 11.


Figure 11: Project structure after integration with Struts2″.

Final struture

Before showing final project structure let’s tidy a little bit up. Remove:

  • Remove class: App.java
  • Remove class: AppTest.java
  • Change Default output folder (Java build path -> Source) to IntegrationProject/target/classes
  • Remove folder: build

Having all that done the final structure of the project should look as presented in Figure 12.


Figure 12: Final project structure.

Test that all is OK so far:

mvn clean
mvn compile
mvn war:war

Part 4 of the tutorial can be found at Java Technologies Integration tutorial – part 4.