Struts is an open source web application framework that is designed to support the development life cycle, which includes building, deploying, and maintaining the application. Struts is based on the MVC (Model View Controller) pattern. It is available under Apache License.
The official site of Struts to download the distribution, support, contribution, and tutorials is https://struts.apache.org/.
Here, we will create a Maven-based Struts web application to understand how to integrate hibernate with Struts. In this recipe, we will continue to use the DAO pattern.
Struts has no plugin available for integration with hibernate, so we will manage all hibernate code manually.
In this section, we will create a code file required for hibernate and Struts with a detailed description.
Here, we will create a Maven project; so, all project dependencies will be mentioned in pom.xml
:
Source file: pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.packt</groupId> <artifactId>StrutsHibernate</artifactId> <packaging>war</packaging> <version>0.0.1-SNAPSHOT</version> <name>StrutsHibernate Maven Webapp</name> <url>http://maven.apache.org</url> <properties> <struts2-core.version>2.3.24</struts2-core.version> <hibernate.version>4.3.5.Final</hibernate.version> </properties> <dependencies> <dependency> <groupId>org.apache.struts</groupId> <artifactId>struts2-core</artifactId> <version>${struts2-core.version}</version> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-core</artifactId> <version>${hibernate.version}</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.9</version> </dependency> </dependencies> <build> <finalName>StrutsHibernate</finalName> </build> </project>
In this pom file, we covered the required dependency for the Struts core, hibernate, and the MySQL connector only.
We will create a hibernate configuration file to provide the database configuration:
Source file: hibernate.cfg.xml
<?xml version='1.0' encoding='UTF-8'?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory> <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property> <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/StrutsHibernateIntegration</property> <property name="hibernate.connection.username">root</property> <property name="hibernate.connection.password">root</property> <property name="show_sql">true</property> <property name="hbm2ddl.auto">create</property> <mapping class="com.packt.modal.Film" /> </session-factory> </hibernate-configuration>
Use the following script to create the tables if you are not using hbm2dll=create|update
:
Table: film
create table film ( id bigint not null auto_increment, name varchar(255), releaseYear bigint, primary key (id) );
A model class is the same as a POJO. Here, we will use the same POJO class that was created in the previous recipe, Integration with Spring. Also, we will use the Film.java
file from the previous recipe.
Here, we will create an interface for the film class. Execute the following code:
Source file: FilmDao.java
package com.packt.dao; import java.util.List; import com.packt.modal.Film; public interface FilmDao { public void save(Film film); public List<Film> getAll(); }
We need to add a filter in web.xml
, create Action
, and also map Actions
with the view part.
As this is a web-based example, we need to register the Struts filter in web.xml
so that every web request coming from the user passes through that filter only:
Source 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 Hibernate 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> </web-app>
In this file, the filter is added with url-pattern /*
, and org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter
is added as the filter class so that every request is passed through the StrutsPrepareAndExecuteFilter
filter.
In this class, we create the actions that are used to perform operations:
Source file: FileAction.java
package com.packt.action; import java.util.ArrayList; import java.util.List; import org.hibernate.SessionFactory; import com.opensymphony.xwork2.ActionSupport; import com.opensymphony.xwork2.ModelDriven; import com.packt.common.HibernateUtil; import com.packt.dao.FilmDao; import com.packt.dao.FilmDaoImpl; import com.packt.modal.Film; /* Line 15 */ public class FilmAction extends ActionSupport implements ModelDriven { Film film = new Film(); List<Film> films = new ArrayList<Film>(); @Override /* Line 21 */ public String execute() throws Exception { /* Line 22 */ return SUCCESS; } public List<Film> getFilms() { return films; } public void setFilms(List<Film> films) { this.films = films; } public Object getModel() { return film; } /* Line 37 */ public String saveFilm(){ SessionFactory sessionFactory = HibernateUtil.getSessionFactory(); FilmDao filmDao = new FilmDaoImpl(sessionFactory); filmDao.save(film); // refresh films films = filmDao.getAll(); return SUCCESS; } /* Line 48 */ public String listAllFilms(){ films = null; SessionFactory sessionFactory = HibernateUtil.getSessionFactory(); FilmDao filmDao = new FilmDaoImpl(sessionFactory); films = filmDao.getAll(); return SUCCESS; } }
In Line 15
, you can find the extends ActionSupport
class. The ActionSupport
implements multiple interfaces, including the Action
interface.
Consider the following code:
public interface Action { public static final String SUCCESS = "success"; public static final String NONE = "none"; public static final String ERROR = "error"; public static final String INPUT = "input"; public static final String LOGIN = "login"; public String execute() throws Exception; }
Here, we override the execute()
method which returns SUCCESS
as a result. SUCCESS
is the final variable of the Action
interface, which provides the result name and is used in the struts.xml
mapping file to redirect if it is success.
Also, Line 15
shows the implements ModelDriven
interface, which is used to convert the form data into an object automatically.
Source file: struts.xml
<?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> /* Line 5 */ <constant name="struts.devMode" value="true" /> <package name="default" namespace="/" extends="struts-default"> /* Line 9 */ <action name="addFilmAction" class="com.packt.action.FilmAction" method="saveFilm"> /* Line 10 */ <result name="success">view/film.jsp</result> </action> /* Line 13 */ <action name="listFilmAction" class="com.packt.action.FilmAction" method="listAllFilms"> /* Line 14 */ <result name="success">view/film.jsp</result> </action> </package> </struts>
This file shows the handler for all requests and decides the proper responses accordingly.
Line 5
sets the struts.devMode
constant to true
; Struts will consider the current environment to be the development environment and provide more information and logs on the console or output window. This option is not preferred in the production environment.
Line 9
creates an action with the name "addFilmAction"
, the com.packt.action.FilmAction
class, and the method is saveFilm
. It means that if a request comes for the addFilmAction
action, it will execute the saveFilm
method of the com.packt.action.FilmAction
class. If the saveFilm
method returns success as an output, it will return film.jsp
as the response written in Line 10
.
Lines 13
and 14
are used to create the action for the list of all Films
.
In this section, we will discuss the implementation of the FilmDao
interface and create a .jsp
file, which is used to test our code.
This file shows the implementation of the FilmDao
interface:
Source file: FilmDaoImpl.java
package com.packt.dao; import java.util.List; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.Transaction; import com.packt.modal.Film; public class FilmDaoImpl implements FilmDao { private SessionFactory sessionFactory; public FilmDaoImpl(SessionFactory sessionFactory) { this.sessionFactory = sessionFactory; } public void save(Film film) { Session session = this.sessionFactory.openSession(); Transaction tx = session.beginTransaction(); session.saveOrUpdate(film); tx.commit(); session.close(); } public List<Film> getAll() { Session session = this.sessionFactory.openSession(); List<Film> filmList = session.createQuery("from Film").list(); session.close(); return filmList; } }
In this file, we only created the two methods that are used to save the file and list all the films.
The Film.jsp
view is created in the view
directory, which resides under the webapp
directory in a traditional web application:
Source file: film.java
<%@ taglib prefix="s" uri="/struts-tags"%> <html> <head> </head> <body> <h1>Hibernate with Struts 2 integration</h1> <h2>Add Film</h2> /* Line 10 */ <s:form action="addFilmAction"> <s:textfield name="name" label="Name" value="" /> <s:textfield name="releaseYear" label="Release Year" value="" /> <s:submit /> </s:form> <h2>All Films</h2> <s:if test="films.size() > 0"> <table border="1" cellpadding="3"> <tr> <th>Id</th> <th>Name</th> <th>Release Year</th> </tr> /* Line 24 */ <s:iterator value="films"> <tr> <td><s:property value="id" /></td> <td><s:property value="name" /></td> <td><s:property value="releaseYear" /></td> </tr> </s:iterator> </table> </s:if> </body> </html>
This file is returned as an output if the method mapped in struts.xml
is returned with the desired result tag.
Line 10
creates a Struts form with the addFilmAction
action, which invokes the saveFilm
methods of the com.packt.action.FilmAction
class with the mapping provided in struts.xml
.
Line 24
accesses the list of the variable films defined in FilmAction
and renders it as a table using an iterator
.
Let's take a look at how this works for us by running a project.
As this is a web-based application, we will use Apache Tomcat as the server environment to run the project. Tomcat is available under Apache License Version 2 and can be downloaded from http://tomcat.apache.org/.
After running the project, we will open the following link in a browser:
http://localhost:9090/StrutsHibernate/listFilmAction
Once you open this link, it will display a form asking you to insert the film details. Below this, a list of films will also be displayed. At startup, it shows a blank table as no film records were inserted prior to this, as shown in the following screenshot:
Once you insert any record in the form and click on Submit, it will invoke the saveFilm
method of the FilmAction
class. This mapping is provided in struts.xml
. Take a look at the following screenshot:
Once you click on Submit, it will submit all the data to the server, and the server will convert all the submitted fields to a Film
object and save it to the database. This will also return with all the film records. Take a look at the following screenshot:
You can read more on Spring integration at:
http://docs.spring.io/spring/docs/current/spring-framework-reference/html/orm.html.