Show
Tutorial:Saving/Retreving BLOB object in Spring 3 MVC and Hibernateby Viral Patel · January 11, 2011 Working with BLOB / CLOB data types in database is sometime a trivial task. I found particularly when working with Hibernate 3 to store and retrieve BLOB objects we need certain things to be taken care of. Let us see a tutorial where we will using Spring 3 MVC and Hibernate 3 to store and retrieve blob objects in database. Our GoalOur goal is to create a Document Manager application in Spring 3 MVC and Hibernate. Following is the functionality.
Step 1: Create Database TableFor Document Manager application, we will use MySQL database. Create a table documents in MySQL database docdb. This is very preliminary example and thus we have minimum columns to represent a document. Feel free to extend this example and create a more complex application.CREATE DATABASE `docdb`;
USE `docdb`;
CREATE TABLE `documents` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(200) NOT NULL,
`description` text NOT NULL,
`filename` varchar(200) NOT NULL,
`content` mediumblob NOT NULL, /* for ORACLE enter BLOB*/
`content_type` varchar(255) NOT NULL,
`created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
);
Code language: SQL (Structured Query Language) (sql)Step 2: Create Maven Project in EclipseThe document manager application will use Maven for build and dependency management. For this we will use the Maven Dynamic Web Project in Eclipse as the base architecture of our application. Or directly download the below source code: Maven Dynamic Web Project (6.7 KB) Once you have imported / created the Maven web project in Eclipse. Copy following content into Mavens pom.xml file. These are the dependencies we will use in our Document manager application. File: /pom.xml<?xml version="1.0" encoding="UTF-8"?><project>
<modelVersion>4.0.0</modelVersion>
<groupId>MavenWeb</groupId>
<artifactId>MavenWeb</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>
<description></description>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.5</source>
<target>1.5</target>
</configuration>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>2.0</version>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${org.springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${org.springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${org.springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${org.springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>${org.springframework.version}</version>
</dependency>
<dependency>
<groupId>taglibs</groupId>
<artifactId>standard</artifactId>
<version>1.1.2</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.1.2</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>3.3.2.ga</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.10</version>
</dependency>
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>20030825.184428</version>
</dependency>
<dependency>
<groupId>commons-pool</groupId>
<artifactId>commons-pool</artifactId>
<version>1.5.4</version>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.2.1</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>1.3</version>
</dependency>
</dependencies>
<properties>
<org.springframework.version>3.0.2.RELEASE</org.springframework.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
</project>
Code language: HTML, XML (xml) Unzip the source code to your hard drive and import the project in Eclipse. Once the project is imported in Eclipse, we will create package structure for Java source. First rename the project to DocumentManager and create following packages under src/main/java folder.
Entity class The Hibernate model classLet us start with the coding of Document manager application. First we will create a model object or hibernate POJO class to store document information. Also this class will be an Entity class and will be linked with DOCUMENTS table in database. Create a java class Document.java under net.viralpatel.docmanager.model package and copy following code into it. File: /src/main/java/net/viralpatel/docmanager/model/Document.javapackage net.viralpatel.docmanager.model;
import java.sql.Blob;
import java.sql.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Lob;
import javax.persistence.Table;
@Entity
@Table(name="documents")
public class Document {
@Id
@GeneratedValue
@Column(name="id")
private Integer id;
@Column(name="name")
private String name;
@Column(name="description")
private String description;
@Column(name="filename")
private String filename;
@Column(name="content")
@Lob
private Blob content;
@Column(name="content_type")
private String contentType;
@Column(name="created")
private Date created;
//Getter and Setter methods
}
Code language: Java (java)The first thing youll notice is that the import statements import from javax.persistence rather than a Hibernate or Spring package. Using Hibernate with Spring, the standard JPA annotations work just as well and thats what Im using here.
The Data Access (DAO) LayerThe DAO layer of Document Manager application consist of a class DocumentDAO. Ideal solution will be to create an interface (DocumentDAO) and its corresponding implementation class DocumentDAOImpl. But for sake of simplicity we will create just normal DAO class DocumentDAO.java. File: src/main/java/net/viralpatel/docmanager/dao/DocumentDAO.javapackage net.viralpatel.docmanager.dao;
import java.util.List;
import net.viralpatel.docmanager.model.Document;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
@Repository
public class DocumentDAO {
@Autowired
private SessionFactory sessionFactory;
@Transactional
public void save(Document document) {
Session session = sessionFactory.getCurrentSession();
session.save(document);
}
@Transactional
public List<Document> list() {
Session session = sessionFactory.getCurrentSession();
List<Document> documents = null;
try {
documents = (List<Document>)session.createQuery("from Document").list();
} catch (HibernateException e) {
e.printStackTrace();
}
return documents;
}
@Transactional
public Document get(Integer id) {
Session session = sessionFactory.getCurrentSession();
return (Document)session.get(Document.class, id);
}
@Transactional
public void remove(Integer id) {
Session session = sessionFactory.getCurrentSession();
Document document = (Document)session.get(Document.class, id);
session.delete(document);
}
}
Code language: Java (java)Methods:
Adding Spring MVC Support to WebapplicationLet us add Spring MVC support to our web application. Update the web.xml file and add servlet mapping for org.springframework.web.servlet.DispatcherServlet. Also note that we have mapped url / with springServlet so all the request are handled by spring. File: /src/webapp/WEB-INF/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"
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
id="WebApp_ID" version="2.5">
<display-name>DocumentManager</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>spring</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>spring</servlet-name>
<url-pattern>*.html</url-pattern>
</servlet-mapping>
</web-app>
Code language: HTML, XML (xml)Once the web.xml is configured, let us add spring-servlet.xml and jdbc.properties files in /src/main/webapp/WEB-INF folder. File: /src/main/webapp/WEB-INF/jdbc.propertiesjdbc.driverClassName= com.mysql.jdbc.Driver
jdbc.dialect=org.hibernate.dialect.MySQLDialect
jdbc.databaseurl=jdbc:mysql://localhost:3306/docdb
jdbc.username=root
jdbc.password=password
Code language: HTML, XML (xml)The jdbc.properties file contains database connection information such as database url, username, password, driver class. You may want to edit the driverclass and dialect to other DB if you are not using MySQL. File: /src/main/webapp/WEB-INF/spring-servlet.xml<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:lang="http://www.springframework.org/schema/lang"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:util="http://www.springframework.org/schema/util"
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/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee.xsd
http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
<context:annotation-config />
<context:component-scan base-package="net.viralpatel.docmanager" />
<bean id="jspViewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass"
value="org.springframework.web.servlet.view.JstlView" />
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
</bean>
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
p:location="/WEB-INF/jdbc.properties" />
<bean id="dataSource"
class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"
p:driverClassName="${jdbc.driverClassName}"
p:url="${jdbc.databaseurl}" p:username="${jdbc.username}"
p:password="${jdbc.password}" />
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation">
<value>classpath:hibernate.cfg.xml</value>
</property>
<property name="configurationClass">
<value>org.hibernate.cfg.AnnotationConfiguration</value>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${jdbc.dialect}</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.connection.SetBigStringTryClob">true</prop>
<prop key="hibernate.jdbc.batch_size">0</prop>
</props>
</property>
</bean>
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- one of the properties available; the maximum file size in bytes -->
<property name="maxUploadSize" value="10000000" />
</bean>
<tx:annotation-driven />
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
</beans>
Code language: HTML, XML (xml)The spring-servlet.xml file contains different spring mappings such as transaction manager, hibernate session factory bean, data source etc.
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<mapping class="net.viralpatel.docmanager.model.Document" />
</session-factory>
</hibernate-configuration>
Code language: HTML, XML (xml)The Controller Spring MVC controller classWe are almost done with our application. Just add following Spring controller class DocumentController.java to net.viralpatel.docmanager.controller package. File: /src/main/java/net/viralpatel/docmanager/controller/DocumentController.javapackage net.viralpatel.docmanager.controller;
import java.io.IOException;
import java.io.OutputStream;
import java.sql.Blob;
import java.sql.SQLException;
import java.util.Map;
import javax.servlet.http.HttpServletResponse;
import net.viralpatel.docmanager.dao.DocumentDAO;
import net.viralpatel.docmanager.model.Document;
import org.apache.commons.io.IOUtils;
import org.hibernate.Hibernate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;
@Controller
public class DocumentController {
@Autowired
private DocumentDAO documentDao;
@RequestMapping("/index")
public String index(Map<String, Object> map) {
try {
map.put("document", new Document());
map.put("documentList", documentDao.list());
}catch(Exception e) {
e.printStackTrace();
}
return "documents";
}
@RequestMapping(value = "/save", method = RequestMethod.POST)
public String save(
@ModelAttribute("document") Document document,
@RequestParam("file") MultipartFile file) {
System.out.println("Name:" + document.getName());
System.out.println("Desc:" + document.getDescription());
System.out.println("File:" + file.getName());
System.out.println("ContentType:" + file.getContentType());
try {
Blob blob = Hibernate.createBlob(file.getInputStream());
document.setFilename(file.getOriginalFilename());
document.setContent(blob);
document.setContentType(file.getContentType());
} catch (IOException e) {
e.printStackTrace();
}
try {
documentDao.save(document);
} catch(Exception e) {
e.printStackTrace();
}
return "redirect:/index.html";
}
@RequestMapping("/download/{documentId}")
public String download(@PathVariable("documentId")
Integer documentId, HttpServletResponse response) {
Document doc = documentDao.get(documentId);
try {
response.setHeader("Content-Disposition", "inline;filename=\"" +doc.getFilename()+ "\"");
OutputStream out = response.getOutputStream();
response.setContentType(doc.getContentType());
IOUtils.copy(doc.getContent().getBinaryStream(), out);
out.flush();
out.close();
} catch (IOException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
@RequestMapping("/remove/{documentId}")
public String remove(@PathVariable("documentId")
Integer documentId) {
documentDao.remove(documentId);
return "redirect:/index.html";
}
}
Code language: Java (java)The spring controller defines four methods to manipulate document manager application.
<%@taglib uri="http://www.springframework.org/tags" prefix="spring"%>
<%@taglib uri="http://www.springframework.org/tags/form" prefix="form"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<html>
<head>
<title>Document Manager - viralpatel.net</title>
</head>
<body>
<h2>Document Manager</h2>
<h3>Add new document</h3>
<form:form method="post" action="save.html" commandName="document" enctype="multipart/form-data">
<form:errors path="*" cssClass="error"/>
<table>
<tr>
<td><form:label path="name">Name</form:label></td>
<td><form:input path="name" /></td>
</tr>
<tr>
<td><form:label path="description">Description</form:label></td>
<td><form:textarea path="description" /></td>
</tr>
<tr>
<td><form:label path="content">Document</form:label></td>
<td><input type="file" name="file" id="file"></input></td>
</tr>
<tr>
<td colspan="2">
<input type="submit" value="Add Document"/>
</td>
</tr>
</table>
</form:form>
<br/>
<h3>Document List</h3>
<c:if test="${!empty documentList}">
<table class="data">
<tr>
<th>Name</th>
<th>Description</th>
<th> </th>
</tr>
<c:forEach items="${documentList}" var="document">
<tr>
<td width="100px">${document.name}</td>
<td width="250px">${document.description}</td>
<td width="20px">
<a href="${pageContext.request.contextPath}/download/${document.id}.html"><img
src="${pageContext.request.contextPath}/img/save_icon.gif" border="0"
title="Download this document"/></a>
<a href="${pageContext.request.contextPath}/remove/${document.id}.html"
onclick="return confirm('Are you sure you want to delete this document?')"><img
src="${pageContext.request.contextPath}/img/delete_icon.gif" border="0"
title="Delete this document"/></a>
</td>
</tr>
</c:forEach>
</table>
</c:if>
</body>
</html>
Code language: HTML, XML (xml)Download Source codeClick here to download full source code of Document manager application (16 KB)Thats All folksCompile and execute the Document manager application in Eclipse. Open URL http://localhost:8080/DocumentManager/index.html |