This tutorial will show how you can store images in Database and retrieve them from DB and display in browser using Struts 2, Spring and Hibernate step by step. I have used Oracle Database to store the data.
It uses Struts 2 for presentation layer and Spring to manage the business and DAO objects and Hibernate at DAO layer to access dabase.
To get all the required jar files and classpath setup please look at
http://tiwarij2eeblog.blogspot.com/2011/01/integration-of-struts-20-spring-30-and.html
Step 1: Setup project in eclipse as given below.
Step 2: Copy all required jar files to WEB-INF/lib folder.
Step 3: Create VO object and hibernate mapping file.
package org.paandav.blog.vo;
import java.io.Serializable;
import java.sql.Blob;
public class User implements Serializable {
private static final long serialVersionUID = 1L;
private Long id;
private Long version;
private String firstName;
private String lastName;
private Blob image;
private String conTentType;
private String fileName;
private byte[] imageInBytes; // For external use
private int contentLength;// For external use
public int getContentLength() {
return contentLength;
}
public void setContentLength(int contentLength) {
this.contentLength = contentLength;
}
public byte[] getImageInBytes() {
return imageInBytes;
}
public void setImageInBytes(byte[] imageInBytes) {
this.imageInBytes = imageInBytes;
}
public String getFileName() {
return fileName;
}
public void setFileName(String fileName) {
this.fileName = fileName;
}
public String getConTentType() {
return conTentType;
}
public void setConTentType(String conTentType) {
this.conTentType = conTentType;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public Blob getImage() {
return image;
}
public void setImage(Blob image) {
this.image = image;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Long getVersion() {
return version;
}
public void setVersion(Long version) {
this.version = version;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
}
Hibernate Mapping file - User.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="org.paandav.blog.vo">
<class name="User" table="BT_USER" optimistic-lock="version" lazy="false">
<id name="id" column="userId">
<generator class="native" />
</id>
<version name="version" type="long" />
<property name="firstName" length="50" type="string" />
<property name="lastName" length="50" type="string" />
<property name="image" type="blob" />
<property name="conTentType" length="300" type="string" />
<property name="fileName" length="300" type="string" />
</class>
</hibernate-mapping>
Step 4: Hibernate configuration file oracle_hibernate.cfg.xml.
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- Database connection settings -->
<property name="connection.driver_class">oracle.jdbc.driver.OracleDriver</property>
<property name="connection.url">jdbc:oracle:thin:@localhost:1521:ORACLE</property>
<property name="connection.username">pradeep</property>
<property name="connection.password">pradeep</property>
<!-- JDBC connection pool (use the built-in) -->
<property name="connection.pool_size">2</property>
<!-- SQL dialect -->
<property name="dialect">org.hibernate.dialect.Oracle10gDialect</property>
<!-- Disable the second-level cache -->
<property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
<!-- Echo all executed SQL to stdout -->
<property name="show_sql">true</property>
<!-- Drop and re-create the database schema on startup -->
<property name="hbm2ddl.auto">update</property>
<mapping resource="org/paandav/blog/vo/User.hbm.xml" />
</session-factory>
</hibernate-configuration>
Step 5: Create applicationContext.xml file.
<?xml version="1.0" encoding="UTF-8"?>
<!-- Application context definition for Online Exam -->
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/jdbc
http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<!-- END FOR LOGIC LAYER -->
<context:annotation-config />
<!-- Instruct Spring to retrieve and apply @AspectJ aspects which are defined
as beans in this context (such as the CallMonitoringAspect below). -->
<aop:aspectj-autoproxy />
<!-- Hibernate plugin code -->
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="configurationClass" value="org.hibernate.cfg.AnnotationConfiguration" />
<property name="configLocation" value="classpath:oracle_hibernate.cfg.xml" />
</bean>
<bean id="userService" class=" org.paandav.bolg.service.UserServiceImpl">
<property name="userDao" ref="userDao"></property>
</bean>
<bean id="userDao" class="org.paandav.blog.dao.UserDAOImpl">
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>
<!-- Transaction Manger -->
<bean id="txManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<tx:advice id="txAdvice" transaction-manager="txManager">
<tx:attributes>
<tx:method name="*" propagation="SUPPORTS" isolation="READ_COMMITTED"
rollback-for="Exception" />
</tx:attributes>
</tx:advice>
<aop:config>
<aop:pointcut id="serviceLayerBeanMethods"
expression="execution(* org.paandav.bolg.service.*.*(..))" />
<aop:advisor advice-ref="txAdvice" pointcut-ref="serviceLayerBeanMethods" />
</aop:config>
</beans>
Step 6: Create struts.xml file
<?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="false" />
<constant name="struts.custom.i18n.resources" value="global" />
<constant name="struts.objectFactory" value="spring" />
<package name="commonPackage" namespace="/" extends="struts-default">
<result-types>
<result-type name="imageBytesResult"
class="org.paandav.blog.action.ImageBytesResult" />
</result-types>
<action name="addUserData" class="org.paandav.blog.action.UserAction">
<result name="input">
WEB-INF/jsp/imageUploader.jsp
</result>
</action>
<action name="displayFullImage" class="org.paandav.blog.action.FullImageAction">
<result name="input">
WEB-INF/jsp/dispalyFullImage.jsp
</result>
</action>
<action name="getImage" class="org.paandav.blog.action.GetImageAction">
<result name="imageBytesResult" type="imageBytesResult">
</result>
</action>
</package>
</struts>
Step 7: Create web.xml file
<?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/j2ee" xmlns:javaee="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/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
id="WebApp_9" version="2.4">
<display-name>Open Online Exam</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>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext.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>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<error-page>
<error-code>404</error-code>
<location>/index.jsp</location>
</error-page>
</web-app>
Step 8: Struts 2 action classes and validation files.
UserAction-validation.xml
<!DOCTYPE validators PUBLIC
"-//OpenSymphony Group//XWork Validator 1.0.2//EN"
"http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd">
<validators>
<field name="firstName">
<field-validator type="requiredstring">
<message key="First name is blank" />
</field-validator>
</field>
<field name="lastName">
<field-validator type="requiredstring">
<message key="Last name is blank" />
</field-validator>
</field>
</validators>
UserAction.java
package org.paandav.blog.action;
import java.io.File;
import java.io.FileInputStream;
import java.sql.Blob;
import java.util.List;
import org.hibernate.Hibernate;
import org.paandav.blog.vo.User;
import org.paandav.bolg.service.UserService;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;
import com.opensymphony.xwork2.Preparable;
public class UserAction extends ActionSupport implements ModelDriven<User>,
Preparable {
private static final long serialVersionUID = 1L;
User user = new User();
private File file;
private String contentType;
private String filename;
private UserService userService;
private List<User> allUserList;
private String from;
public String getFrom() {
return from;
}
public void setFrom(String from) {
this.from = from;
}
public List<User> getAllUserList() {
return allUserList;
}
public void setAllUserList(List<User> allUserList) {
this.allUserList = allUserList;
}
public UserService getUserService() {
return userService;
}
public void setUserService(UserService userService) {
this.userService = userService;
}
public void setUpload(File file) {
this.file = file;
}
public void setUploadContentType(String contentType) {
this.contentType = contentType;
}
public void setUploadFileName(String filename) {
this.filename = filename;
}
@Override
public User getModel() {
return user;
}
@Override
public void validate() {
if ("INIT".equalsIgnoreCase(from)) {
clearErrors();
return;
}
if (file == null) {
addFieldError("upload", "Upload an image");
}
}
@Override
public String execute() throws Exception {
if ("INIT".equalsIgnoreCase(from)) {
return INPUT;
}
try {
if (file != null) {
Blob image = Hibernate.createBlob(new FileInputStream(file));
user.setImage(image);
user.setConTentType(contentType);
user.setFileName(filename);
}
userService.save(user);
allUserList = userService.getAllUsers();
addActionMessage("Data Saved successfully");
} catch (Exception ex) {
addActionError("Upload failed");
}
return INPUT;
}
@Override
public void prepare() throws Exception {
allUserList = userService.getAllUsers();
}
}
ImageBytesResult.java
package org.paandav.blog.action;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts2.ServletActionContext;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.Result;
public class ImageBytesResult implements Result {
private static final long serialVersionUID = 1L;
@Override
public void execute(ActionInvocation invocation) throws Exception {
GetImageAction action = (GetImageAction) invocation.getAction();
HttpServletResponse response = ServletActionContext.getResponse();
response.setContentType(action.getContentType());
response.setContentLength(action.getContentLength());
response.getOutputStream().write(action.getImageInBytes());
response.getOutputStream().flush();
}
}
GetImageAction.java
package org.paandav.blog.action;
import org.paandav.blog.vo.User;
import org.paandav.bolg.service.UserService;
import com.opensymphony.xwork2.ActionSupport;
public class GetImageAction extends ActionSupport {
private static final long serialVersionUID = 1L;
private UserService userService;
private Long id;
private User user;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public UserService getUserService() {
return userService;
}
public void setUserService(UserService userService) {
this.userService = userService;
}
@Override
public String execute() throws Exception {
user = userService.getUserById(id);
return "imageBytesResult";
}
public byte[] getImageInBytes() {
return user.getImageInBytes();
}
public String getContentType() {
return user.getConTentType();
}
public String getContentDisposition() {
return "";
}
public int getContentLength() {
return user.getContentLength();
}
public int getBufferSize() {
return 1024;
}
}
FullImageAction.java
package org.paandav.blog.action;
import com.opensymphony.xwork2.ActionSupport;
public class FullImageAction extends ActionSupport {
private static final long serialVersionUID = 1L;
private Long imageId;
public Long getImageId() {
return imageId;
}
public void setImageId(Long imageId) {
this.imageId = imageId;
}
@Override
public String execute() throws Exception {
return INPUT;
}
}
Step 9: Service layer java classes.
UserService.java
package org.paandav.bolg.service;
import java.util.List;
import org.paandav.blog.vo.User;
public interface UserService {
User save(User user) throws Exception;
List<User> getAllUsers() throws Exception;
User getUserById(long id) throws Exception;
}
UserServiceImpl.java
package org.paandav.bolg.service;
import java.util.List;
import org.paandav.blog.dao.UserDAO;
import org.paandav.blog.vo.User;
public class UserServiceImpl implements UserService {
private UserDAO userDao;
public UserDAO getUserDao() {
return userDao;
}
public void setUserDao(UserDAO userDao) {
this.userDao = userDao;
}
@Override
public User save(User user) throws Exception {
return userDao.save(user);
}
@Override
public List<User> getAllUsers() throws Exception {
return userDao.getAllUsers();
}
@Override
public User getUserById(long id) throws Exception {
return userDao.getUserById(id);
}
}
Step 10: DAO layer java classes
BaseDAO.java
package org.paandav.blog.dao;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
public class BaseDAO {
private SessionFactory sessionFactory;
public SessionFactory getSessionFactory() {
return sessionFactory;
}
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
protected Session getSession() {
return sessionFactory.getCurrentSession();
}
}
UserDAO.java
package org.paandav.blog.dao;
import java.util.List;
import org.paandav.blog.vo.User;
public interface UserDAO {
User save(User user) throws Exception;
List<User> getAllUsers() throws Exception;
User getUserById(long id) throws Exception;
}
UserDAOImpl.java
package org.paandav.blog.dao;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.util.List;
import org.paandav.blog.vo.User;
public class UserDAOImpl extends BaseDAO implements UserDAO {
@Override
public User save(User user) throws Exception {
getSession().save(user);
return user;
}
@SuppressWarnings("unchecked")
@Override
public List<User> getAllUsers() throws Exception {
List<User> allUsers = getSession().createQuery("from User").list();
return allUsers;
}
@Override
public User getUserById(long id) throws Exception {
User user = (User) getSession().get(User.class, new Long(id));
// Convert BLOB to byte array
user.setImageInBytes(getImageInBytes(user));
user.setContentLength((int) user.getImage().length());
return user;
}
public byte[] getImageInBytes(User user) {
if (user.getImage() == null) {
return new byte[0];
}
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try {
InputStream is = user.getImage().getBinaryStream();
byte[] buf = new byte[1024];
int i = 0;
while ((i = is.read(buf)) >= 0) {
baos.write(buf, 0, i);
}
is.close();
} catch (Exception ex) {
ex.printStackTrace();
}
return baos.toByteArray();
}
}
Step 11: jsp files in WEB-INF/jsp folder
imageUploader.jsp
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%@ taglib prefix="s" uri="/struts-tags"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body style="font-family: verdana; margin-top: 3%;">
<div>
<table border=1 align="center">
<tr>
<td>First Name</td>
<td>Last Name</td>
<td>Photo</td>
<td>View full Image</td>
</tr>
<s:iterator value="allUserList">
<tr>
<td><s:property value="firstName" /></td>
<td><s:property value="lastName" /></td>
<td align="center"><img alt="" width="150" height="100"
src="getImage.action?id=<s:property value="id" />"></td>
<td><a href="displayFullImage.action?imageId=<s:property value="id" />" target="_new">View full Image</a></td>
</tr>
</s:iterator>
<s:form action="addUserData" theme="simple"
enctype="multipart/form-data">
<tr>
<td><font color="red"><s:fielderror fieldName="firstName" /></font>
<s:textfield name="firstName"></s:textfield></td>
<td><font color="red"><s:fielderror fieldName="lastName" /></font><s:textfield
name="lastName"></s:textfield></td>
<td colspan="3"><font color="red"><s:fielderror
fieldName="upload" /></font><s:file name="upload" label="file" /> <s:submit></s:submit></td>
</tr>
</s:form>
</table>
</div>
</body>
</html>
dispalyFullImage.jsp
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%@ taglib prefix="s" uri="/struts-tags"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
</head>
<body>
<table align="center">
<tr>
<td><img alt="" width="100%" height="100%"
src="getImage.action?id=<s:property value="imageId" />" /></td>
</tr>
</table>
</body>
</html>
Step 12: Now either deploy the application on Tomcat or Other Server or start server from eclipse and access the URL
http://localhost:8080/blogs_tutorials/addUserData.action?from=INIT
It will display a screen with upload options. Fill the data and upload the photos. All uploaded photos will be displayed on the same screen and you will see small uploaded images like below
If you want to see the original size image click on View full Image link and it will display full image in new browser window like below.