<?xml version="1.0" encoding="UTF-8"?> <rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" ><channel><title>ViralPatel.net &#187; Spring</title> <atom:link href="http://viralpatel.net/blogs/category/spring/feed" rel="self" type="application/rss+xml" /><link>http://viralpatel.net/blogs</link> <description>Tutorials, Java, J2EE, Struts, AJAX, JavaScript, CSS, Web 2.0, MySQL, Articles</description> <lastBuildDate>Tue, 24 Jan 2012 13:45:10 +0000</lastBuildDate> <language>en</language> <sy:updatePeriod>hourly</sy:updatePeriod> <sy:updateFrequency>1</sy:updateFrequency> <generator>http://wordpress.org/?v=3.3.1</generator> <item><title>Spring MVC: Multiple Row Form Submit using List of Beans</title><link>http://viralpatel.net/blogs/2011/12/spring-mvc-multi-row-submit-java-list.html</link> <comments>http://viralpatel.net/blogs/2011/12/spring-mvc-multi-row-submit-java-list.html#comments</comments> <pubDate>Thu, 01 Dec 2011 06:48:24 +0000</pubDate> <dc:creator>Viral Patel</dc:creator> <category><![CDATA[Spring]]></category> <category><![CDATA[Spring 3 MVC]]></category> <category><![CDATA[Java]]></category> <category><![CDATA[spring beans]]></category> <category><![CDATA[spring mvc]]></category><guid isPermaLink="false">http://viralpatel.net/blogs/?p=2235</guid> <description><![CDATA[Recently I had a requirement where using Spring MVC we had to take inputs multiple rows of data from user. The form had many rows which user can edit and submit. Spring MVC provides very simple yet elegant way of collecting data from multiple rows from HTML form and store them in List of Beans [...]]]></description> <content:encoded><![CDATA[<p>Recently I had a requirement where using Spring MVC we had to take inputs multiple rows of data from user. The form had many rows which user can edit and submit. Spring MVC provides very simple yet elegant way of collecting data from multiple rows from HTML form and store them in List of Beans in Java.</p><p>Lets look at the requirement first. We have a screen where data for multiple Contacts is displayed. The Contact data is displayed in an HTML table. Each row in the table represents a single contact. Contact details consist of attributes such as Firstname, Lastname, Email and Phone number.</p><p><strong>Related:</strong> <a ref="nofollow" href="http://viralpatel.net/blogs/2010/06/tutorial-spring-3-mvc-introduction-spring-mvc-framework.html">Spring 3 MVC Tutorial Series (Must Read)</a></p><p>The Add Contact form would look like following:<br /> <img src="http://viralpatel.net/blogs/wp-content/uploads/2011/11/spring-mvc-multi-row-form.png" alt="spring-mvc-multi-row-form" title="spring-mvc-multi-row-form" width="630" height="220" class="aligncenter size-full wp-image-2237" /></p><p>Lets see the code behind this example.</p><p>Tools and Technologies used:</p><ol><li>Java 5 or above</li><li>Eclipse 3.3 or above</li><li>Spring MVC 3.0</li></ol><h2>Step 1: Create Project Structure</h2><p>Open Eclipse and create a <strong>Dynamic Web Project</strong>.<br /> <img src="http://viralpatel.net/blogs/wp-content/uploads/2010/06/eclipse-dynamic-web-project.png" alt="eclipse-dynamic-web-project" title="eclipse-dynamic-web-project" width="373" height="458" class="aligncenter size-full wp-image-2065" /></p><p>Enter project name as <strong>SpringMVC_Multi_Row</strong> and press <em>Finish</em>.</p><h2>Step 2: Copy Required JAR files</h2><p>Once the Dynamic Web Project is created in Eclipse, copy the required JAR files under <strong>WEB-INF/lib</strong> folder. Following are the list of JAR files:<br /> <img src="http://viralpatel.net/blogs/wp-content/uploads/2011/11/spring-mvc-multi-row-jar-files.png" alt="spring-mvc-multi-row-jar-files" title="spring-mvc-multi-row-jar-files" width="329" height="203" class="aligncenter size-full wp-image-2238" /></p><p><br/></p><h2>Step 3: Adding Spring MVC support</h2><p>Once the basic project setup is done, we will add Spring 3 MVC support. For that first modify default web.xml and add springs DispatcherServlet.</p><p><em>File: /WebContent/WEB-INF/web.xml</em></p><pre class="brush: xml; title: ; notranslate">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;web-app xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
	xmlns=&quot;http://java.sun.com/xml/ns/javaee&quot;
	xmlns:web=&quot;http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd&quot;
	xsi:schemaLocation=&quot;http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd&quot;
	id=&quot;WebApp_ID&quot; version=&quot;2.5&quot;&gt;
	&lt;display-name&gt;Spring3MVC-Multi-Row&lt;/display-name&gt;
	&lt;servlet&gt;
		&lt;servlet-name&gt;spring&lt;/servlet-name&gt;
		&lt;servlet-class&gt;org.springframework.web.servlet.DispatcherServlet&lt;/servlet-class&gt;
		&lt;load-on-startup&gt;1&lt;/load-on-startup&gt;
	&lt;/servlet&gt;
	&lt;servlet-mapping&gt;
		&lt;servlet-name&gt;spring&lt;/servlet-name&gt;
		&lt;url-pattern&gt;*.html&lt;/url-pattern&gt;
	&lt;/servlet-mapping&gt;
&lt;/web-app&gt;
</pre><p><strong>Related:</strong> <a href="http://viralpatel.net/blogs/2010/06/tutorial-spring-3-mvc-introduction-spring-mvc-framework.html">Tutorial: Learn Spring MVC Lifecycle</a></p><p>Now add spring-servlet.xml file under WEB-INF folder.</p><p><em>File: /WebContent/WEB-INF/spring-servlet.xml</em></p><pre class="brush: xml; highlight: [10,11]; title: ; notranslate">
&lt;?xml  version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;beans xmlns=&quot;http://www.springframework.org/schema/beans&quot;
	xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
	xmlns:context=&quot;http://www.springframework.org/schema/context&quot;
	xmlns:mvc=&quot;http://www.springframework.org/schema/mvc&quot;
	xsi:schemaLocation=&quot;http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
		http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd&quot;&gt;

	&lt;context:annotation-config /&gt;
	&lt;context:component-scan base-package=&quot;net.viralpatel.spring3.controller&quot; /&gt;	

	&lt;bean id=&quot;jspViewResolver&quot;
		class=&quot;org.springframework.web.servlet.view.InternalResourceViewResolver&quot;&gt;
		&lt;property name=&quot;viewClass&quot;
			value=&quot;org.springframework.web.servlet.view.JstlView&quot; /&gt;
		&lt;property name=&quot;prefix&quot; value=&quot;/WEB-INF/jsp/&quot; /&gt;
		&lt;property name=&quot;suffix&quot; value=&quot;.jsp&quot; /&gt;
	&lt;/bean&gt;
&lt;/beans&gt;
</pre><p>Note that in above spring-servlet file, line 10, 11 defines context:annotation-config and component-scan tags. These tags let Spring MVC knows that the spring mvc annotations are used to map controllers and also the path from where the controller files needs to be loaded. All the files below package <code>net.viralpatel.spring3.controller</code> will be picked up and loaded by spring mvc.</p><h2>Step 4: Add Spring Controller and Form classes</h2><p><em>File: /src/net/viralpatel/spring3/form/Contact.java</em></p><pre class="brush: java; title: ; notranslate">
package net.viralpatel.spring3.form;

public class Contact {
	private String firstname;
	private String lastname;
	private String email;
	private String phone;

	public Contact() {
	}

	public Contact(String firstname, String lastname, String email, String phone) {
		this.firstname = firstname;
		this.lastname = lastname;
		this.email = email;
		this.phone = phone;
	}

	// Getter and Setter methods
}
</pre><p><em>File: /src/net/viralpatel/spring3/form/ContactForm.java</em></p><pre class="brush: java; highlight: [7]; title: ; notranslate">
package net.viralpatel.spring3.form;

import java.util.List;

public class ContactForm {

	private List&lt;Contact&gt; contacts;

	public List&lt;Contact&gt; getContacts() {
		return contacts;
	}

	public void setContacts(List&lt;Contact&gt; contacts) {
		this.contacts = contacts;
	}
}
</pre><p>Note line 7 in above code how we have defined a List of bean Contact which will hold the multi-row data for each Contact.</p><p><em>File: /src/net/viralpatel/spring3/controller/ContactController.java</em></p><pre class="brush: java; title: ; notranslate">
package net.viralpatel.spring3.controller;

import java.util.ArrayList;
import java.util.List;

import net.viralpatel.spring3.form.Contact;
import net.viralpatel.spring3.form.ContactForm;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;

@Controller
public class ContactController {

	private static List&lt;Contact&gt; contacts = new ArrayList&lt;Contact&gt;();

	static {
		contacts.add(new Contact(&quot;Barack&quot;, &quot;Obama&quot;, &quot;barack.o@whitehouse.com&quot;, &quot;147-852-965&quot;));
		contacts.add(new Contact(&quot;George&quot;, &quot;Bush&quot;, &quot;george.b@whitehouse.com&quot;, &quot;785-985-652&quot;));
		contacts.add(new Contact(&quot;Bill&quot;, &quot;Clinton&quot;, &quot;bill.c@whitehouse.com&quot;, &quot;236-587-412&quot;));
		contacts.add(new Contact(&quot;Ronald&quot;, &quot;Reagan&quot;, &quot;ronald.r@whitehouse.com&quot;, &quot;369-852-452&quot;));
	}

	@RequestMapping(value = &quot;/get&quot;, method = RequestMethod.GET)
	public ModelAndView get() {

		ContactForm contactForm = new ContactForm();
		contactForm.setContacts(contacts);

		return new ModelAndView(&quot;add_contact&quot; , &quot;contactForm&quot;, contactForm);
	}

	@RequestMapping(value = &quot;/save&quot;, method = RequestMethod.POST)
	public ModelAndView save(@ModelAttribute(&quot;contactForm&quot;) ContactForm contactForm) {
		System.out.println(contactForm);
		System.out.println(contactForm.getContacts());
		List&lt;Contact&gt; contacts = contactForm.getContacts();

		if(null != contacts &amp;&amp; contacts.size() &gt; 0) {
			ContactController.contacts = contacts;
			for (Contact contact : contacts) {
				System.out.printf(&quot;%s \t %s \n&quot;, contact.getFirstname(), contact.getLastname());
			}
		}

		return new ModelAndView(&quot;show_contact&quot;, &quot;contactForm&quot;, contactForm);
	}
}
</pre><p>In above ContactController class, we have defile two methods: <code>get()</code> and <code>save()</code>.</p><p><strong>get() method</strong>: This method is used to display Contact form with pre-populated values. Note we added a list of contacts (Contacts are initialize in static block) in <code>ContactForm</code> bean object and set this inside a <code>ModelAndView</code> object. The add_contact.jsp is displayed which in turns display all contacts in tabular form to edit.</p><p><strong>save() method:</strong> This method is used to fetch contact data from the form submitted and save it in the static array. Also it renders <code>show_contact.jsp</code> file to display contacts in tabular form.</p><h2>Step 5: Add JSP View files</h2><p>Add following files under <strong>WebContent/WEB-INF/jsp/</strong> directory.</p><p><em>File: /WebContent/WEB-INF/jsp/add_contact.jsp</em></p><pre class="brush: xml; title: ; notranslate">
&lt;%@taglib uri=&quot;http://www.springframework.org/tags&quot; prefix=&quot;spring&quot;%&gt;
&lt;%@taglib uri=&quot;http://www.springframework.org/tags/form&quot; prefix=&quot;form&quot;%&gt;
&lt;%@taglib uri=&quot;http://java.sun.com/jsp/jstl/core&quot; prefix=&quot;c&quot;%&gt;
&lt;html&gt;
&lt;head&gt;
	&lt;title&gt;Spring 3 MVC Multipe Row Submit - viralpatel.net&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;

&lt;h2&gt;Spring MVC Multiple Row Form Submit example&lt;/h2&gt;
&lt;form:form method=&quot;post&quot; action=&quot;save.html&quot; modelAttribute=&quot;contactForm&quot;&gt;
	&lt;table&gt;
	&lt;tr&gt;
		&lt;th&gt;No.&lt;/th&gt;
		&lt;th&gt;Name&lt;/th&gt;
		&lt;th&gt;Lastname&lt;/th&gt;
		&lt;th&gt;Email&lt;/th&gt;
		&lt;th&gt;Phone&lt;/th&gt;
	&lt;/tr&gt;
	&lt;c:forEach items=&quot;${contactForm.contacts}&quot; var=&quot;contact&quot; varStatus=&quot;status&quot;&gt;
		&lt;tr&gt;
			&lt;td align=&quot;center&quot;&gt;${status.count}&lt;/td&gt;
			&lt;td&gt;&lt;input name=&quot;contacts[${status.index}].firstname&quot; value=&quot;${contact.firstname}&quot;/&gt;&lt;/td&gt;
			&lt;td&gt;&lt;input name=&quot;contacts[${status.index}].lastname&quot; value=&quot;${contact.lastname}&quot;/&gt;&lt;/td&gt;
			&lt;td&gt;&lt;input name=&quot;contacts[${status.index}].email&quot; value=&quot;${contact.email}&quot;/&gt;&lt;/td&gt;
			&lt;td&gt;&lt;input name=&quot;contacts[${status.index}].phone&quot; value=&quot;${contact.phone}&quot;/&gt;&lt;/td&gt;
		&lt;/tr&gt;
	&lt;/c:forEach&gt;
&lt;/table&gt;
&lt;br/&gt;
&lt;input type=&quot;submit&quot; value=&quot;Save&quot; /&gt;

&lt;/form:form&gt;
&lt;/body&gt;
&lt;/html&gt;
</pre><p>In above JSP file, we display contact details in a table. Also each attribute is displayed in a textbox. Note that <strong>modelAttribute=&#8221;contactForm&#8221;</strong> is defined in <code><br /><form:form /></code> tag. This tag defines the modelAttribute name for Spring mapping. On form submission, Spring will parse the values from request and fill the ContactForm bean and pass it to the controller.</p><p>Also note how we defined textboxes name. It is in form <strong>contacts[i].a</strong>. Thus Spring knows that we want to display the List item with index <strong>i</strong> and its attribute <strong>a</strong>.</p><p><code>contacts[${status.index}].firstname</code> will generate each rows as follows:</p><p>contacts[0].firstname  // mapped to first item in contacts list<br /> contacts[1].firstname  // mapped to second item in contacts list<br /> contacts[2].firstname  // mapped to third item in contacts list</p><h3>Spring 3 MVC and path attribute and square bracket</h3><p>One thing here is worth noting that we haven&#8217;t used Spring&#8217;s <code><br /><form:input /></code> tag to render textboxes. This is because Spring MVC 3 has a unique way of handling <strong>path</strong> attribute for <code><br /><form:input /></code> tag. If we define the textbox as follows:</p><pre class="brush: xml; gutter: false; title: ; notranslate">
&lt;form:input path=&quot;contacts[${status.index}].firstname&quot; /&gt;
</pre><p>Then instead of converting it to following HTML code:</p><pre class="brush: xml; gutter: false; title: ; notranslate">
&lt;input name=&quot;contacts[0].firstname&quot; /&gt;
&lt;input name=&quot;contacts[1].firstname&quot; /&gt;
&lt;input name=&quot;contacts[2].firstname&quot; /&gt;
</pre><p>It converts it into following:</p><pre class="brush: xml; gutter: false; title: ; notranslate">
&lt;input name=&quot;contacts0.firstname&quot; /&gt;
&lt;input name=&quot;contacts1.firstname&quot; /&gt;
&lt;input name=&quot;contacts2.firstname&quot; /&gt;
</pre><p>Note how it removed square brackets [ ] from name attribute. In previous versions of Spring (before 2.5) the square bracket were allowed in <strong>name</strong> attribute.</p><p>It seems w3c has later changed the HTML specification and removed  [ ] from html input name.<br /> Read the specification <a ref="nofollow" href="http://www.w3.org/TR/html4/types.html#type-name">http://www.w3.org/TR/html4/types.html#type-name</a>. It clearly says that:</p><blockquote><p>ID and NAME tokens must begin with a letter ([A-Za-z]) and may be followed by any number of letters, digits ([0-9]), hyphens (&#8220;-&#8221;), underscores (&#8220;_&#8221;), colons (&#8220;:&#8221;), and periods (&#8220;.&#8221;).</p></blockquote><p>Thus, square brackets aren&#8217;t allowed in name attribute! And thus Spring 3 onwards this was implemented.</p><p>So far I haven&#8217;t got any workaround to use springs <code>&lt;form:input /&gt;</code> tag instead of plain html <code>&lt;input /&gt;</code> to render and fetch data from multiple rows.</p><p><em>File: /WebContent/WEB-INF/jsp/show_contact.jsp</em></p><pre class="brush: xml; title: ; notranslate">
&lt;%@taglib uri=&quot;http://www.springframework.org/tags&quot; prefix=&quot;spring&quot;%&gt;
&lt;%@taglib uri=&quot;http://www.springframework.org/tags/form&quot; prefix=&quot;form&quot;%&gt;
&lt;%@taglib uri=&quot;http://java.sun.com/jsp/jstl/core&quot; prefix=&quot;c&quot;%&gt;
&lt;html&gt;
&lt;head&gt;
	&lt;title&gt;Spring 3 MVC Multipe Row Submit - viralpatel.net&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;h2&gt;Show Contacts&lt;/h2&gt;
&lt;table width=&quot;50%&quot;&gt;
	&lt;tr&gt;
		&lt;th&gt;Name&lt;/th&gt;
		&lt;th&gt;Lastname&lt;/th&gt;
		&lt;th&gt;Email&lt;/th&gt;
		&lt;th&gt;Phone&lt;/th&gt;
	&lt;/tr&gt;
	&lt;c:forEach items=&quot;${contactForm.contacts}&quot; var=&quot;contact&quot; varStatus=&quot;status&quot;&gt;
		&lt;tr&gt;
			&lt;td&gt;${contact.firstname}&lt;/td&gt;
			&lt;td&gt;${contact.lastname}&lt;/td&gt;
			&lt;td&gt;${contact.email}&lt;/td&gt;
			&lt;td&gt;${contact.phone}&lt;/td&gt;
		&lt;/tr&gt;
	&lt;/c:forEach&gt;
&lt;/table&gt;
&lt;br/&gt;
&lt;input type=&quot;button&quot; value=&quot;Back&quot; onclick=&quot;javascript:history.back()&quot;/&gt;
&lt;/body&gt;
&lt;/html&gt;
</pre><p><em>File: /WebContent/index.jsp</em></p><pre class="brush: xml; gutter: false; title: ; notranslate">
&lt;jsp:forward page=&quot;get.html&quot;&gt;&lt;/jsp:forward&gt;
</pre><p><br/></p><h2>Final Project Structure</h2><p>Once we have added all relevant source files and jar files, the project structure should look like following:<br /> <img src="http://viralpatel.net/blogs/wp-content/uploads/2011/12/spring-multi-row-project-structure.png" alt="spring-multi-row-project-structure" title="spring-multi-row-project-structure" width="251" height="373" class="aligncenter size-full wp-image-2244" /></p><p><br/></p><h2>Step 6: Execute it</h2><p>Execute the web application <strong>Right click on project > Run As > Run on Server</strong>.</p><p><strong>Add Contact page</strong><br /> <img src="http://viralpatel.net/blogs/wp-content/uploads/2011/11/spring-mvc-multi-row-form.png" alt="" title="spring-mvc-multi-row-form" width="630" height="220" class="aligncenter size-full wp-image-2237" /></p><p><strong>Show Contact page</strong><br /> <img src="http://viralpatel.net/blogs/wp-content/uploads/2011/12/spring-multiple-row-list-show-page.png" alt="spring-multiple-row-list-show-page" title="spring-multiple-row-list-show-page" width="435" height="200" class="aligncenter size-full wp-image-2245" /></p><h2>Download Source Code</h2><p><strong><a href="http://viralpatel.net/blogs/download/spring/SpringMVC_Multi_Row.zip">Spring-MVC-Multiple-Row-List-example.zip (2.9 mb)</a></strong></p><div id="relatedpost"><h2  class="related_post_title">Related Posts</h2><ul class="related_post"><li><a href="http://viralpatel.net/blogs/2012/01/convert-array-to-set-java-arraylist.html" title="Convert Arrays to Set in Java">Convert Arrays to Set in Java</a></li><li><a href="http://viralpatel.net/blogs/2205/change-spring-servlet-filename-configuration" title="Change spring-servlet.xml Filename (Spring Web Contenxt Configuration Filename)">Change spring-servlet.xml Filename (Spring Web Contenxt Configuration Filename)</a></li><li><a href="http://viralpatel.net/blogs/2011/01/tutorial-save-get-blob-object-spring-3-mvc-hibernate.html" title="Tutorial:Saving/Retreving BLOB object in Spring 3 MVC and Hibernate">Tutorial:Saving/Retreving BLOB object in Spring 3 MVC and Hibernate</a></li><li><a href="http://viralpatel.net/blogs/2011/01/java-convert-exponential-decimal-double-number.html" title="Java: Convert Exponential form to Decimal number format in Java ">Java: Convert Exponential form to Decimal number format in Java </a></li><li><a href="http://viralpatel.net/blogs/2010/11/spring3-mvc-hibernate-maven-tutorial-eclipse-example.html" title="Tutorial:Create Spring 3 MVC Hibernate 3 Example using Maven in Eclipse">Tutorial:Create Spring 3 MVC Hibernate 3 Example using Maven in Eclipse</a></li><li><a href="http://viralpatel.net/blogs/2010/10/convert-string-to-enum-instance-string-enum-java.html" title="Convert String to Enum Instance in Java">Convert String to Enum Instance in Java</a></li><li><a href="http://viralpatel.net/blogs/2010/10/spring-3-mvc-themes-tutorial-example.html" title="Spring 3 MVC: Themes in Spring-Tutorial with Example">Spring 3 MVC: Themes in Spring-Tutorial with Example</a></li></ul></div>]]></content:encoded> <wfw:commentRss>http://viralpatel.net/blogs/2011/12/spring-mvc-multi-row-submit-java-list.html/feed</wfw:commentRss> <slash:comments>10</slash:comments> </item> <item><title>Change spring-servlet.xml Filename (Spring Web Contenxt Configuration Filename)</title><link>http://viralpatel.net/blogs/2205/change-spring-servlet-filename-configuration</link> <comments>http://viralpatel.net/blogs/2205/change-spring-servlet-filename-configuration#comments</comments> <pubDate>Fri, 18 Nov 2011 09:30:01 +0000</pubDate> <dc:creator>Viral Patel</dc:creator> <category><![CDATA[Spring]]></category> <category><![CDATA[Spring 3 MVC]]></category> <category><![CDATA[application-context]]></category> <category><![CDATA[spring mvc]]></category> <category><![CDATA[web.xml]]></category><guid isPermaLink="false">http://viralpatel.net/blogs/?p=2205</guid> <description><![CDATA[The first thing that we do when we want to implement Spring MVC in our project is to add DispatcherServlets entry in deployment descriptor (web.xml). Also we write a spring web configuration xxxx-servlet.xml which contains all the MVC mappings and data. By default the name of file must be XXX-servlet.xml where XXX is the name [...]]]></description> <content:encoded><![CDATA[<p><a href="http://viralpatel.net/blogs/wp-content/uploads/2011/02/spring-logo.png"><img src="http://viralpatel.net/blogs/wp-content/uploads/2011/02/spring-logo.png" alt="spring-logo" title="spring-logo" width="258" height="151" class="alignleft size-full wp-image-2166" /></a> The first thing that we do when we want to implement Spring MVC in our project is to add DispatcherServlets entry in deployment descriptor (web.xml). Also we write a spring web configuration xxxx-servlet.xml which contains all the MVC mappings and data.</p><p>By default the name of file must be XXX-servlet.xml where XXX is the name of servlet. For example in below entry in Web.xml we defined servlet named &#8220;spring&#8221;.</p><pre class="brush: xml; highlight: [2]; title: ; notranslate">
	&lt;servlet&gt;
		&lt;servlet-name&gt;spring&lt;/servlet-name&gt;
		&lt;servlet-class&gt;
			org.springframework.web.servlet.DispatcherServlet
		&lt;/servlet-class&gt;
		&lt;load-on-startup&gt;1&lt;/load-on-startup&gt;
	&lt;/servlet&gt;
	&lt;servlet-mapping&gt;
		&lt;servlet-name&gt;spring&lt;/servlet-name&gt;
		&lt;url-pattern&gt;*.html&lt;/url-pattern&gt;
	&lt;/servlet-mapping&gt;
</pre><p>Note that the servlet name is &#8220;spring&#8221; and thus, Spring will by default load file named &#8220;spring-servlet.xml&#8221; from your webapps WEB-INF folder.</p><h4>What if we want to load a file called &#8220;bean.xml&#8221; instead of default &#8220;XXX-servlet.xml&#8221; ?</h4><p>Well, this can be achieved by passing one init-parameter to spring&#8217;s DispatcherServlet. Check the following web.xml snippet.</p><pre class="brush: xml; highlight: [6,7,8,9]; title: ; notranslate">
	&lt;servlet&gt;
		&lt;servlet-name&gt;spring&lt;/servlet-name&gt;
		&lt;servlet-class&gt;
			org.springframework.web.servlet.DispatcherServlet
		&lt;/servlet-class&gt;
		&lt;init-param&gt;
			&lt;param-name&gt;contextConfigLocation&lt;/param-name&gt;
		        &lt;param-value&gt;/WEB-INF/bean.xml&lt;/param-value&gt;
		&lt;/init-param&gt;
		&lt;load-on-startup&gt;1&lt;/load-on-startup&gt;
	&lt;/servlet&gt;
	&lt;servlet-mapping&gt;
		&lt;servlet-name&gt;spring&lt;/servlet-name&gt;
		&lt;url-pattern&gt;*.html&lt;/url-pattern&gt;
	&lt;/servlet-mapping&gt;
</pre><p>Note that in above code snippet, we have passed an init-param to DispatcherServlet called <strong>contextConfigLocation</strong>. Using this parameter not only can we change the name of Spring&#8217;s web context file but also change its location.</p><p>This parameter will call <code>setContextConfigLocation</code> method on <code>DispatcherServlet</code> and overrides default context config file. Note that it is possible to add multiple locations separated by any number of commas and spaced.</p><pre class="brush: xml; highlight: [8]; title: ; notranslate">
	&lt;servlet&gt;
		&lt;servlet-name&gt;spring&lt;/servlet-name&gt;
		&lt;servlet-class&gt;
			org.springframework.web.servlet.DispatcherServlet
		&lt;/servlet-class&gt;
		&lt;init-param&gt;
			&lt;param-name&gt;contextConfigLocation&lt;/param-name&gt;
		        &lt;param-value&gt;/WEB-INF/bean.xml, /WEB-INF/bean-service.xml, /WEB-INF/bean-dao.xml&lt;/param-value&gt;
		&lt;/init-param&gt;
		&lt;load-on-startup&gt;1&lt;/load-on-startup&gt;
	&lt;/servlet&gt;
	&lt;servlet-mapping&gt;
		&lt;servlet-name&gt;spring&lt;/servlet-name&gt;
		&lt;url-pattern&gt;*.html&lt;/url-pattern&gt;
	&lt;/servlet-mapping&gt;
</pre><p>I hope this is useful <img src='http://viralpatel.net/blogs/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /></p><div id="relatedpost"><h2  class="related_post_title">Related Posts</h2><ul class="related_post"><li><a href="http://viralpatel.net/blogs/2011/01/tutorial-save-get-blob-object-spring-3-mvc-hibernate.html" title="Tutorial:Saving/Retreving BLOB object in Spring 3 MVC and Hibernate">Tutorial:Saving/Retreving BLOB object in Spring 3 MVC and Hibernate</a></li><li><a href="http://viralpatel.net/blogs/2010/11/spring3-mvc-hibernate-maven-tutorial-eclipse-example.html" title="Tutorial:Create Spring 3 MVC Hibernate 3 Example using Maven in Eclipse">Tutorial:Create Spring 3 MVC Hibernate 3 Example using Maven in Eclipse</a></li><li><a href="http://viralpatel.net/blogs/2010/10/spring-3-mvc-themes-tutorial-example.html" title="Spring 3 MVC: Themes in Spring-Tutorial with Example">Spring 3 MVC: Themes in Spring-Tutorial with Example</a></li><li><a href="http://viralpatel.net/blogs/2010/07/spring-3-mvc-internationalization-i18n-localization-tutorial-example.html" title="Spring 3 MVC: Internationalization &#038; Localization Tutorial with Example">Spring 3 MVC: Internationalization &#038; Localization Tutorial with Example</a></li><li><a href="http://viralpatel.net/blogs/2010/07/spring-3-mvc-tiles-plugin-tutorial-example-eclipse.html" title="Spring 3 MVC: Tiles Plugin Tutorial with Example in Eclipse">Spring 3 MVC: Tiles Plugin Tutorial with Example in Eclipse</a></li><li><a href="http://viralpatel.net/blogs/2010/07/spring-3-mvc-handling-forms.html" title="Spring 3 MVC: Handling Forms in Spring 3.0 MVC">Spring 3 MVC: Handling Forms in Spring 3.0 MVC</a></li><li><a href="http://viralpatel.net/blogs/2010/06/spring-3-mvc-create-hello-world-application-spring-3-mvc.html" title="Spring 3 MVC: Create Hello World application in Spring 3.0 MVC">Spring 3 MVC: Create Hello World application in Spring 3.0 MVC</a></li></ul></div>]]></content:encoded> <wfw:commentRss>http://viralpatel.net/blogs/2205/change-spring-servlet-filename-configuration/feed</wfw:commentRss> <slash:comments>2</slash:comments> </item> <item><title>Introducing Cache support in Spring 3.1 M1</title><link>http://viralpatel.net/blogs/2011/02/cache-support-spring-3-1-m1.html</link> <comments>http://viralpatel.net/blogs/2011/02/cache-support-spring-3-1-m1.html#comments</comments> <pubDate>Fri, 25 Feb 2011 09:35:05 +0000</pubDate> <dc:creator>Viral Patel</dc:creator> <category><![CDATA[Spring]]></category> <category><![CDATA[spring-3-mvc-series]]></category><guid isPermaLink="false">http://viralpatel.net/blogs/?p=2165</guid> <description><![CDATA[Spring 3.1 M1 is out with some very useful features. One of the coolest feature in the latest release is comprehensive Caching support! Spring Framework provides support for transparently adding caching into an existing Spring application. Similar to the transaction support, the caching abstraction allows consistent use of various caching solutions with minimal impact on [...]]]></description> <content:encoded><![CDATA[<p><img src="http://img.viralpatel.net/2011/02/spring-logo.png" alt="spring-logo" title="spring-logo" width="258" height="151" class="alignright size-full wp-image-2166" />Spring 3.1 M1 is out with some very <a href="http://blog.springsource.com/2011/02/11/spring-framework-3-1-m1-released/" rel="nofollow">useful features</a>. One of the coolest feature in the latest release is comprehensive Caching support!</p><p>Spring Framework provides support for transparently adding caching into an existing Spring application. Similar to the transaction support, the caching abstraction allows consistent use of various caching solutions with minimal impact on the code.</p><p>The cache is applied to Java methods, reducing the number of executions based on the information available. Spring checks if the given method is already executed for given set of parameters. If the method is already executed, Spring uses the cache value and returns it to caller instead of calling the method again. This is a write through cache. This way, expensive methods (whether CPU or IO bound) can be executed only once for a given set of parameters and the result reused without having to actually execute the method again. The caching logic is applied transparently without any interference to the invoker.</p><h2>Adding Cache support to Spring project</h2><p>In order to add Cache support to any Spring based project, one needs to declare the configuration using new Spring tag in the schema declaration.</p><pre class="brush: xml; title: ; notranslate">
&lt;beans xmlns=&quot;http://www.springframework.org/schema/beans&quot; xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
  xmlns:cache=&quot;http://www.springframework.org/schema/cache&quot;
   xsi:schemaLocation=&quot;http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd&quot;&gt;

  &lt;cache:annotation-driven /&gt;
  ...
&lt;/beans&gt;
</pre><p>Note the <code>cache:annotation-driven</code> tag in above declaration enables the caching in given Spring project.</p><h2>Using @Cacheable and @CacheEvict annotations</h2><p>Spring 3.1 M1 provides two very useful Java annotations: <code>@Cacheable</code> and <code>@CacheEvict</code> which allow methods to trigger cache population or cache eviction. Let us take a closer look at each annotation:</p><h3>@Cacheable annotation</h3><p>This annotation mark a method cacheable. Thus the result from this method call will be stored into the cache on subsequent invocations with same arguments.</p><pre class="brush: java; title: ; notranslate">
@Cacheable(&quot;persons&quot;)
public Person profile(Long personId) { ... }
</pre><p>In the above code snippet, method <code>profile</code> is marked cacheable using <code>@Cacheable</code> annotation. Also the method is associated with a cache named &#8220;<code>persons</code>&#8220;. Whenever method profile is called, the Spring framework will check if cached entry is available in persons cache and returns the same without calling profile method.</p><p>It is also possible to provide multiple cache names if you have multiple caches declared in your application. For example:</p><pre class="brush: java; title: ; notranslate">
@Cacheable({&quot;persons&quot;, &quot;profiles&quot;})
public Person profile(Long personId) { ... }
</pre><p>In above code snippet, we provide two cache names persons and profiles. Spring framework will check in all the caches if entry is available for given method call with argument personId, if at least one cache is hit, then the associated value will be returned.</p><h3>@CacheEvict annotation</h3><p>Cache eviction is removing of any unused or stale data from the cache. Opposed to @Cacheable, annotation @CacheEvict demarcates methods that perform cache eviction, that is methods that act as triggers for removing data from the cache. Just like its sibling, @CacheEvict requires one to specify one (or multiple) caches that are affected by the action, allows a key or a condition to be specified but in addition, features an extra parameter <code>allEntries</code> which indicates whether a cache-wide eviction needs to be performed rather then just an entry one (based on the key):</p><pre class="brush: java; title: ; notranslate">
@CacheEvict (value = &quot;persons&quot;, allEntries=true)
public List&lt;Person&gt; listPersons()
</pre><p>This annotation is very useful when an entire cache region needs to be cleared out. The Spring framework will ignore any key specified in this scenario as it does not apply.</p><h3>Using Default key</h3><p>The cache is nothing but a key-value store which stores the data based on certain key. In Spring framework based caching, the method arguments of cached method acts as the source of Key generation. Every key is essentially the Hash-code of these arguments. This approach works well for objects with natural keys as long as the <code>hashCode()</code> reflects that. If that is not the case then for distributed or persistent environments, the strategy needs to be changed as the objects <code>hashCode</code> is not preserved. In fact, depending on the JVM implementation or running conditions, the same <code>hashCode</code> can be reused for different objects, in the same VM instance.</p><p>To provide a different default key generator, one needs to implement the <code>org.springframework.cache.KeyGenerator</code> interface. Once configured, the generator will be used for each declaration that does not specify its own key generation strategy.</p><p>By default, all the method arguments are used in Key generation logic. In practice not all methods have only one argument or, worse yet, the parameters are not suitable as cache keys – take for example a variation of the method above:</p><pre class="brush: java; title: ; notranslate">
@Cacheable(value=&quot;persons&quot;, key=&quot;personId&quot;)
public Person profile(Long personId, Long groundId) { ... }
</pre><p>Here we are using just <code>personId</code> in key generation ignoring groupId altogether.</p><h3>Understand Conditional caching</h3><p>Spring framework also supports conditional caching letting user to cache certain methods based on some conditions. For example, in following code snippet we cache profiles only for those users who have profileId greater than 50:</p><pre class="brush: java; title: ; notranslate">
@Cacheable(value=&quot;persons&quot;, condition=&quot;personId &gt; 50&quot;)
public Person profile(Long personId) { ... }
</pre><h2>Currently supported libraries</h2><p>There are probably hundreds of cache libraries available which can be used in your JEE project. For now the Spring framework supports following implementations:</p><ol><li>JDK ConcurrentMap based Cache</li><li>Ehcache based Cache</li></ol><h3>JDK ConcurrentMap based Cache</h3><p>The JDK-based Cache implementation resides under <code>org.springframework.cache.concurrent</code> package. It allows one to use <code>ConcurrentHashMap</code> as a backing Cache store.</p><pre class="brush: xml; title: ; notranslate">
&lt;!-- generic cache manager --&gt;
&lt;bean id=&quot;cacheManager&quot; class=&quot;org.springframework.cache.support.SimpleCacheManager&quot;&gt;
  &lt;property name=&quot;caches&quot;&gt;
    &lt;set&gt;
      &lt;bean class=&quot;org.springframework.cache.concurrent.ConcurrentCacheFactoryBean&quot; p:name=&quot;default&quot;/&gt;
      &lt;bean class=&quot;org.springframework.cache.concurrent.ConcurrentCacheFactoryBean&quot; p:name=&quot;persons&quot;/&gt;
    &lt;/set&gt;
  &lt;/property&gt;
&lt;/bean&gt;</pre><p>In above code snippet, we use <code>SimpleCacheManager</code> class to create a <code>CacheManager</code>. Note that we have created two caches in our application, one is <code>default</code> and second is <code>persons</code>.</p><h3>Ehcache based Cache</h3><p>The Ehcache implementation is located under <code>org.springframework.cache.ehcache</code> package. Again, to use it, one simply needs to declare the appropriate <code>CacheManager</code>:</p><pre class="brush: xml; title: ; notranslate">
&lt;bean id=&quot;cacheManager&quot; class=&quot;org.springframework.cache.ehcache.EhcacheCacheManager&quot; p:cache-manager=&quot;ehcache&quot;/&gt;

&lt;!-- Ehcache library setup --&gt;
&lt;bean id=&quot;ehcache&quot; class=&quot;org.springframework.cache.ehcache.EhCacheManagerFactoryBean&quot; p:config-location=&quot;ehcache.xml&quot;/&gt;
</pre><p>This setup bootstraps ehcache library inside Spring IoC (through bean ehcache) which is then wired into the dedicated CacheManager implementation. Note the entire ehcache-specific configuration is read from the resource ehcache.xml.</p><h2>References</h2><ul><li><a rel="nofollow" target="_new" href="http://blog.springsource.com/2011/02/11/spring-framework-3-1-m1-released/">Spring framework 3.1 M1 release</a></li><li><a rel="nofollow" target="_new" href="http://static.springsource.org/spring/docs/3.1.0.M1/spring-framework-reference/html/cache.html">Spring Cache documentation</a></li></ul><div id="relatedpost"><h2  class="related_post_title">Related Posts</h2><ul class="related_post"><li><a href="http://viralpatel.net/blogs/2010/11/spring3-mvc-hibernate-maven-tutorial-eclipse-example.html" title="Tutorial:Create Spring 3 MVC Hibernate 3 Example using Maven in Eclipse">Tutorial:Create Spring 3 MVC Hibernate 3 Example using Maven in Eclipse</a></li><li><a href="http://viralpatel.net/blogs/2010/10/spring-3-mvc-themes-tutorial-example.html" title="Spring 3 MVC: Themes in Spring-Tutorial with Example">Spring 3 MVC: Themes in Spring-Tutorial with Example</a></li><li><a href="http://viralpatel.net/blogs/2010/07/spring-3-mvc-internationalization-i18n-localization-tutorial-example.html" title="Spring 3 MVC: Internationalization &#038; Localization Tutorial with Example">Spring 3 MVC: Internationalization &#038; Localization Tutorial with Example</a></li><li><a href="http://viralpatel.net/blogs/2010/07/spring-3-mvc-tiles-plugin-tutorial-example-eclipse.html" title="Spring 3 MVC: Tiles Plugin Tutorial with Example in Eclipse">Spring 3 MVC: Tiles Plugin Tutorial with Example in Eclipse</a></li><li><a href="http://viralpatel.net/blogs/2010/07/spring-3-mvc-handling-forms.html" title="Spring 3 MVC: Handling Forms in Spring 3.0 MVC">Spring 3 MVC: Handling Forms in Spring 3.0 MVC</a></li><li><a href="http://viralpatel.net/blogs/2010/06/spring-3-mvc-create-hello-world-application-spring-3-mvc.html" title="Spring 3 MVC: Create Hello World application in Spring 3.0 MVC">Spring 3 MVC: Create Hello World application in Spring 3.0 MVC</a></li><li><a href="http://viralpatel.net/blogs/2010/06/tutorial-spring-3-mvc-introduction-spring-mvc-framework.html" title="Spring 3 MVC – Introduction to Spring 3 MVC Framework">Spring 3 MVC – Introduction to Spring 3 MVC Framework</a></li></ul></div>]]></content:encoded> <wfw:commentRss>http://viralpatel.net/blogs/2011/02/cache-support-spring-3-1-m1.html/feed</wfw:commentRss> <slash:comments>2</slash:comments> </item> <item><title>Spring Roo: Customizing Web MVC UI Forms</title><link>http://viralpatel.net/blogs/2011/02/spring-roo-customizing-web-mvc-ui-forms.html</link> <comments>http://viralpatel.net/blogs/2011/02/spring-roo-customizing-web-mvc-ui-forms.html#comments</comments> <pubDate>Mon, 07 Feb 2011 11:51:17 +0000</pubDate> <dc:creator>Jose Delgado</dc:creator> <category><![CDATA[Spring]]></category> <category><![CDATA[Spring Roo]]></category> <category><![CDATA[html form]]></category> <category><![CDATA[spring-roo]]></category><guid isPermaLink="false">http://viralpatel.net/blogs/?p=2154</guid> <description><![CDATA[There are many features that I like from Spring Roo: The shell is very effective for constructing projects -with a helpful tab completion- Round-trip is essential to keep the code in sync Code generation without &#8220;unnecessary abstractions&#8221; is refreshing -although version 1.1.2 might bring some of them back- just to mention a few. At the [...]]]></description> <content:encoded><![CDATA[<p>There are many features that I like from Spring Roo:</p><ul><li>The shell is  very effective  for constructing projects -with a helpful tab completion-</li><li>Round-trip is essential to keep the code in sync</li><li>Code generation without  &#8220;unnecessary abstractions&#8221; is refreshing -although version 1.1.2 might bring some of them back-  just to  mention a few.</li></ul><p>At the top of  the list,  I am  placing,  what I consider  the jewel-of-the-crown:  The Tagx library for JSP(x) views. The article assumes some familiarity with Spring Roo. For more information on Spring Roo visit its website at <a rel="nofollow" target="_new" href="http://www.springsource.org/roo">http://www.springsource.org/roo</a>.</p><h2>Tagx Library in a Nutshell</h2><p>The tagx library is installed by the Web  MVC add-on. Spring Roo scaffolds controllers and views from  entities classes.  Views are created with components from the tagx library. Please read reference document at <a rel="nofollow" target="_new" href="http://static.springsource.org/spring-roo/reference/html/base-web.html">http://static.springsource.org/spring-roo/reference/html/base-web.html</a> for a complete description.</p><h2>Without further ado. Straight to business.</h2><p>This article refers to forms implemented in World Almanac by jD  website. World Almanac is a member  of a group of  web apps created  to experiment with Spring Roo development. The link of the showcases website is at <a rel="nofollow" target="_new" href="https://pragmatikroo.org/showcases">https://pragmatikroo.org/showcases</a>. The purpose is to implement   typical web development requirements beyond the CRUD scope.</p><p>This is the problem to work on: I need  to customize a  list.tagx  component to render country flag images. Typically this component renders  strings and numbers inside a grid. The form will be paginated for easy navigation, as shown in the image below.  This functionality  provides a  World Almanac galleria view  Additionally, I want to attach  a click event for navigating to a country detail  page.</p><p>The form provides two select controls for enabling counties filtering.  The form is paginated and navigated the same way a typical list.jspx form is.  Typically Roo select buttons are associated with an action button. In this case,  I remove them and the filtering action is triggered by a choice select. I didn&#8217;t have to start from scratch. I just tweaked Roo generated source code. Roo is great!.</p><div id="attachment_2155" class="wp-caption aligncenter" style="width: 477px"><img src="http://img.viralpatel.net/2011/02/spring-roo-paginated-contries-form.png" alt="spring-roo-paginated-contries-form" title="spring-roo-paginated-contries-form" width="467" height="372" class="size-full wp-image-2155" /><p class="wp-caption-text">Paginated Gallery Form</p></div><p>Below is the source code that renders the flag country gallery view. There is a lot of customization here. However you can still see  the  skeleton of  the original scaffold form created by Roo.</p><p><strong>Paginated Gallery  JSPx code</strong></p><pre class="brush: xml; title: ; notranslate">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;
&lt;div xmlns:jsp=&quot;http://java.sun.com/JSP/Page&quot;
	xmlns:page=&quot;urn:jsptagdir:/WEB-INF/tags/form&quot;
	xmlns:table=&quot;urn:jsptagdir:/WEB-INF/tags/form/fields&quot; version=&quot;2.0&quot;
	xmlns:field=&quot;urn:jsptagdir:/WEB-INF/tags/form/fields&quot;
	xmlns:form=&quot;urn:jsptagdir:/WEB-INF/tags/form&quot;
	xmlns:fn=&quot;http://java.sun.com/jsp/jstl/functions&quot;&gt;

&lt;script type=&quot;text/javascript&quot;&gt;
    &lt;![CDATA[

       function selectIt( aName ){
    	   var selectContinentPage=&quot;/worldAlmanac/countrys&quot;;
    	   document.body.innerHTML = '&lt;form id=&quot;dynForm&quot; action='+
    	                                 selectContinentPage+
    	                                 '  method=&quot;get&quot;&gt;'+
    	                                 '&lt;input type=&quot;hidden&quot; name=&quot;find&quot; value=&quot;gallery&quot; /&gt;'+
    	                                 '&lt;input type=&quot;hidden&quot; name=&quot;\page&quot; value=&quot;1&quot; /&gt;'+
    	                                 '&lt;input type=&quot;hidden&quot; name=&quot;\size&quot; value=&quot;50&quot; /&gt;'+
    	                                 '&lt;input type=&quot;hidden&quot; name=&quot;'+aName.name+'&quot; value=&quot;'+aName.value+'&quot; /&gt;'+
    	                               '&lt;/form&gt;';
           document.getElementById(&quot;dynForm&quot;).submit();
        }
        ]]&gt;
    &lt;/script&gt;

&lt;jsp:output omit-xml-declaration=&quot;yes&quot; /&gt;
 &lt;div id=&quot;wrapperTop&quot;&gt;
                  &lt;input name=&quot;btnBack&quot; title=&quot;Previous Page&quot;
                    onMouseOver=&quot;window.status='Previous Page'; return true&quot;
                    onMouseOut=&quot;window.status=''; return true&quot;
                    onclick=&quot;location.href = '/worldAlmanac'&quot;
                    type=&quot;button&quot; value=&quot;Previous Page&quot;/&gt;
  &lt;/div&gt;

	&lt;page:list id=&quot;pl:org.josean.rooworld.domain.Country&quot;
	           items=&quot;${countrys}&quot;&gt;
	&lt;div&gt;
		&lt;div style=&quot;float: left; width: 60%;&quot;&gt;

		      &lt;field:select     disableFormBinding=&quot;true&quot;
				              id=&quot;f:org.josean.rooworld.domain.Country.continent&quot;
				              items=&quot;${continent}&quot;
				              field=&quot;continent&quot;
				              path=&quot;/countrys&quot;
				              onchange=&quot;selectIt(this);&quot;/&gt;

		&lt;/div&gt;
		&lt;div&gt;
			&lt;field:select disableFormBinding=&quot;true&quot;
				         id=&quot;f:org.josean.rooworld.domain.Country.region&quot;
				         items=&quot;${region}&quot;
				         field=&quot;region&quot;
				         path=&quot;/countrys&quot;
				         onchange=&quot;selectIt(this);&quot; /&gt;
		 &lt;/div&gt;
	&lt;/div&gt;

	&lt;table:gallery data=&quot;${countrys}&quot;
		id=&quot;l:org.josean.rooworld.domain.Country&quot; path=&quot;/countrys&quot;
        title=&quot;Click on image to select country info&quot; page=&quot;${page}&quot; size=&quot;${size}&quot;
		typeIdFieldName=&quot;code&quot; pageid=&quot;page&quot; sizeid=&quot;size&quot; delete=&quot;false&quot;
		update=&quot;false&quot; create=&quot;false&quot; select=&quot;false&quot; show=&quot;false&quot;
		anchorURL=&quot;/countrys?find=gallery&quot;&gt;
		&lt;table:column id=&quot;c:org.josean.rooworld.domain.Country.code&quot;
			type=&quot;img&quot; property=&quot;code&quot;  /&gt;

	&lt;/table:gallery&gt;

&lt;/page:list&gt;

&lt;script type=&quot;text/javascript&quot;&gt;
    &lt;![CDATA[

             function applyStateControl(aControl, anItem){

                var option = aControl.getElementsByClassName(&quot;HTMLOptionElement&quot;);
                for( i=0; i&lt;aControl.options.length;i++){
                     if(aControl.options.item(i).value==anItem)
                         break;
                    }
                aControl.options.item(i).defaultSelected=true;
             }
             var selectedItem= window.location.search;
             var cIndex = selectedItem.indexOf(&quot;continent&quot;);
             var rIndex = selectedItem.indexOf(&quot;region&quot;);
             if(cIndex&gt;-1){
                 var continent= selectedItem.substring( cIndex+10, selectedItem.length);
                 var control = document.getElementById(&quot;_continent_id&quot;);
                 applyStateControl(control, continent);

             }
             else if (rIndex&gt;-1){
            	  var region= selectedItem.substring( rIndex+7, selectedItem.length);
                  var control = document.getElementById(&quot;_region_id&quot;);
                  applyStateControl(control, region);
             }

     ]]&gt;
    &lt;/script&gt;
&lt;/div&gt;
</pre><p>Next,  I show the country detail form navigated after clicking its flag. WorldAlmanac integrates easily Google Maps as well.   It  renders the country map using its latitude/longitude stored in the database.   All elements together create a nice composition.!</p><div id="attachment_2156" class="wp-caption aligncenter" style="width: 543px"><img src="http://img.viralpatel.net/2011/02/spring-roo-detailed-country-form.png" alt="spring-roo-detailed-country-form" title="spring-roo-detailed-country-form" width="533" height="391" class="size-full wp-image-2156" /><p class="wp-caption-text">Detailed Country Form</p></div><p><strong>Detailed  Country JSPx code</strong></p><pre class="brush: xml; title: ; notranslate">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;
&lt;div
 xmlns:field=&quot;urn:jsptagdir:/WEB-INF/tags/form/fields&quot;
 xmlns:jsp=&quot;http://java.sun.com/JSP/Page&quot;
 xmlns:page=&quot;urn:jsptagdir:/WEB-INF/tags/form&quot;
 version=&quot;2.0&quot;
 xmlns:spring=&quot;http://www.springframework.org/tags&quot;
 xmlns:c=&quot;http://java.sun.com/jsp/jstl/core&quot;&gt;
  &lt;jsp:output omit-xml-declaration=&quot;yes&quot; /&gt;

  &lt;spring:url
   value=&quot;http://maps.google.com/maps/api/js?sensor=false&quot;
   var=&quot;google_map_url&quot; /&gt;

  &lt;spring:url
   value=&quot;/static/js/googleMap.js&quot;
   var=&quot;tmp_map_url&quot; /&gt;

  &lt;c:set
   var=&quot;map_url&quot;
   value=&quot;uri:/${tmp_map_url}&quot; /&gt;

&lt;script
 type=&quot;text/javascript&quot;
 src=&quot;${google_map_url}&quot;&gt;
&lt;/script&gt;

&lt;script
 src=&quot;${tmp_map_url}&quot;
 type=&quot;text/javascript&quot;&gt;
&lt;/script&gt;

  &lt;page:show
   id=&quot;ps:org.josean.rooworld.domain.Country&quot;
   object=&quot;${country}&quot;
   z=&quot;3tU6/DN2doNWT+sTLgEAZR7U8hk=&quot;&gt;
    &lt;table
     width=&quot;100%;&quot;&gt;
      &lt;tr&gt;
        &lt;td
         width=&quot;50%&quot;&gt;
          &lt;field:display
           field=&quot;code&quot;
           id=&quot;s:org.josean.rooworld.domain.Country.code&quot;
           object=&quot;${country}&quot;
           type=&quot;img&quot;
           z=&quot;?&quot;
           label=&quot;Flag&quot; /&gt;
          &lt;field:display
           field=&quot;name&quot;
           id=&quot;s:org.josean.rooworld.domain.Country.name&quot;
           object=&quot;${country}&quot;
           z=&quot;FAyyuD7aX42uNNgL4e7tS//taRI=&quot; /&gt;
          &lt;field:display
           field=&quot;continent&quot;
           id=&quot;s:org.josean.rooworld.domain.Country.continent&quot;
           object=&quot;${country}&quot;
           z=&quot;fSpvsKUctolI0akJTZzYHoOwueo=&quot; /&gt;
          &lt;field:display
           field=&quot;region&quot;
           id=&quot;s:org.josean.rooworld.domain.Country.region&quot;
           object=&quot;${country}&quot;
           z=&quot;z7xfg8bZs8LFPftHWVjP45HdpGI=&quot; /&gt;
          &lt;field:display
           field=&quot;surfaceArea&quot;
           id=&quot;s:org.josean.rooworld.domain.Country.surfaceArea&quot;
           object=&quot;${country}&quot;
           z=&quot;7C7ri5E3jCruBij5X5iEJqh4g1k=&quot; /&gt;
          &lt;field:display
           field=&quot;indepYear&quot;
           id=&quot;s:org.josean.rooworld.domain.Country.indepYear&quot;
           object=&quot;${country}&quot;
           z=&quot;EZL1ubZ/J9SiMbCUfokjr1OoDKA=&quot; /&gt;

          &lt;field:display
           field=&quot;population&quot;
           id=&quot;s:org.josean.rooworld.domain.Country.population&quot;
           object=&quot;${country}&quot;
           z=&quot;kqB3gvDWozV4lRD2m/S/6tpw2rE=&quot; /&gt;
          &lt;field:display
           field=&quot;lifeExpectancy&quot;
           id=&quot;s:org.josean.rooworld.domain.Country.lifeExpectancy&quot;
           object=&quot;${country}&quot;
           z=&quot;6Sj9b9rtuCZd1V5oNnz7gmAaQkI=&quot; /&gt;
          &lt;field:display
           field=&quot;gnp&quot;
           id=&quot;s:org.josean.rooworld.domain.Country.gnp&quot;
           object=&quot;${country}&quot;
           z=&quot;cQC9QwBNccJoYP9+xn4nAakFVVk=&quot; /&gt;
          &lt;field:display
           field=&quot;gnpold&quot;
           id=&quot;s:org.josean.rooworld.domain.Country.gnpold&quot;
           object=&quot;${country}&quot;
           z=&quot;AKqXyf8qWGWBU0HwUSIvnnLzZeE=&quot; /&gt;
          &lt;field:display
           field=&quot;localName&quot;
           id=&quot;s:org.josean.rooworld.domain.Country.localName&quot;
           object=&quot;${country}&quot;
           z=&quot;jYwa2XCaRe58W9ae45HLAaLlt7A=&quot; /&gt;
          &lt;field:display
           field=&quot;govermentForm&quot;
           id=&quot;s:org.josean.rooworld.domain.Country.govermentForm&quot;
           object=&quot;${country}&quot;
           z=&quot;N9WckigFkEM6lBgGaHR3QG13Lq4=&quot; /&gt;
          &lt;field:display
           field=&quot;capital&quot;
           id=&quot;s:org.josean.rooworld.domain.Country.capital&quot;
           object=&quot;${country}&quot;
           z=&quot;JRQSSvwHoOt1d2yff5JeK7NDn0k=&quot; /&gt;
          &lt;field:display
           field=&quot;code2&quot;
           id=&quot;s:org.josean.rooworld.domain.Country.code2&quot;
           object=&quot;${country}&quot;
           z=&quot;gIR7Z72tUJCdEBJHExd4FLG1ze0=&quot; /&gt;
          &lt;field:display
           field=&quot;headofState&quot;
           id=&quot;s:org.josean.rooworld.domain.Country.headofState&quot;
           object=&quot;${country}&quot;
           z=&quot;EmNqI9StH4djy7tAZsVKe3+VJ+A=&quot; /&gt;
          &lt;field:display
           field=&quot;latitude&quot;
           id=&quot;s:org.josean.rooworld.domain.Country.latitude&quot;
           object=&quot;${country}&quot;
           z=&quot;?&quot; /&gt;
          &lt;field:display
           field=&quot;longitude&quot;
           id=&quot;s:org.josean.rooworld.domain.Country.longitude&quot;
           object=&quot;${country}&quot;
           z=&quot;?&quot; /&gt;
          &lt;page:find
           reportParam=&quot;${country.code}&quot;
           path=&quot;/pdf/countryReport&quot;
           id=&quot;c:report&quot;
           buttonLabel=&quot;Pdf Report&quot; /&gt;
        &lt;/td&gt;
        &lt;td&gt;
          &lt;div
           id=&quot;map_canvas&quot;
           style=&quot;width: 400px; height: 550px;&quot;&gt;
            &lt;button
             onclick=&quot;initialize();&quot;&gt;Show Map&lt;/button&gt;
          &lt;/div&gt;
        &lt;/td&gt;
      &lt;/tr&gt;
    &lt;/table&gt;
  &lt;/page:show&gt;
&lt;/div&gt;
</pre><p>That is it!</p><h2>Conclusion</h2><p>This article has shown a customization example  using code originally started  from the scaffold one created by the  Spring Roo Web MVC add-on.  I found the Jspx notation very expressive and intuitive. The tagx library is ample and  easily to extend if needed.   Jspx are XML documents, consequently they are validated against  wellness.  I have to say that this annoyed me in the beginning but after a short time, I got used to and started to like it. Not to mention the benefits of having forms error checking.</p><p>Spring Roo Web MVC views  are simpler and less interactive their contra-parts  based heavily in Javascript and Ajax.  However,  I believe they are very useful  in a variety of Web Development projects and plenty of market for them.  As the Reader can see, the look and feel of  a Roo created app can totally be change to meet any UI/Web design requirement.  This code example was create Spring Roo 1.1.0.M1.</p><div id="relatedpost"><h2  class="related_post_title">Related Posts</h2><ul class="related_post"><li><a href="http://viralpatel.net/blogs/2011/02/spring-roo-save-read-blob-object-spring-roo-tutorial.html" title="Spring Roo: Saving/Retreving BLOB object in Spring Roo">Spring Roo: Saving/Retreving BLOB object in Spring Roo</a></li><li><a href="http://viralpatel.net/blogs/2011/01/spring-roo-implement-masterdetail-forms.html" title="How to implement Master/Detail forms using Spring Roo">How to implement Master/Detail forms using Spring Roo</a></li><li><a href="http://viralpatel.net/blogs/2205/change-spring-servlet-filename-configuration" title="Change spring-servlet.xml Filename (Spring Web Contenxt Configuration Filename)">Change spring-servlet.xml Filename (Spring Web Contenxt Configuration Filename)</a></li><li><a href="http://viralpatel.net/blogs/2011/02/cache-support-spring-3-1-m1.html" title="Introducing Cache support in Spring 3.1 M1">Introducing Cache support in Spring 3.1 M1</a></li><li><a href="http://viralpatel.net/blogs/2011/01/spring-roo-two-database-configuration.html" title="Spring Roo: Two Databases Configuration">Spring Roo: Two Databases Configuration</a></li><li><a href="http://viralpatel.net/blogs/2011/01/tutorial-save-get-blob-object-spring-3-mvc-hibernate.html" title="Tutorial:Saving/Retreving BLOB object in Spring 3 MVC and Hibernate">Tutorial:Saving/Retreving BLOB object in Spring 3 MVC and Hibernate</a></li><li><a href="http://viralpatel.net/blogs/2010/11/spring3-mvc-hibernate-maven-tutorial-eclipse-example.html" title="Tutorial:Create Spring 3 MVC Hibernate 3 Example using Maven in Eclipse">Tutorial:Create Spring 3 MVC Hibernate 3 Example using Maven in Eclipse</a></li></ul></div>]]></content:encoded> <wfw:commentRss>http://viralpatel.net/blogs/2011/02/spring-roo-customizing-web-mvc-ui-forms.html/feed</wfw:commentRss> <slash:comments>14</slash:comments> </item> <item><title>Spring Roo: Saving/Retreving BLOB object in Spring Roo</title><link>http://viralpatel.net/blogs/2011/02/spring-roo-save-read-blob-object-spring-roo-tutorial.html</link> <comments>http://viralpatel.net/blogs/2011/02/spring-roo-save-read-blob-object-spring-roo-tutorial.html#comments</comments> <pubDate>Tue, 01 Feb 2011 10:13:33 +0000</pubDate> <dc:creator>Jose Delgado</dc:creator> <category><![CDATA[Java]]></category> <category><![CDATA[Spring]]></category> <category><![CDATA[Spring Roo]]></category> <category><![CDATA[blob]]></category> <category><![CDATA[spring-roo]]></category><guid isPermaLink="false">http://viralpatel.net/blogs/?p=2148</guid> <description><![CDATA[After reading the excellent article titled Saving/Retreving BLOB object in Spring MVC/Hibernate immediately came to my mind: How would it be the process of recreating the same example but using Spring Roo. What would it be the similarities/differences in the projects source code. The article assumes the Reader is a Developer with some familiarity with [...]]]></description> <content:encoded><![CDATA[<p>After reading the excellent article titled <a href="http://viralpatel.net/blogs/2011/01/tutorial-save-get-blob-object-spring-3-mvc-hibernate.html">Saving/Retreving BLOB object in Spring MVC/Hibernate</a> immediately came to my mind:</p><ol><li>How would it be  the process of recreating the same example but using Spring Roo.</li><li>What would it be the similarities/differences in the projects source code.</li></ol><p>The article  assumes  the Reader is a Developer with some familiarity with Spring Roo. For introductory information about Spring Roo vist <a rel="nofollow" target="_new" href="http://www.ibm.com/developerworks/java/library/os-springroo1/index.html?ca=drs-">http://www.ibm.com/developerworks/java/library/os-springroo1/index.html?ca=drs-</a>.</p><h2>Project setup</h2><p>Spring Roo brings alternatives for setting up a project: a) Entering project using  a script file or b) Creating the database first and reverse engineering it using Roo DBRE commands.</p><p>For this article I am using option a), via an script file.  Option b) is specially convenient for projects with an database already in place.  I&#8217;ll vist Roo DBRE in a coming article in the near future.</p><p><em>Script File</em></p><pre class="brush: xml; title: ; notranslate">
project --topLevelPackage org.pragmatikroo.roodocman
persistence setup --provider HIBERNATE --database MYSQL --databaseName roodocman --userName &amp;lt;username&amp;gt; --password &amp;lt;password&amp;gt;
entity		--class ~.domain.Document
field string 	--fieldName name 		--notNull --sizeMax 30
field string 	--fieldName description 	--sizeMax 500
field string 	--fieldName filename 		--notNull
//field blob 	--fieldName content		--notNull //Type not supported by Roo
field string 	--fieldName contentType 	--notNull
field numbert	--fieldName size -
controller all 	--package ~.web
perform clean
perform eclipse
</pre><p>Notice <code>content</code> field  is of  type blob. This field would have to be entered manually into the entity class. You can use the IDE of  your choice. I use STS. Either you use STS or the native Roo shell, the project would need to be synced by Roo after the change. More on this later.</p><h2>Generate Entity Class</h2><pre class="brush: java; title: ; notranslate">
package org.pragmatikroo.roodocman;

@RooJavaBean
@RooToString
@RooEntity
public class Document {

    @NotNull
    @Size(max = 30)
    private java.lang.String name;

    @NotNull
    @Size(max = 500)
    private java.lang.String description;

    private java.lang.String filename;

    @NotNull
    @Lob
    @Basic(fetch = FetchType.LAZY)
    private byte[] content;

    private java.lang.String contentType;

    private java.lang.Long size;

    @Transient
    @Size(max = 100)
    private String url ;
}
</pre><p>Please review the seminal article for more information about the example entity fields.  All highlighted code is manually added to the original file created by Roo. Why I added field size and url  directly into the entity class?. I could have entered referred fields using the shell too. Right?.  I did it  in purpose to mentioned that Spring Roo is a <u>round-trip tool</u>.  There are two more fields not shown in the entity class. They are the  id and version fields,  Roo automatically handle them using an ITD. Details about round-trip capabilities and how Roo uses ITDs, please visit Spring Roo website at http://www.springsource.org/roo.  One more thing about the blob field. DBMS have different type of  blobs. Verify that your project database is using the right one for your purposes.</p><p>As mention before: always make sure that Roo synced  your latest changes. That would save you a lot of confusion.</p><p>It  is a good time to deploy the application and verify that everything is working find to this point.</p><h2>Required Source code changes</h2><p>Well, to this point Spring Roo has done a lot for us. Properly setup the project. Created a Maven pom.xml with all required dependencies -well, almost; more on this below-.  Generate all the code necessary for having a working web app. If this not enough, Roo is there in the background monitoring the project against any possible change.</p><p>With exception of  the  blob field -content- all the other fields are ready to go. Roo took care of them. In order to save/retrieve data from the blob field, we need to modify code in the client and in the server side  for  allowing  file uploads.</p><h2>Server Side Changes</h2><p>Basically we need code that allows us to save/retrieve documents that include a blob field. The documents are entered using a web form. Typically Roo by default, generates client and server side code for having CRUD operations for every entity. I am not allowing updates in this version of  the application. So, I disabled it, by setting the update=false in the <code>@RooWebScaffold</code> annotation. Please make sure next code is  included in the <code>DocumentController</code> project file.</p><pre class="brush: java; title: ; notranslate">
@RooWebScaffold(path = &amp;quot;documents&amp;quot;, formBackingObject = Document.class, update=false)
@InitBinder
protected void initBinder(HttpServletRequest request,
    				   ServletRequestDataBinder binder)
				   throws ServletException {
	binder.registerCustomEditor(byte[].class,   	newByteArrayMultipartFileEditor());
    }
@RequestMapping(value=&amp;quot;savedoc&amp;quot;,  method = RequestMethod.POST)
public String createdoc(@Valid Document document,
    				BindingResult result,
    				Model model,
    				@RequestParam(&amp;quot;content&amp;quot;) MultipartFile content,
    					 	HttpServletRequest request) {

    	document.setContentType(content.getContentType());
    	document.setFilename(content.getOriginalFilename());
    	document.setSize(content.getSize());

    	log.debug(&amp;quot;Document: &amp;quot;);
    	log.debug(&amp;quot;Name: &amp;quot;+content.getOriginalFilename());
    	log.debug(&amp;quot;Description: &amp;quot;+document.getDescription());
    	log.debug(&amp;quot;File: &amp;quot; +content.getName());
    	log.debug(&amp;quot;Type: &amp;quot;+content.getContentType());
    	log.debug(&amp;quot;Size: &amp;quot;+content.getSize());
        if (result.hasErrors()) {
            model.addAttribute(&amp;quot;document&amp;quot;, document);
            return &amp;quot;documents/create&amp;quot;;
        }
        document.persist();

        return &amp;quot;redirect:/documents?page=1&amp;amp;size=10&amp;quot; +   			encodeUrlPathSegment(document.getId().toString(), request);
    }

@RequestMapping(value = &amp;quot;/{id}&amp;quot;, method = RequestMethod.GET)
    public String show(@PathVariable(&amp;quot;id&amp;quot;) Long id, Model model) {
    	Document doc = Document.findDocument(id);
    	doc.setU(&amp;quot;/documents/showdoc/&amp;quot;+id);
        model.addAttribute(&amp;quot;document&amp;quot;, Document.findDocument(id));
        model.addAttribute(&amp;quot;itemId&amp;quot;, id);
        return &amp;quot;documents/show&amp;quot;;
    }

@RequestMapping(value = &amp;quot;/showdoc/{id}&amp;quot;, method = RequestMethod.GET)
public String showdoc(	@PathVariable(&amp;quot;id&amp;quot;) Long id,
    				HttpServletResponse response,
    				Model model) {
   Document doc = Document.findDocument(id);

   try {
          response.setHeader(&amp;quot;Content-Disposition&amp;quot;, &amp;quot;inline;filename=\&amp;quot;&amp;quot; +doc.getFilename()+ &amp;quot;\&amp;quot;&amp;quot;);

          OutputStream out = response.getOutputStream();
          response.setContentType(doc.getContentType());
          IOUtils.copy( new ByteArrayInputStream(doc.getContent()),out);
            out.flush();

        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
</pre><p>The code above allows CRUD operations with all the document fields including the blob. Very-very important: all this source code must be placed in the <code>DocumentControler.java</code> file to avoid been removed by Roo when the project is synced for changes.</p><h2>Client Side Changes</h2><p>On client side, I created a create custom form. Please replace the content of the create.jspx, with:</p><p><em>Create.jpsx Form</em></p><pre class="brush: xml; title: ; notranslate">
&amp;lt;form:multi id=&amp;quot;fc_org_pragmatikroo_roodocman_domain_Document&amp;quot; modelAttribute=&amp;quot;document&amp;quot; path=&amp;quot;/documents/savedoc&amp;quot; render=&amp;quot;${empty dependencies}&amp;quot; z=&amp;quot;O7jiRGyhKQOUnBT8yJ9W4XU6VrQ=&amp;quot;&amp;gt;
      &amp;lt;field:input field=&amp;quot;name&amp;quot; id=&amp;quot;c_org_pragmatikroo_roodocman_domain_Document_name&amp;quot; max=&amp;quot;30&amp;quot; required=&amp;quot;true&amp;quot; z=&amp;quot;K3YncHn7F+HtBX/zgCZMYM6VO7k=&amp;quot;/&amp;gt;
      &amp;lt;field:textarea field=&amp;quot;description&amp;quot; id=&amp;quot;c_org_pragmatikroo_roodocman_domain_Document_description&amp;quot; required=&amp;quot;true&amp;quot; z=&amp;quot;/RLpJWAf9zVjHtRapWIFve8JB8Y=&amp;quot;/&amp;gt;
      &amp;lt;field:input field=&amp;quot;filename&amp;quot; id=&amp;quot;c_org_pragmatikroo_roodocman_domain_Document_filename&amp;quot; render=&amp;quot;false&amp;quot; z=&amp;quot;u4EclOEjQnID4g34VPv9zu9+qPo=&amp;quot;/&amp;gt;
      &amp;lt;field:file field=&amp;quot;content&amp;quot; id=&amp;quot;c_org_pragmatikroo_roodocman_domain_Document_content&amp;quot; required=&amp;quot;true&amp;quot; z=&amp;quot;GZHlfc+o4h7EBA/SZ8/yXMVenOw=&amp;quot;/&amp;gt;
      &amp;lt;field:input field=&amp;quot;contentType&amp;quot; id=&amp;quot;c_org_pragmatikroo_roodocman_domain_Document_contentType&amp;quot; render=&amp;quot;false&amp;quot; z=&amp;quot;jtq5/DHhBTgNImjac/d4AIfpCzA=&amp;quot;/&amp;gt;
      &amp;lt;field:input field=&amp;quot;size&amp;quot; id=&amp;quot;c_org_pragmatikroo_roodocman_domain_Document_size&amp;quot; render=&amp;quot;false&amp;quot; validationMessageCode=&amp;quot;field_invalid_integer&amp;quot; z=&amp;quot;ONDmhU5Eg5pw1j8LgTz9sXjOm6E=&amp;quot;/&amp;gt;
      &amp;lt;field:textarea field=&amp;quot;url&amp;quot; id=&amp;quot;c_org_pragmatikroo_roodocman_domain_Document_url&amp;quot; render=&amp;quot;false&amp;quot; z=&amp;quot;bQ3FUVGL01nfWselK7WDPUD65Rw=&amp;quot;/&amp;gt;
&amp;lt;/form:multi&amp;gt;
</pre><p>As you can see, the form depends on two custom tagx files -multi.tagx and file.tagx- not included in the Spring Roo tag library. These two tags handle the blob field input.<br /><div id="attachment_2152" class="wp-caption aligncenter" style="width: 583px"><img src="http://img.viralpatel.net/2011/02/spring-roo-blob-object.png" alt="spring-roo-blob-object" title="spring-roo-blob-object" width="573" height="222" class="size-full wp-image-2152" /><p class="wp-caption-text">Create Form</p></div></p><p><em>Show.jpx Form</em></p><pre class="brush: xml; title: ; notranslate">
&amp;lt;page:show id=&amp;quot;ps_org_pragmatikroo_roodocman_domain_Document&amp;quot; object=&amp;quot;${document}&amp;quot; path=&amp;quot;/documents&amp;quot; update=&amp;quot;false&amp;quot; z=&amp;quot;J8X2O2T06x6jYb3WAyaNiTPGVZ0=&amp;quot;&amp;gt;
      &amp;lt;field:display field=&amp;quot;name&amp;quot; id=&amp;quot;s_org_pragmatikroo_roodocman_domain_Document_name&amp;quot; object=&amp;quot;${document}&amp;quot; z=&amp;quot;VZEPJgXqYkqaHpDDPTcYr6DAjsM=&amp;quot;/&amp;gt;
      &amp;lt;field:display field=&amp;quot;description&amp;quot; id=&amp;quot;s_org_pragmatikroo_roodocman_domain_Document_description&amp;quot; object=&amp;quot;${document}&amp;quot; z=&amp;quot;CeXQhSyEDeLn1Iu2hblanNbVc+A=&amp;quot;/&amp;gt;
      &amp;lt;field:display field=&amp;quot;filename&amp;quot; id=&amp;quot;s_org_pragmatikroo_roodocman_domain_Document_filename&amp;quot; object=&amp;quot;${document}&amp;quot; z=&amp;quot;2HT3+zT1+1ft5kN4KhvXFWT9QnM=&amp;quot;/&amp;gt;
      &amp;lt;field:display field=&amp;quot;contentType&amp;quot; id=&amp;quot;s_org_pragmatikroo_roodocman_domain_Document_contentType&amp;quot; object=&amp;quot;${document}&amp;quot; z=&amp;quot;FgCNUQ2KCygzKpUbP06Nxyjyfd8=&amp;quot;/&amp;gt;
      &amp;lt;field:display field=&amp;quot;size&amp;quot; id=&amp;quot;s_org_pragmatikroo_roodocman_domain_Document_size&amp;quot; object=&amp;quot;${document}&amp;quot; z=&amp;quot;WdQ4wob2LThzMpucODZRa275TBc=&amp;quot;/&amp;gt;
      &amp;lt;field:frame field=&amp;quot;url&amp;quot; id=&amp;quot;s_org_pragmatikroo_roodocman_domain_Document_url&amp;quot; object=&amp;quot;${document}&amp;quot; render=&amp;quot;true&amp;quot; z=&amp;quot;user-managed&amp;quot;/&amp;gt;
&amp;lt;/page:show&amp;gt;
</pre><p>This form depends on a custom tag frame.tagx. Basically is a iframe html for rendering images.<br /><div id="attachment_2150" class="wp-caption aligncenter" style="width: 585px"><img src="http://img.viralpatel.net/2011/02/spring-roo-blob-show-form.png" alt="spring-roo-blob-show-form" title="spring-roo-blob-show-form" width="575" height="266" class="size-full wp-image-2150" /><p class="wp-caption-text">Show Form</p></div></p><div id="attachment_2151" class="wp-caption aligncenter" style="width: 586px"><img src="http://img.viralpatel.net/2011/02/spring-roo-blob-list-form.png" alt="spring-roo-blob-list-form" title="spring-roo-blob-list-form" width="576" height="144" class="size-full wp-image-2151" /><p class="wp-caption-text">List Form</p></div><p>Little issue with a missed dependency: When you deploy the app -after the file upload changes- you will find a  missing dependence error.</p><pre class="brush: xml; title: ; notranslate">
&amp;lt;dependency&amp;gt;
    &amp;lt;groupId&amp;gt;commons-io&amp;lt;/groupId&amp;gt;
    &amp;lt;artifactId&amp;gt;commons-io&amp;lt;/artifactId&amp;gt;
    &amp;lt;version&amp;gt;2.0.1&amp;lt;/version&amp;gt;
&amp;lt;/dependency&amp;gt;
</pre><p>This is it!.</p><h2>Download Source</h2><p><a href="http://viralpatel.net/blogs/download/spring/spring-roo-blob-documentmanager.zip">Click here to download source code (ZIP, 94kb).</a></p><h2>Conclusion</h2><p>Well, the Reader has been exposed to two pretty close but at the same time different ways of  implementing a particular web application project.  Both are using the same  high quality open source code Java-based development stack: Spring 3.X. I believe both ways are good and valid. There is a significant difference in Spring Roo approach though. Roo advocates for removing the &#8220;<strong>unnecessary abstractions</strong>&#8221; from web development. So, you won&#8217;t find Daos or Services classes in a  typical Roo project. This is totally fine with me. However,  it  is a subject still in revision by the community at large. Not to mention that nothing stops you for implementing them if you need/want them.  If you allow me one final point, I like better Roo approach because it gives me more time for thinking and figuring our how to solve the problem.</p><div id="relatedpost"><h2  class="related_post_title">Related Posts</h2><ul class="related_post"><li><a href="http://viralpatel.net/blogs/2011/02/spring-roo-customizing-web-mvc-ui-forms.html" title="Spring Roo: Customizing Web MVC UI Forms">Spring Roo: Customizing Web MVC UI Forms</a></li><li><a href="http://viralpatel.net/blogs/2011/01/spring-roo-implement-masterdetail-forms.html" title="How to implement Master/Detail forms using Spring Roo">How to implement Master/Detail forms using Spring Roo</a></li><li><a href="http://viralpatel.net/blogs/2011/01/tutorial-save-get-blob-object-spring-3-mvc-hibernate.html" title="Tutorial:Saving/Retreving BLOB object in Spring 3 MVC and Hibernate">Tutorial:Saving/Retreving BLOB object in Spring 3 MVC and Hibernate</a></li><li><a href="http://viralpatel.net/blogs/2205/change-spring-servlet-filename-configuration" title="Change spring-servlet.xml Filename (Spring Web Contenxt Configuration Filename)">Change spring-servlet.xml Filename (Spring Web Contenxt Configuration Filename)</a></li><li><a href="http://viralpatel.net/blogs/2011/02/cache-support-spring-3-1-m1.html" title="Introducing Cache support in Spring 3.1 M1">Introducing Cache support in Spring 3.1 M1</a></li><li><a href="http://viralpatel.net/blogs/2011/01/spring-roo-two-database-configuration.html" title="Spring Roo: Two Databases Configuration">Spring Roo: Two Databases Configuration</a></li><li><a href="http://viralpatel.net/blogs/2010/11/spring3-mvc-hibernate-maven-tutorial-eclipse-example.html" title="Tutorial:Create Spring 3 MVC Hibernate 3 Example using Maven in Eclipse">Tutorial:Create Spring 3 MVC Hibernate 3 Example using Maven in Eclipse</a></li></ul></div>]]></content:encoded> <wfw:commentRss>http://viralpatel.net/blogs/2011/02/spring-roo-save-read-blob-object-spring-roo-tutorial.html/feed</wfw:commentRss> <slash:comments>46</slash:comments> </item> <item><title>How to implement Master/Detail forms using Spring Roo</title><link>http://viralpatel.net/blogs/2011/01/spring-roo-implement-masterdetail-forms.html</link> <comments>http://viralpatel.net/blogs/2011/01/spring-roo-implement-masterdetail-forms.html#comments</comments> <pubDate>Mon, 31 Jan 2011 12:09:00 +0000</pubDate> <dc:creator>Jose Delgado</dc:creator> <category><![CDATA[Spring]]></category> <category><![CDATA[Spring Roo]]></category> <category><![CDATA[spring-roo]]></category> <category><![CDATA[Tutorial]]></category><guid isPermaLink="false">http://viralpatel.net/blogs/?p=2145</guid> <description><![CDATA[I jumped in the Spring Roo wagon since version 1.1.0M1. The first thing I wanted to do after got used to it. It was to try typical requirements that come very often in the work of a Web Developer. I needed a wep app to work on, so I came up with World Alamac by [...]]]></description> <content:encoded><![CDATA[<p>I jumped in the Spring Roo wagon since  version 1.1.0M1.  The first thing I wanted to do after got used to it. It was to try  typical requirements that come very often in the work of a  Web Developer.<br /> I needed a wep app to work on, so I came up with  World Alamac by jD.  Basically, WorldAlmanac web site is an experimentation  test bed for using Roo. You can visit World Almanac and other Roo-based showcases at <a rel="nofollow" target="_new" href="https://pragmatikroo.org/showcases">https://pragmatikroo.org/showcases</a>.</p><p>I  created a list of  things that I wanted to try: master/detail forms, reports creation, pdf generation, images rendering and SEO to mention a few.   Let&#8217;s start with the first item of   the referred list.  The article assumes  the Reader is a Developer with familiarity with Spring Roo. For information about Spring Roo please visit the project web site: <a rel="nofollow" target="_new" href="http://www.springsource.org/roo">http://www.springsource.org/roo</a>.</p><h2>World Almanac Master/Detail Form</h2><p>The web application uses a database with data of the Countries, Cities and  Languages spoken in the Earth. I selected  the Country/City entitiesto build a master/detail web form. You can try the web form  at <a rel="nofollow" target="_new" href="http://pragmatikroo.org/worldAlmanac/">http://pragmatikroo.org/worldAlmanac/</a> on the Cities menu.</p><p>As I formalized the master/detail implementation, I realized that it could be get it, as the composition of  two  list.jspx from the tagx library included with Roo.  A top list.jspx for the upper grid (Countries) and another one for the lower (Cities).  Some basic grid events are required as well: independent upper and lower navigation,  Cities rendering -after country selection- and grids state management.</p><div id="attachment_2146" class="wp-caption aligncenter" style="width: 668px"><img src="http://img.viralpatel.net/2011/01/spring-roo-countries-web-form.png" alt="spring-roo-countries-web-form" title="spring-roo-countries-web-form" width="658" height="243" class="size-full wp-image-2146" /><p class="wp-caption-text">Countries Web Form</p></div><h2>Master Grid View</h2><p>The master/detail form is rendered  using a customized  form created by a finder Roo command.  The  upper grid code is shown below:<br /> <b>Master Grid Client Code</b></p><pre class="brush: xml; title: ; notranslate">
&lt;page:list id=&quot;pl:org.josean.rooworld.domain.Country&quot; items=&quot;${countrys}&quot; z=&quot;fmh1dw5QkHal9+wnb0JDqVvC1f8=&quot;&gt;
      &lt;tblchooser:tblchooser data=&quot;${countrys}&quot; maxPages=&quot;${upperTblMaxPages}&quot; page=&quot;${upage}&quot; size=&quot;${usize}&quot; pageid=&quot;upage&quot; sizeid=&quot;usize&quot; anchorURL=&quot;${upperTblAnchorURL}&quot; id=&quot;l:org.josean.rooworld.domain.Country&quot; path=&quot;/citys&quot; typeIdFieldName=&quot;${upperTypeIdFieldName}&quot; z=&quot;1FSBfbX2cD9Hf48J/CgEpgGqM5I=&quot;&gt;
            &lt;table:column id=&quot;c:org.josean.rooworld.domain.Country.name&quot; property=&quot;name&quot; maxLength=&quot;20&quot; /&gt;
            &lt;table:column id=&quot;c:org.josean.rooworld.domain.Country.region&quot; property=&quot;region&quot; maxLength=&quot;20&quot; /&gt;
            &lt;table:column id=&quot;c:org.josean.rooworld.domain.Country.surfaceArea&quot; property=&quot;surfaceArea&quot; z=&quot;EnBh6dRSPblki866Bz0xsC4Yvs4=&quot; /&gt;
            &lt;table:column id=&quot;c:org.josean.rooworld.domain.Country.indepYear&quot; property=&quot;indepYear&quot; z=&quot;O8Ya+uYQroS0GvycsapKO1RZ3QU=&quot; /&gt;
            &lt;table:column id=&quot;c:org.josean.rooworld.domain.Country.population&quot; property=&quot;population&quot; z=&quot;jpsNyj3k7FE84bLm63Wke+N0/lo=&quot; /&gt;
            &lt;table:column id=&quot;c:org.josean.rooworld.domain.Country.code&quot; property=&quot;code&quot; z=&quot;?&quot; /&gt;
      &lt;/tblchooser:tblchooser&gt;
&lt;/page:list&gt;
</pre><p>There  is a custom tag named  tblchooser.  This is a custom control that enables attributes to support grid functionaly. Each grid  uses  local attributes.  The tblchooser component is included in the code download associated to this article.  Remember this is only the master grid of the master/detail.</p><h2>Detail Grid Client View</h2><div id="attachment_2147" class="wp-caption aligncenter" style="width: 671px"><img src="http://img.viralpatel.net/2011/01/spring-roo-country-selection-form.png" alt="" title="spring-roo-country-selection-form" width="661" height="446" class="size-full wp-image-2147" /><p class="wp-caption-text">Countries/Cities Web Form after a country selection (Australia)</p></div><h2>Detail Grid Client Code</h2><pre class="brush: xml; title: ; notranslate">
&lt;page:list id=&quot;pl:org.josean.rooworld.domain.City&quot; items=&quot;${citys}&quot; z=&quot;?&quot;&gt;
      &lt;table:table data=&quot;${citys}&quot; id=&quot;l:org.josean.rooworld.domain.City&quot; maxPages=&quot;${lowerTblMaxPages}&quot; page=&quot;${lpage}&quot; size=&quot;${lsize}&quot; pageid=&quot;lpage&quot; sizeid=&quot;lsize&quot; typeIdFieldName=&quot;${lowerTypeIdFieldName}&quot; anchorURL=&quot;${lowerTblAnchorURL}&quot; path=&quot;/citys&quot; select=&quot;false&quot; z=&quot;fsLaGs5Dtou//oijKgETnKUig+Q=&quot;&gt;
            &lt;table:column id=&quot;c:org.josean.rooworld.domain.City.name&quot; property=&quot;name&quot; maxLength=&quot;20&quot; /&gt;
            &lt;table:column id=&quot;c:org.josean.rooworld.domain.City.district&quot; property=&quot;district&quot; maxLength=&quot;20&quot; /&gt;
            &lt;table:column id=&quot;c:org.josean.rooworld.domain.City.population&quot; property=&quot;population&quot; z=&quot;IXrFcR0CsSh9GUTIAcPddSpBCrM=&quot; /&gt;
      &lt;/table:table&gt;
&lt;/page:list&gt;
</pre><p>Pretty much same as the upper grid.  Only difference it uses  just a regular table control.</p><h2>Server Side code</h2><pre class="brush: java; title: ; notranslate">
@RequestMapping(params = { &quot;find=ByIncountry&quot;, &quot;form&quot; }, method = RequestMethod.GET)
public String CityController.findCitysByIncountryForm(
	@RequestParam(value = &quot;upage&quot;, required = false) Integer upage,
	@RequestParam(value = &quot;usize&quot;, required = false) Integer usize,
	@RequestParam(value = &quot;lpage&quot;, required = false) Integer lpage,
	@RequestParam(value = &quot;lsize&quot;, required = false) Integer lsize,
	@RequestParam(value = &quot;ctryselected&quot;, required = false) String ctryselected,
	ModelMap modelMap) {
				modelMap.addAttribute(&quot;update&quot;, false);
				modelMap.addAttribute(&quot;delete&quot;, false);
				modelMap.addAttribute(&quot;create&quot;, false);

	if (upage != null || usize != null) {
		int sizeNo = usize == null ? 10 : usize.intValue();
		modelMap.addAttribute(
		&quot;countrys&quot;,
		Country.findCountryEntriesAllObj(
		upage == null ? 0 : (upage.intValue() - 1) * sizeNo,
		sizeNo));

		float nrOfPages = (float) Country.countCountrys() / sizeNo;
		modelMap.addAttribute(
			&quot;upperTblMaxPages&quot;,
			(int) ((nrOfPages &gt; (int) nrOfPages || nrOfPages == 0.0) ? nrOfPages + 1
							: nrOfPages));
		modelMap.addAttribute(&quot;upperTblAnchorURL&quot;, &quot;/citys?find=ByIncountry&amp;form&quot;);
		modelMap.addAttribute(&quot;upperTypeIdFieldName&quot;, &quot;code&quot;);
		modelMap.addAttribute(&quot;upage&quot;, upage);
		modelMap.addAttribute(&quot;usize&quot;, usize);
	} else {
		modelMap.addAttribute(&quot;countrys&quot;, Country.findAllCountrysAllObj());
	}

	if (ctryselected != null) {
		int sizeNo = 10;
		lpage = lpage == null ? 0 : lpage.intValue();

		int numOfCities = City.countCitiesByCountry(ctryselected);
		int nrOfPages = (int)Math.ceil(((double)numOfCities) / sizeNo);
		int from =  ( lpage ==0? 0 : (lpage.intValue()-1) * sizeNo );

		if (nrOfPages &gt;= 1){
						modelMap.addAttribute(&quot;citys&quot;,City.findCitysByIncountry(ctryselected,from, 10));
			}
	else {
				modelMap.addAttribute(&quot;citys&quot;,City.findCitysByIncountry(ctryselected,0,numOfCities));
	}

	modelMap.addAttribute(&quot;lowerTblMaxPages&quot;, nrOfPages);
	modelMap.addAttribute(&quot;lowerTblAnchorURL&quot;,&quot;/citys?find=ByIncountry&amp;form&amp;ctryselected=&quot; + ctryselected+ &quot;&amp;upage=&quot; + upage + &quot;&amp;usize=&quot; + usize);

	modelMap.addAttribute(&quot;lowerTypeIdFieldName&quot;, &quot;id&quot;);
	modelMap.addAttribute(&quot;lpage&quot;, lpage);
	modelMap.addAttribute(&quot;lsize&quot;, lsize);
	} else {
		if (ctryselected == null)
			modelMap.addAttribute(&quot;citys&quot;, null);
	}
		return &quot;citys/findCitysByIncountry&quot;;
	}
</pre><p> This  method code  handles the master/detail, countries/cities form  of  WorldAlmanac  web app.  As you can see  it follows closely the client side. The upper section handles the countries grid population and its navigation. The ctryselected   is a pivot the actives the lower section on country selection on  the web form.  There is not much else to explain here.  Basically, it is a light customization of the source code generate by Roo.</p><p>That is it!</p><h2>Download Source</h2><p><a href="http://viralpatel.net/blogs/download/spring/springroo-masterdetail.zip">Click here to download source code (ZIP, 3kb)</a></p><h2>Conclusion</h2><p>This is  WorldAlmanac  master/detail  implementation -using Spring Roo- in a nutshell.  I sincerely look forward  to helping some colleagues Developers that have requested details and  source code of it. It is more a detailed description than a  ready-to go code.  However, I truly believe that  the approach can  be applied to any  particular project.  It is a simple implementation that uses nothing more than Spring Roo as it was wrapped in version 1.1.0M1.  The components might need some tweak since Roo has evolve since code inception.  Further questions would be  handled using the blog.</p><div id="relatedpost"><h2  class="related_post_title">Related Posts</h2><ul class="related_post"><li><a href="http://viralpatel.net/blogs/2011/02/spring-roo-customizing-web-mvc-ui-forms.html" title="Spring Roo: Customizing Web MVC UI Forms">Spring Roo: Customizing Web MVC UI Forms</a></li><li><a href="http://viralpatel.net/blogs/2011/02/spring-roo-save-read-blob-object-spring-roo-tutorial.html" title="Spring Roo: Saving/Retreving BLOB object in Spring Roo">Spring Roo: Saving/Retreving BLOB object in Spring Roo</a></li><li><a href="http://viralpatel.net/blogs/2010/06/tutorial-spring-3-mvc-introduction-spring-mvc-framework.html" title="Spring 3 MVC – Introduction to Spring 3 MVC Framework">Spring 3 MVC – Introduction to Spring 3 MVC Framework</a></li><li><a href="http://viralpatel.net/blogs/2008/12/tutorial-struts-spring-framework-example-in-eclipse.html" title="Tutorial:Struts Spring framework example in Eclipse.">Tutorial:Struts Spring framework example in Eclipse.</a></li><li><a href="http://viralpatel.net/blogs/2205/change-spring-servlet-filename-configuration" title="Change spring-servlet.xml Filename (Spring Web Contenxt Configuration Filename)">Change spring-servlet.xml Filename (Spring Web Contenxt Configuration Filename)</a></li><li><a href="http://viralpatel.net/blogs/2011/11/hibernate-hello-world-example-annotation.html" title="Hibernate Hello World example using Annotation">Hibernate Hello World example using Annotation</a></li><li><a href="http://viralpatel.net/blogs/2011/02/cache-support-spring-3-1-m1.html" title="Introducing Cache support in Spring 3.1 M1">Introducing Cache support in Spring 3.1 M1</a></li></ul></div>]]></content:encoded> <wfw:commentRss>http://viralpatel.net/blogs/2011/01/spring-roo-implement-masterdetail-forms.html/feed</wfw:commentRss> <slash:comments>4</slash:comments> </item> <item><title>Spring Roo: Two Databases Configuration</title><link>http://viralpatel.net/blogs/2011/01/spring-roo-two-database-configuration.html</link> <comments>http://viralpatel.net/blogs/2011/01/spring-roo-two-database-configuration.html#comments</comments> <pubDate>Wed, 26 Jan 2011 19:13:40 +0000</pubDate> <dc:creator>Jose Delgado</dc:creator> <category><![CDATA[Spring]]></category> <category><![CDATA[Spring Roo]]></category> <category><![CDATA[Database]]></category><guid isPermaLink="false">http://viralpatel.net/blogs/?p=2142</guid> <description><![CDATA[I&#8217;ve seen very often a recurrent question on Spring Roo forums. The question is &#8220;How to configure the application to handle two databases&#8221;. Certainly this is a more ample question to Spring Roo only, due it involves JPA and the Spring persistence stack. So, I believe it will be of interest to all the Spring [...]]]></description> <content:encoded><![CDATA[<p><img src="http://img.viralpatel.net/2011/01/spring-roo-logo.png" alt="spring-roo-logo" title="spring-roo-logo" width="198" height="118" class="alignright size-full wp-image-2143" />I&#8217;ve seen very often a recurrent question on <strong>Spring Roo</strong> forums. The question is &#8220;How to configure the application to handle two databases&#8221;.</p><p>Certainly this is a more ample question to Spring Roo only, due it involves JPA and the Spring persistence stack. So, I believe it will be of interest to all the Spring development community that face such problem.</p><p>I am assuming the Reader is a Java Developer with some familarity with Spring Roo. I focus on to how to get to configuration only. For help on how to use Roo, please visit <a rel="nofollow" target="_new" href="http://www.springsource.org/roo">http://www.springsource.org/roo</a>.</p><h2>Hands on the problem</h2><p>I created the following minimal Roo project (shown below) for explaining the setup. I&#8217;ll modify the configuration in a way that each entity will come from different independent databases.</p><pre class="brush: xml; title: ; notranslate">
project --topLevelPackage org.pragmatikroo.twodb
persistence setup --provider HIBERNATE --database MYSQL --userName &lt;username&gt; --password &lt;password&gt; --databaseName twodbone
logging setup --level DEBUG --package PERSISTENCE
entity --class ~.domain.DbOne
field string --fieldName name
entity --class ~.domain.DbTwo
field string --fieldName name
perform clean
perform eclipse
exit
</pre><h3>Database.properties file original</h3><pre class="brush: xml; title: ; notranslate">
database.password=&lt;password&gt;
database.url=jdbc\:mysql\://localhost\:3306/twodb
database.username=&lt;username&gt;
database.driverClassName=com.mysql.jdbc.Driver
</pre><h3>Database.properties file modified</h3><pre class="brush: xml; title: ; notranslate">
database.password1=&lt;password1&gt;
database.url1=jdbc\:mysql\://localhost\:3306/twodbone
database.username1=&lt;username1&gt;
database.password2=&lt;password1&gt;
database.url2=jdbc\:mysql\://localhost\:3306/twodbtwo
database.username2=&lt;username2&gt;
database.driverClassName=com.mysql.jdbc.Driver
</pre><p>Basically, I have duplicated the code from the original file delivered by Roo to define the 2nd database. This pattern would be repeated for the other files as well.</p><h3>Persistence.xml file modified</h3><pre class="brush: xml; title: ; notranslate">
&lt;persistence-unit name=&quot;persistenceUnit1&quot; transaction-type=&quot;RESOURCE_LOCAL&quot;&gt;
      &lt;provider&gt;org.hibernate.ejb.HibernatePersistence&lt;/provider&gt;
      &lt;class&gt;org.josean.twodb.domain.DbOne&lt;/class&gt;
      &lt;exclude-unlisted-classes&gt;true&lt;/exclude-unlisted-classes&gt;
      &lt;properties&gt;
            &lt;property name=&quot;hibernate.dialect&quot; value=&quot;org.hibernate.dialect.MySQL5InnoDBDialect&quot;/&gt;
            &lt;!-- value=&quot;create&quot; to build a new database on each run; value=&quot;update&quot; to modify an existing database; value=&quot;create-drop&quot; means the same as &quot;create&quot; but also drops tables when Hibernate closes; value=&quot;validate&quot; makes no changes to the database --&gt;
            &lt;property name=&quot;hibernate.hbm2ddl.auto&quot; value=&quot;update&quot;/&gt;
            &lt;property name=&quot;hibernate.ejb.naming_strategy&quot; value=&quot;org.hibernate.cfg.ImprovedNamingStrategy&quot;/&gt;
            &lt;property name=&quot;hibernate.connection.charSet&quot; value=&quot;UTF-8&quot;/&gt;
            &lt;!-- Uncomment the following two properties for JBoss only --&gt;
            &lt;!-- property name=&quot;hibernate.validator.apply_to_ddl&quot; value=&quot;false&quot; /--&gt;
            &lt;!-- property name=&quot;hibernate.validator.autoregister_listeners&quot; value=&quot;false&quot; /--&gt;
            &lt;/properties&gt;
&lt;/persistence-unit&gt;
&lt;persistence-unit name=&quot;persistenceUnit2&quot; transaction-type=&quot;RESOURCE_LOCAL&quot;&gt;
      &lt;provider&gt;org.hibernate.ejb.HibernatePersistence&lt;/provider&gt;
      &lt;class&gt;org.josean.twodb.domain.DbTwo&lt;/class&gt;
      &lt;exclude-unlisted-classes&gt;true&lt;/exclude-unlisted-classes&gt;
      &lt;properties&gt;
            &lt;property name=&quot;hibernate.dialect&quot; value=&quot;org.hibernate.dialect.MySQL5InnoDBDialect&quot;/&gt;
            &lt;!-- value=&quot;create&quot; to build a new database on each run; value=&quot;update&quot; to modify an existing database; value=&quot;create-drop&quot; means the same as &quot;create&quot; but also drops tables when Hibernate closes; value=&quot;validate&quot; makes no changes to the database --&gt;
            &lt;property name=&quot;hibernate.hbm2ddl.auto&quot; value=&quot;update&quot;/&gt;
            &lt;property name=&quot;hibernate.ejb.naming_strategy&quot; value=&quot;org.hibernate.cfg.ImprovedNamingStrategy&quot;/&gt;
            &lt;property name=&quot;hibernate.connection.charSet&quot; value=&quot;UTF-8&quot;/&gt;
            &lt;!-- Uncomment the following two properties for JBoss only --&gt;
            &lt;!-- property name=&quot;hibernate.validator.apply_to_ddl&quot; value=&quot;false&quot; /--&gt;
            &lt;!-- property name=&quot;hibernate.validator.autoregister_listeners&quot; value=&quot;false&quot; /--&gt;
            &lt;/properties&gt;
&lt;/persistence-unit&gt;
</pre><p>I duplicated the persistence unit code for the 2nd database and define unique ids. <strong>Important:</strong> Add the <code>&lt;class&gt;</code> and <code>&lt;exclude-unlisted-classes&gt;</code> as shown in the code above. As implied each entity handled by this persistence unit have to be included.</p><h3>ApplicationContext.xml file modified</h3><pre class="brush: xml; title: ; notranslate">
&lt;bean class=&quot;org.apache.commons.dbcp.BasicDataSource&quot; destroy-method=&quot;close&quot; id=&quot;dataSource1&quot;&gt;
      &lt;property name=&quot;driverClassName&quot; value=&quot;${database.driverClassName}&quot;/&gt;
      &lt;property name=&quot;url&quot; value=&quot;${database.url1}&quot;/&gt;
      &lt;property name=&quot;username&quot; value=&quot;${database.username1}&quot;/&gt;
      &lt;property name=&quot;password&quot; value=&quot;${database.password1}&quot;/&gt;
      &lt;property name=&quot;validationQuery&quot; value=&quot;SELECT 1 FROM DUAL&quot;/&gt;
      &lt;property name=&quot;testOnBorrow&quot; value=&quot;true&quot;/&gt;
&lt;/bean&gt;
&lt;bean class=&quot;org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean&quot; id=&quot;entityManagerFactory1&quot;&gt;
      &lt;property name=&quot;dataSource&quot; ref=&quot;dataSource1&quot;/&gt;
      &lt;property name=&quot;persistenceUnitName&quot; value=&quot;persistenceUnit1&quot;/&gt;
&lt;/bean&gt;
&lt;tx:annotation-driven mode=&quot;aspectj&quot; transaction-manager=&quot;transactionManager1&quot; /&gt;
&lt;bean class=&quot;org.springframework.orm.jpa.JpaTransactionManager&quot; id=&quot;transactionManager1&quot;&gt;
      &lt;property name=&quot;entityManagerFactory&quot; ref=&quot;entityManagerFactory1&quot; /&gt;
&lt;/bean&gt;
&lt;bean class=&quot;org.apache.commons.dbcp.BasicDataSource&quot; destroy-method=&quot;close&quot; id=&quot;dataSource2&quot;&gt;
      &lt;property name=&quot;driverClassName&quot; value=&quot;${database.driverClassName}&quot;/&gt;
      &lt;property name=&quot;url&quot; value=&quot;${database.url2}&quot;/&gt;
      &lt;property name=&quot;username&quot; value=&quot;${database.username2}&quot;/&gt;
      &lt;property name=&quot;password&quot; value=&quot;${database.password2}&quot;/&gt;
      &lt;property name=&quot;validationQuery&quot; value=&quot;SELECT 1 FROM DUAL&quot;/&gt;
      &lt;property name=&quot;testOnBorrow&quot; value=&quot;true&quot;/&gt;
&lt;/bean&gt;
&lt;bean class=&quot;org.springframework.orm.jpa.JpaTransactionManager&quot; id=&quot;transactionManager2&quot;&gt;
      &lt;property name=&quot;entityManagerFactory&quot; ref=&quot;entityManagerFactory2&quot;/&gt;
&lt;/bean&gt;
&lt;tx:annotation-driven mode=&quot;aspectj&quot; transaction-manager=&quot;transactionManager2&quot; /&gt;
&lt;bean class=&quot;org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean&quot; id=&quot;entityManagerFactory2&quot;&gt;
      &lt;property name=&quot;dataSource&quot; ref=&quot;dataSource2&quot;/&gt;
      &lt;property name=&quot;persistenceUnitName&quot; value=&quot;persistenceUnit2&quot;/&gt;
&lt;/bean&gt;
</pre><p>Same process as the other files. Duplicate as shown. Add property attribute to the <code>entityManagerFactory</code> beans.</p><h3>Web.xml file modified</h3><pre class="brush: xml; title: ; notranslate">
&lt;filter&gt;
      &lt;filter-name&gt;Spring OpenEntityManagerInViewFilter1&lt;/filter-name&gt;
      &lt;filter-class&gt;org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter&lt;/filter-class&gt;
      &lt;init-param&gt;
            &lt;param-name&gt;entityManagerFactoryBeanName&lt;/param-name&gt;
            &lt;param-value&gt;entityManagerFactory1&lt;/param-value&gt;
      &lt;/init-param&gt;
&lt;/filter&gt;
&lt;filter&gt;
      &lt;filter-name&gt;Spring OpenEntityManagerInViewFilter2&lt;/filter-name&gt;
      &lt;filter-class&gt;org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter&lt;/filter-class&gt;
      &lt;init-param&gt;
            &lt;param-name&gt;entityManagerFactoryBeanName&lt;/param-name&gt;
            &lt;param-value&gt;entityManagerFactory2&lt;/param-value&gt;
      &lt;/init-param&gt;
&lt;/filter&gt;
</pre><p>This is it!. Application ready for deploying and testing.</p><h2>Conclusion</h2><p>I showed the interested Reader how to setup the application context of a Spring web app to access 2nd databases, in particular to Spring Roo Developer.</p><div id="relatedpost"><h2  class="related_post_title">Related Posts</h2><ul class="related_post"><li><a href="http://viralpatel.net/blogs/2205/change-spring-servlet-filename-configuration" title="Change spring-servlet.xml Filename (Spring Web Contenxt Configuration Filename)">Change spring-servlet.xml Filename (Spring Web Contenxt Configuration Filename)</a></li><li><a href="http://viralpatel.net/blogs/2011/02/cache-support-spring-3-1-m1.html" title="Introducing Cache support in Spring 3.1 M1">Introducing Cache support in Spring 3.1 M1</a></li><li><a href="http://viralpatel.net/blogs/2011/02/spring-roo-customizing-web-mvc-ui-forms.html" title="Spring Roo: Customizing Web MVC UI Forms">Spring Roo: Customizing Web MVC UI Forms</a></li><li><a href="http://viralpatel.net/blogs/2011/02/spring-roo-save-read-blob-object-spring-roo-tutorial.html" title="Spring Roo: Saving/Retreving BLOB object in Spring Roo">Spring Roo: Saving/Retreving BLOB object in Spring Roo</a></li><li><a href="http://viralpatel.net/blogs/2011/01/spring-roo-implement-masterdetail-forms.html" title="How to implement Master/Detail forms using Spring Roo">How to implement Master/Detail forms using Spring Roo</a></li><li><a href="http://viralpatel.net/blogs/2011/01/tutorial-save-get-blob-object-spring-3-mvc-hibernate.html" title="Tutorial:Saving/Retreving BLOB object in Spring 3 MVC and Hibernate">Tutorial:Saving/Retreving BLOB object in Spring 3 MVC and Hibernate</a></li><li><a href="http://viralpatel.net/blogs/2010/11/row-data-multiplication-in-oracle.html" title="Row Data Multiplication in Oracle">Row Data Multiplication in Oracle</a></li></ul></div>]]></content:encoded> <wfw:commentRss>http://viralpatel.net/blogs/2011/01/spring-roo-two-database-configuration.html/feed</wfw:commentRss> <slash:comments>22</slash:comments> </item> <item><title>Tutorial:Saving/Retreving BLOB object in Spring 3 MVC and Hibernate</title><link>http://viralpatel.net/blogs/2011/01/tutorial-save-get-blob-object-spring-3-mvc-hibernate.html</link> <comments>http://viralpatel.net/blogs/2011/01/tutorial-save-get-blob-object-spring-3-mvc-hibernate.html#comments</comments> <pubDate>Tue, 11 Jan 2011 13:52:40 +0000</pubDate> <dc:creator>Viral Patel</dc:creator> <category><![CDATA[Hibernate]]></category> <category><![CDATA[Spring 3 MVC]]></category> <category><![CDATA[blob]]></category> <category><![CDATA[MySQL]]></category> <category><![CDATA[Spring]]></category> <category><![CDATA[spring mvc]]></category><guid isPermaLink="false">http://viralpatel.net/blogs/?p=2129</guid> <description><![CDATA[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 [...]]]></description> <content:encoded><![CDATA[<p><img src="http://img.viralpatel.net/2011/01/spring-hibernate-blob-mysql-tutorial.png" alt="spring-hibernate-blob-mysql-tutorial" title="spring-hibernate-blob-mysql-tutorial" width="231" height="110" class="alignleft size-full wp-image-2130" />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.</p><h2>Our Goal</h2><p>Our goal is to create a Document Manager application in Spring 3 MVC and Hibernate. Following is the functionality.</p><ol><li>A form is displayed on main page with fields such as Document name, description and browse button to select document from file system.</li><li>User can select any document from local drive and upload the same using Save document functionality.</li><li>All the documents saved are added in a database table.</li><li>List of all the documents present in database is displayed on the main page.</li><li>Each document in the list have two buttons: Delete and Download.</li><li>Any document can be downloaded by clicking on download button.</li><li>Any document can be deleted by clicking on delete button.</li></ol><p>Here is the final screen shot of Document manager application.<br /> <img src="http://img.viralpatel.net/2011/01/document-manager-hibernate-spring-blob.png" alt="document-manager-hibernate-spring-blob" title="document-manager-hibernate-spring-blob" width="451" height="358" class="aligncenter size-full wp-image-2131" /></p><h2>Step 1: Create Database Table</h2><p>For Document Manager application, we will use MySQL database. Create a table <strong>documents</strong> in MySQL database <strong>docdb</strong>. 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.</p><pre class="brush: sql; title: ; notranslate">
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`)
);
</pre><h2>Step 2: Create Maven Project in Eclipse</h2><p>The document manager application will use Maven for build and dependency management. For this we will use the <a href="http://viralpatel.net/blogs/2010/07/generate-dynamic-web-project-maven-eclipse-wtp.html">Maven Dynamic Web Project in Eclipse</a> as the base architecture of our application.</p><p>Or directly download the below source code:<br /> <a rel="nofollow" href="http://viralpatel.net/blogs/download/j2ee/maven/MavenWeb.zip"><strong>Maven Dynamic Web Project</strong> (6.7 KB)</a></p><p>Once you have imported / created the Maven web project in Eclipse. Copy following content into Maven&#8217;s pom.xml file. These are the dependencies we will use in our Document manager application.<br /> <em>File: /pom.xml</em></p><pre class="brush: xml; title: ; notranslate">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;&lt;project&gt;
  &lt;modelVersion&gt;4.0.0&lt;/modelVersion&gt;
  &lt;groupId&gt;MavenWeb&lt;/groupId&gt;
  &lt;artifactId&gt;MavenWeb&lt;/artifactId&gt;
  &lt;packaging&gt;war&lt;/packaging&gt;
  &lt;version&gt;0.0.1-SNAPSHOT&lt;/version&gt;
  &lt;description&gt;&lt;/description&gt;
  &lt;build&gt;
    &lt;plugins&gt;
      &lt;plugin&gt;
        &lt;artifactId&gt;maven-compiler-plugin&lt;/artifactId&gt;
        &lt;configuration&gt;
          &lt;source&gt;1.5&lt;/source&gt;
          &lt;target&gt;1.5&lt;/target&gt;
        &lt;/configuration&gt;
      &lt;/plugin&gt;
      &lt;plugin&gt;
        &lt;artifactId&gt;maven-war-plugin&lt;/artifactId&gt;
        &lt;version&gt;2.0&lt;/version&gt;
      &lt;/plugin&gt;
    &lt;/plugins&gt;
  &lt;/build&gt;
  &lt;dependencies&gt;
    &lt;dependency&gt;
      &lt;groupId&gt;javax.servlet&lt;/groupId&gt;
      &lt;artifactId&gt;servlet-api&lt;/artifactId&gt;
      &lt;version&gt;2.5&lt;/version&gt;
    &lt;/dependency&gt;
    &lt;dependency&gt;
      &lt;groupId&gt;org.springframework&lt;/groupId&gt;
      &lt;artifactId&gt;spring-beans&lt;/artifactId&gt;
      &lt;version&gt;${org.springframework.version}&lt;/version&gt;
    &lt;/dependency&gt;
    &lt;dependency&gt;
      &lt;groupId&gt;org.springframework&lt;/groupId&gt;
      &lt;artifactId&gt;spring-jdbc&lt;/artifactId&gt;
      &lt;version&gt;${org.springframework.version}&lt;/version&gt;
    &lt;/dependency&gt;
    &lt;dependency&gt;
      &lt;groupId&gt;org.springframework&lt;/groupId&gt;
      &lt;artifactId&gt;spring-web&lt;/artifactId&gt;
      &lt;version&gt;${org.springframework.version}&lt;/version&gt;
    &lt;/dependency&gt;
    &lt;dependency&gt;
      &lt;groupId&gt;org.springframework&lt;/groupId&gt;
      &lt;artifactId&gt;spring-webmvc&lt;/artifactId&gt;
      &lt;version&gt;${org.springframework.version}&lt;/version&gt;
    &lt;/dependency&gt;
    &lt;dependency&gt;
      &lt;groupId&gt;org.springframework&lt;/groupId&gt;
      &lt;artifactId&gt;spring-orm&lt;/artifactId&gt;
      &lt;version&gt;${org.springframework.version}&lt;/version&gt;
    &lt;/dependency&gt;
    &lt;dependency&gt;
      &lt;groupId&gt;taglibs&lt;/groupId&gt;
      &lt;artifactId&gt;standard&lt;/artifactId&gt;
      &lt;version&gt;1.1.2&lt;/version&gt;
    &lt;/dependency&gt;
    &lt;dependency&gt;
      &lt;groupId&gt;javax.servlet&lt;/groupId&gt;
      &lt;artifactId&gt;jstl&lt;/artifactId&gt;
      &lt;version&gt;1.1.2&lt;/version&gt;
    &lt;/dependency&gt;
    &lt;dependency&gt;
      &lt;groupId&gt;org.hibernate&lt;/groupId&gt;
      &lt;artifactId&gt;hibernate-entitymanager&lt;/artifactId&gt;
      &lt;version&gt;3.3.2.ga&lt;/version&gt;
    &lt;/dependency&gt;
    &lt;dependency&gt;
      &lt;groupId&gt;mysql&lt;/groupId&gt;
      &lt;artifactId&gt;mysql-connector-java&lt;/artifactId&gt;
      &lt;version&gt;5.1.10&lt;/version&gt;
    &lt;/dependency&gt;
    &lt;dependency&gt;
      &lt;groupId&gt;commons-dbcp&lt;/groupId&gt;
      &lt;artifactId&gt;commons-dbcp&lt;/artifactId&gt;
      &lt;version&gt;20030825.184428&lt;/version&gt;
    &lt;/dependency&gt;
    &lt;dependency&gt;
      &lt;groupId&gt;commons-pool&lt;/groupId&gt;
      &lt;artifactId&gt;commons-pool&lt;/artifactId&gt;
      &lt;version&gt;1.5.4&lt;/version&gt;
    &lt;/dependency&gt;
    &lt;dependency&gt;
      &lt;groupId&gt;commons-fileupload&lt;/groupId&gt;
      &lt;artifactId&gt;commons-fileupload&lt;/artifactId&gt;
      &lt;version&gt;1.2.1&lt;/version&gt;
    &lt;/dependency&gt;
    &lt;dependency&gt;
      &lt;groupId&gt;commons-io&lt;/groupId&gt;
      &lt;artifactId&gt;commons-io&lt;/artifactId&gt;
      &lt;version&gt;1.3&lt;/version&gt;
    &lt;/dependency&gt;
  &lt;/dependencies&gt;
  &lt;properties&gt;
    &lt;org.springframework.version&gt;3.0.2.RELEASE&lt;/org.springframework.version&gt;
    &lt;project.build.sourceEncoding&gt;UTF-8&lt;/project.build.sourceEncoding&gt;
  &lt;/properties&gt;
&lt;/project&gt;
</pre><p><img src="http://img.viralpatel.net/2011/01/document-manager-project-structure.png" alt="document-manager-project-structure" title="document-manager-project-structure" class="alignright size-full wp-image-2132" /><br /> 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 <strong>DocumentManager</strong> and create following packages under <strong>src/main/java</strong> folder.</p><ol><li><em>net.viralpatel.docmanager.controller</em> – This package will contain Spring Controller classes for Document Manager application.</li><li><em>net.viralpatel.docmanager.model</em> – This package will contain form object for Document manager application. Document model will be a simple POJO class with different attributes such as document name, description, filename etc.</li><li><em>net.viralpatel.docmanager.dao</em> – This is the DAO layer of Document manager application. It consists of DocumentDao class which will use Hibernate API to interact with database.</li><li>The <em>src/main/resources</em> folder will have hibernate configuration file: <em>hibernate.cfg.xml</em>.</li><li>The <em>WEB-INF</em> folder will have <em>jsp/documents.jsp</em> file to render document list and add form and <em>jdbc.properties</em> file containing database connection configuration. Also it contains <em>spring-servlet.xml</em> which will define all the Controller class and <em>web.xml</em> which contain spring configuration.</li></ol><h2>Entity class &#8211; The Hibernate model class</h2><p>Let 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.</p><p>Create a java class <code>Document.java</code> under <code>net.viralpatel.docmanager.model</code> package and copy following code into it.<br /> <em>File: /src/main/java/net/viralpatel/docmanager/model/Document.java</em></p><pre class="brush: java; title: ; notranslate">
package 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=&quot;documents&quot;)
public class Document {

	@Id
	@GeneratedValue
	@Column(name=&quot;id&quot;)
	private Integer id;

	@Column(name=&quot;name&quot;)
	private String name;

	@Column(name=&quot;description&quot;)
	private String description;

	@Column(name=&quot;filename&quot;)
	private String filename;

	@Column(name=&quot;content&quot;)
	@Lob
	private Blob content;

	@Column(name=&quot;content_type&quot;)
	private String contentType;

	@Column(name=&quot;created&quot;)
	private Date created;

	//Getter and Setter methods
}
</pre><p>The first thing you’ll 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 that’s what I’m using here.</p><ul><li>First we’ve annotated the class with <code>@Entity</code> which tells Hibernate that this class represents an object that we can persist.</li><li>The <code>@Table(name = "documents")</code> annotation tells Hibernate which table to map properties in this class to documents table. The first property in this class on line 20 is our object ID which will be unique for all events persisted. This is why we’ve annotated it with <code>@Id</code>.</li><li>The <code>@GeneratedValue</code> annotation says that this value will be determined by the datasource, not by the code.</li><li>The <code>@Column(name = "filename")</code> annotation is used to map this property to the FILENAME column in the DOCUMENTS table.</li></ul><h2>The Data Access (DAO) Layer</h2><p>The 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.</p><p><em>File: src/main/java/net/viralpatel/docmanager/dao/DocumentDAO.java</em></p><pre class="brush: java; title: ; notranslate">
package 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&lt;Document&gt; list() {
		Session session = sessionFactory.getCurrentSession();
		List&lt;Document&gt; documents = null;
		try {
			documents = (List&lt;Document&gt;)session.createQuery(&quot;from Document&quot;).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);
	}
}
</pre><p><strong>Methods:</strong></p><ul><li><b>list()</b> Method &#8211; This method gets the list of all documents stored in documents table and return a List of Document objects.</li><li><b>save()</b> Method &#8211; This method is used to store a new document (including BLOB) into database.</li><li><b>get()</b> Method &#8211; This method returns Document entry for a given ID from database. Used in download functionality to download a stored document from database.</li><li><b>remove()</b> Method &#8211; This method is used to delete a document with specific ID from database.</li></ul><p>Note that we have used two Spring annotations <code>@Repository</code> and <code>@Autowired</code>. Classes marked with annotations are candidates for auto-detection by Spring when using annotation-based configuration and classpath scanning. The <code>@Component</code> annotation is the main stereotype that indicates that an annotated class is a “component”.</p><p>The <code>@Repository</code> annotation is yet another stereotype that was introduced in Spring 2.0. This annotation is used to indicate that a class functions as a repository and needs to have exception translation applied transparently on it. The benefit of exception translation is that the service layer only has to deal with exceptions from Spring’s DataAccessException hierarchy, even when using plain JPA in the DAO classes.</p><p>Another annotation used in DocumentDAO is <code>@Autowired</code>. This is used to autowire the dependency of the DocumentDAO on the SessionFactory.</p><p>Also note that we have used @Transactional annotation on each method. Ideally the DAO layer is access from a Service layer and transaction management needs to be specified at Service layer. But again for sake of simplicity we will not include service layer in our example and directly call the DAO layer from Spring Controller. Again, feel free to change this implementation and add your own service layer in between.</p><p>For more information about A layered application with Services in Spring MVC and Hibernate read this tutorial.<br /> <a href="http://viralpatel.net/blogs/2010/11/spring3-mvc-hibernate-maven-tutorial-eclipse-example.html">Spring MVC Hibernate Maven example</a></p><h2>Adding Spring MVC Support to Webapplication</h2><p>Let us add Spring MVC support to our web application.<br /> 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.</p><p><em>File: /src/webapp/WEB-INF/web.xml</em></p><pre class="brush: xml; title: ; notranslate">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;web-app xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
	xmlns=&quot;http://java.sun.com/xml/ns/javaee&quot;
	xmlns:web=&quot;http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd&quot;
	xsi:schemaLocation=&quot;http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd&quot;
	id=&quot;WebApp_ID&quot; version=&quot;2.5&quot;&gt;
	&lt;display-name&gt;DocumentManager&lt;/display-name&gt;
	&lt;welcome-file-list&gt;
		&lt;welcome-file&gt;index.html&lt;/welcome-file&gt;
	&lt;/welcome-file-list&gt;
	&lt;servlet&gt;
		&lt;servlet-name&gt;spring&lt;/servlet-name&gt;
		&lt;servlet-class&gt;
			org.springframework.web.servlet.DispatcherServlet
		&lt;/servlet-class&gt;
		&lt;load-on-startup&gt;1&lt;/load-on-startup&gt;
	&lt;/servlet&gt;
	&lt;servlet-mapping&gt;
		&lt;servlet-name&gt;spring&lt;/servlet-name&gt;
		&lt;url-pattern&gt;*.html&lt;/url-pattern&gt;
	&lt;/servlet-mapping&gt;
&lt;/web-app&gt;
</pre><p>Once the web.xml is configured, let us add spring-servlet.xml and jdbc.properties files in /src/main/webapp/WEB-INF folder.</p><p><em>File: /src/main/webapp/WEB-INF/jdbc.properties</em></p><pre class="brush: xml; title: ; notranslate">
jdbc.driverClassName= com.mysql.jdbc.Driver
jdbc.dialect=org.hibernate.dialect.MySQLDialect
jdbc.databaseurl=jdbc:mysql://localhost:3306/docdb
jdbc.username=root
jdbc.password=password
</pre><p>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.</p><p><em>File: /src/main/webapp/WEB-INF/spring-servlet.xml</em></p><pre class="brush: xml; title: ; notranslate">
&lt;?xml  version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;beans xmlns=&quot;http://www.springframework.org/schema/beans&quot;
	xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
	xmlns:aop=&quot;http://www.springframework.org/schema/aop&quot;
	xmlns:context=&quot;http://www.springframework.org/schema/context&quot;
	xmlns:jee=&quot;http://www.springframework.org/schema/jee&quot;
	xmlns:lang=&quot;http://www.springframework.org/schema/lang&quot;
	xmlns:p=&quot;http://www.springframework.org/schema/p&quot;
	xmlns:tx=&quot;http://www.springframework.org/schema/tx&quot;
	xmlns:util=&quot;http://www.springframework.org/schema/util&quot;
	xsi:schemaLocation=&quot;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&quot;&gt;

	&lt;context:annotation-config /&gt;
	&lt;context:component-scan base-package=&quot;net.viralpatel.docmanager&quot; /&gt;

	&lt;bean id=&quot;jspViewResolver&quot;
		class=&quot;org.springframework.web.servlet.view.InternalResourceViewResolver&quot;&gt;
		&lt;property name=&quot;viewClass&quot;
			value=&quot;org.springframework.web.servlet.view.JstlView&quot; /&gt;
		&lt;property name=&quot;prefix&quot; value=&quot;/WEB-INF/jsp/&quot; /&gt;
		&lt;property name=&quot;suffix&quot; value=&quot;.jsp&quot; /&gt;
	&lt;/bean&gt;

	&lt;bean id=&quot;propertyConfigurer&quot;
		class=&quot;org.springframework.beans.factory.config.PropertyPlaceholderConfigurer&quot;
		p:location=&quot;/WEB-INF/jdbc.properties&quot; /&gt;

	&lt;bean id=&quot;dataSource&quot;
		class=&quot;org.apache.commons.dbcp.BasicDataSource&quot; destroy-method=&quot;close&quot;
		p:driverClassName=&quot;${jdbc.driverClassName}&quot;
		p:url=&quot;${jdbc.databaseurl}&quot; p:username=&quot;${jdbc.username}&quot;
		p:password=&quot;${jdbc.password}&quot; /&gt;

	&lt;bean id=&quot;sessionFactory&quot;
		class=&quot;org.springframework.orm.hibernate3.LocalSessionFactoryBean&quot;&gt;
		&lt;property name=&quot;dataSource&quot; ref=&quot;dataSource&quot; /&gt;
		&lt;property name=&quot;configLocation&quot;&gt;
			&lt;value&gt;classpath:hibernate.cfg.xml&lt;/value&gt;
		&lt;/property&gt;
		&lt;property name=&quot;configurationClass&quot;&gt;
			&lt;value&gt;org.hibernate.cfg.AnnotationConfiguration&lt;/value&gt;
		&lt;/property&gt;
		&lt;property name=&quot;hibernateProperties&quot;&gt;
			&lt;props&gt;
				&lt;prop key=&quot;hibernate.dialect&quot;&gt;${jdbc.dialect}&lt;/prop&gt;
				&lt;prop key=&quot;hibernate.show_sql&quot;&gt;true&lt;/prop&gt;
				&lt;prop key=&quot;hibernate.connection.SetBigStringTryClob&quot;&gt;true&lt;/prop&gt;
				&lt;prop key=&quot;hibernate.jdbc.batch_size&quot;&gt;0&lt;/prop&gt;
			&lt;/props&gt;
		&lt;/property&gt;
	&lt;/bean&gt;
	&lt;bean id=&quot;multipartResolver&quot;
		class=&quot;org.springframework.web.multipart.commons.CommonsMultipartResolver&quot;&gt;

		&lt;!-- one of the properties available; the maximum file size in bytes --&gt;
		&lt;property name=&quot;maxUploadSize&quot; value=&quot;10000000&quot; /&gt;
	&lt;/bean&gt;
	&lt;tx:annotation-driven /&gt;

	&lt;bean id=&quot;transactionManager&quot;
		class=&quot;org.springframework.orm.hibernate3.HibernateTransactionManager&quot;&gt;
		&lt;property name=&quot;sessionFactory&quot; ref=&quot;sessionFactory&quot; /&gt;
	&lt;/bean&gt;
&lt;/beans&gt;
</pre><p>The spring-servlet.xml file contains different spring mappings such as transaction manager, hibernate session factory bean, data source etc.</p><ul><li><strong>jspViewResolver</strong> bean &ndash; This bean defined view resolver for spring mvc. For this bean we also set prefix as &#8220;/WEB-INF/jsp/&#8221; and suffix as &#8220;.jsp&#8221;. Thus spring automatically resolves the JSP from WEB-INF/jsp folder and assigned suffix .jsp to it.</li><li><strong>propertyConfigurer</strong> bean &ndash; This bean is used to load database property file jdbc.properties. The database connection details are stored in this file which is used in hibernate connection settings.</li><li><strong>dataSource</strong> bean &ndash; This is the java datasource used to connect to document manager database. We provide jdbc driver class, username, password etc in configuration.</li><li><strong>sessionFactory</strong> bean &ndash; This is Hibernate configuration where we define different hibernate settings. hibernate.cfg.xml is set a config file which contains entity class mappings. Also note that in sessionFactory we have specified few hibernate properties such as <code>hibernate.connection.SetBigStringTryClob</code> and <code>hibernate.jdbc.batch_size</code>. These are used to configure BLOB / CLOB settings in hibernate.</li><li><strong>multipartResolver</strong> bean &ndash; We use Spring MVCs CommonsMultipartResolver. This resolver will resolve multipart form data such as file uploads from the request and make available File object to spring controller. Note that we have specified property <code>maxUploadSize</code> with value 10000000. This is the maximum limit of filesize which can be uploaded in our example.</li><li><strong>transactionManager</strong> bean &ndash; We use hibernate transaction manager to manage the transactions of our document manager application.</li></ul><p><em>File: /src/main/resources/hibernate.cfg.xml</em></p><pre class="brush: xml; title: ; notranslate">
&lt;?xml version='1.0' encoding='utf-8'?&gt;
&lt;!DOCTYPE hibernate-configuration PUBLIC
    &quot;-//Hibernate/Hibernate Configuration DTD//EN&quot;
    &quot;http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd&quot;&gt;

&lt;hibernate-configuration&gt;
    &lt;session-factory&gt;
        &lt;mapping class=&quot;net.viralpatel.docmanager.model.Document&quot; /&gt;
    &lt;/session-factory&gt;

&lt;/hibernate-configuration&gt;
</pre><h2>The Controller &#8211; Spring MVC controller class</h2><p>We are almost done with our application. Just add following Spring controller class DocumentController.java to net.viralpatel.docmanager.controller package.</p><p><em>File: /src/main/java/net/viralpatel/docmanager/controller/DocumentController.java</em></p><pre class="brush: java; title: ; notranslate">
package 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(&quot;/index&quot;)
	public String index(Map&lt;String, Object&gt; map) {
		try {
			map.put(&quot;document&quot;, new Document());
			map.put(&quot;documentList&quot;, documentDao.list());
		}catch(Exception e) {
			e.printStackTrace();
		}

		return &quot;documents&quot;;
	}

	@RequestMapping(value = &quot;/save&quot;, method = RequestMethod.POST)
	public String save(
			@ModelAttribute(&quot;document&quot;) Document document,
			@RequestParam(&quot;file&quot;) MultipartFile file) {

		System.out.println(&quot;Name:&quot; + document.getName());
		System.out.println(&quot;Desc:&quot; + document.getDescription());
		System.out.println(&quot;File:&quot; + file.getName());
		System.out.println(&quot;ContentType:&quot; + 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 &quot;redirect:/index.html&quot;;
	}

	@RequestMapping(&quot;/download/{documentId}&quot;)
	public String download(@PathVariable(&quot;documentId&quot;)
			Integer documentId, HttpServletResponse response) {

		Document doc = documentDao.get(documentId);
		try {
			response.setHeader(&quot;Content-Disposition&quot;, &quot;inline;filename=\&quot;&quot; +doc.getFilename()+ &quot;\&quot;&quot;);
			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(&quot;/remove/{documentId}&quot;)
	public String remove(@PathVariable(&quot;documentId&quot;)
			Integer documentId) {

		documentDao.remove(documentId);

		return &quot;redirect:/index.html&quot;;
	}
}
</pre><p>The spring controller defines four methods to manipulate document manager application.</p><ul><li><b>index</b> method &#8211; This method uses list() method of DocumentDAO to fetch the list of all documents from database. Note that we have mapped request &#8220;/index&#8221; to this method. Thus Spring will automatically calls this method whenever it encounters this url in request.</li><li><b>save</b> method &#8211; This method adds a new document to document list. The document details are fetched in Document object using <code>@ModelAttribute</code> annotation. Also note that the request &#8220;/save&#8221; is mapped with this method. The request method should also be POST. Once the document is added in document list, we redirect to /index.html page which in turn calls index() method to display document list to user. One more thing to note here is <code>@RequestParam</code>. We are mapping MultipartFile object using @RequestParam(&#8220;file&#8221;) annotation. Spring automatically detects &#8220;file&#8221; data from request and map it with MultipartFile object. This object is later converted to BLOB object and set in the Document content.<br /> <br/><br /> <strong>Related:</strong> <a href="http://viralpatel.net/blogs/2010/07/spring-3-mvc-handling-forms.html">Forms in Spring MVC</a></li><li><b>download</b> method &#8211; This method is used to download a selected testcase. Note that we are fetching the document content from database using DAO class and thn set the Data stream in Response. Also note that we are using <code>response.setHeader()</code> method to set <code>"Content-Disposition"</code>. This will raise a Save As dialog box in browser whenever user tries to download a document.</li><li><b>remove</b> method &#8211; This methods removes a document from the document list. Similar to save() this method also redirects user to /index.html page once the document is removed. One thing to note in this method is the way we have mapped request url using @RequestMapping annotation. The url &#8220;/remove/{documentId}” is mapped thus whenever user send a request /remove/12.html, the remove method will try to delete document with ID:12.</li></ul><p>Finally add following JSP file to WEB-INF/jsp folder.<br /> <em>File: /src/main/webapp/WEB-INF/jsp/documents.jsp</em></p><pre class="brush: xml; title: ; notranslate">
&lt;%@taglib uri=&quot;http://www.springframework.org/tags&quot; prefix=&quot;spring&quot;%&gt;
&lt;%@taglib uri=&quot;http://www.springframework.org/tags/form&quot; prefix=&quot;form&quot;%&gt;
&lt;%@taglib uri=&quot;http://java.sun.com/jsp/jstl/core&quot; prefix=&quot;c&quot;%&gt;
&lt;html&gt;
&lt;head&gt;
	&lt;title&gt;Document Manager - viralpatel.net&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;

&lt;h2&gt;Document Manager&lt;/h2&gt;

&lt;h3&gt;Add new document&lt;/h3&gt;
&lt;form:form method=&quot;post&quot; action=&quot;save.html&quot; commandName=&quot;document&quot; enctype=&quot;multipart/form-data&quot;&gt;
	&lt;form:errors path=&quot;*&quot; cssClass=&quot;error&quot;/&gt;
	&lt;table&gt;
	&lt;tr&gt;
		&lt;td&gt;&lt;form:label path=&quot;name&quot;&gt;Name&lt;/form:label&gt;&lt;/td&gt;
		&lt;td&gt;&lt;form:input path=&quot;name&quot; /&gt;&lt;/td&gt;
	&lt;/tr&gt;
	&lt;tr&gt;
		&lt;td&gt;&lt;form:label path=&quot;description&quot;&gt;Description&lt;/form:label&gt;&lt;/td&gt;
		&lt;td&gt;&lt;form:textarea path=&quot;description&quot; /&gt;&lt;/td&gt;
	&lt;/tr&gt;
	&lt;tr&gt;
		&lt;td&gt;&lt;form:label path=&quot;content&quot;&gt;Document&lt;/form:label&gt;&lt;/td&gt;
		&lt;td&gt;&lt;input type=&quot;file&quot; name=&quot;file&quot; id=&quot;file&quot;&gt;&lt;/input&gt;&lt;/td&gt;
	&lt;/tr&gt;
	&lt;tr&gt;
		&lt;td colspan=&quot;2&quot;&gt;
			&lt;input type=&quot;submit&quot; value=&quot;Add Document&quot;/&gt;
		&lt;/td&gt;
	&lt;/tr&gt;
&lt;/table&gt;
&lt;/form:form&gt;

&lt;br/&gt;
&lt;h3&gt;Document List&lt;/h3&gt;
&lt;c:if  test=&quot;${!empty documentList}&quot;&gt;
&lt;table class=&quot;data&quot;&gt;
&lt;tr&gt;
	&lt;th&gt;Name&lt;/th&gt;
	&lt;th&gt;Description&lt;/th&gt;
	&lt;th&gt;&amp;nbsp;&lt;/th&gt;
&lt;/tr&gt;
&lt;c:forEach items=&quot;${documentList}&quot; var=&quot;document&quot;&gt;
	&lt;tr&gt;
		&lt;td width=&quot;100px&quot;&gt;${document.name}&lt;/td&gt;
		&lt;td width=&quot;250px&quot;&gt;${document.description}&lt;/td&gt;
		&lt;td width=&quot;20px&quot;&gt;
			&lt;a href=&quot;${pageContext.request.contextPath}/download/${document.id}.html&quot;&gt;&lt;img
				src=&quot;${pageContext.request.contextPath}/img/save_icon.gif&quot; border=&quot;0&quot;
				title=&quot;Download this document&quot;/&gt;&lt;/a&gt; 

			&lt;a href=&quot;${pageContext.request.contextPath}/remove/${document.id}.html&quot;
				onclick=&quot;return confirm('Are you sure you want to delete this document?')&quot;&gt;&lt;img
				src=&quot;${pageContext.request.contextPath}/img/delete_icon.gif&quot; border=&quot;0&quot;
				title=&quot;Delete this document&quot;/&gt;&lt;/a&gt;
		&lt;/td&gt;
	&lt;/tr&gt;
&lt;/c:forEach&gt;
&lt;/table&gt;
&lt;/c:if&gt;
&lt;/body&gt;
&lt;/html&gt;
</pre><h2>Download Source code</h2><p><a href="http://viralpatel.net/blogs/download/spring/spring-3-mvc-series/DocumentManager.zip">Click here to download full source code of Document manager application (16 KB)</a></p><h2>That’s All folks</h2><p>Compile and execute the Document manager application in Eclipse. Open URL <em>http://localhost:8080/DocumentManager/index.html</em><br /> <img src="http://img.viralpatel.net/2011/01/document-manager-hibernate-spring-blob.png" alt="document-manager-hibernate-spring-blob" title="document-manager-hibernate-spring-blob" width="451" height="358" class="aligncenter size-full wp-image-2131" /></p><div id="relatedpost"><h2  class="related_post_title">Related Posts</h2><ul class="related_post"><li><a href="http://viralpatel.net/blogs/2010/11/spring3-mvc-hibernate-maven-tutorial-eclipse-example.html" title="Tutorial:Create Spring 3 MVC Hibernate 3 Example using Maven in Eclipse">Tutorial:Create Spring 3 MVC Hibernate 3 Example using Maven in Eclipse</a></li><li><a href="http://viralpatel.net/blogs/2011/12/hibernate-many-to-many-annotation-mapping-tutorial.html" title="Hibernate Many To Many Annotation Mapping Tutorial">Hibernate Many To Many Annotation Mapping Tutorial</a></li><li><a href="http://viralpatel.net/blogs/2011/12/hibernate-many-to-many-xml-mapping-example.html" title="Hibernate Many To Many XML Mapping Tutorial">Hibernate Many To Many XML Mapping Tutorial</a></li><li><a href="http://viralpatel.net/blogs/2011/12/hibernate-one-to-many-xml-mapping-tutorial.html" title="Hibernate One To Many XML Mapping Tutorial">Hibernate One To Many XML Mapping Tutorial</a></li><li><a href="http://viralpatel.net/blogs/2214/hibernate-one-to-one-mapping-tutorial-using-annotation" title="Hibernate One To One Annotation Mapping Tutorial">Hibernate One To One Annotation Mapping Tutorial</a></li><li><a href="http://viralpatel.net/blogs/2205/change-spring-servlet-filename-configuration" title="Change spring-servlet.xml Filename (Spring Web Contenxt Configuration Filename)">Change spring-servlet.xml Filename (Spring Web Contenxt Configuration Filename)</a></li><li><a href="http://viralpatel.net/blogs/2011/11/hibernate-one-to-one-mapping-tutorial-xml-mapping.html" title="Hibernate One To One Mapping Tutorial (XML Mapping)">Hibernate One To One Mapping Tutorial (XML Mapping)</a></li></ul></div>]]></content:encoded> <wfw:commentRss>http://viralpatel.net/blogs/2011/01/tutorial-save-get-blob-object-spring-3-mvc-hibernate.html/feed</wfw:commentRss> <slash:comments>16</slash:comments> </item> <item><title>Tutorial:Create Spring 3 MVC Hibernate 3 Example using Maven in Eclipse</title><link>http://viralpatel.net/blogs/2010/11/spring3-mvc-hibernate-maven-tutorial-eclipse-example.html</link> <comments>http://viralpatel.net/blogs/2010/11/spring3-mvc-hibernate-maven-tutorial-eclipse-example.html#comments</comments> <pubDate>Wed, 10 Nov 2010 10:25:52 +0000</pubDate> <dc:creator>Viral Patel</dc:creator> <category><![CDATA[Featured]]></category> <category><![CDATA[Hibernate]]></category> <category><![CDATA[Spring 3 MVC]]></category> <category><![CDATA[MySQL]]></category> <category><![CDATA[Spring]]></category> <category><![CDATA[spring mvc]]></category> <category><![CDATA[spring-3-mvc-series]]></category><guid isPermaLink="false">http://viralpatel.net/blogs/?p=2052</guid> <description><![CDATA[Let us make a complete end-to-end application using Spring 3.0 MVC as front end technology and Hibernate as backend ORM technology. For this application we will also use Maven for build and dependency management and MySQL as database to persist the data. The application will be a simple Contact Manager app which will allow user [...]]]></description> <content:encoded><![CDATA[<p>Let us make a complete end-to-end application using Spring 3.0 MVC as front end technology and Hibernate as backend ORM technology. For this application we will also use Maven for build and dependency management and MySQL as database to persist the data.</p><p>The application will be a simple Contact Manager app which will allow user to add new contacts. The list of contacts will be displayed and user will be able to delete existing contacts.<br /><style type="text/css">#spring{color:#222;width:98%;background-color:#EF9;padding:5px;-moz-border-radius:10px;-webkit-border-radius:10px}#spring
h3{font-size:18px;text-decoration:underline}#spring
ul{list-style:none}#spring ul
li{padding:3px}</style><div id="spring"><h3>Spring 3.0 MVC Series</h3><ul><li><a href="http://viralpatel.net/blogs/2010/06/tutorial-spring-3-mvc-introduction-spring-mvc-framework.html">Part 1: Introduction to Spring 3.0 MVC framework</a></li><li><a href="http://viralpatel.net/blogs/2010/06/spring-3-mvc-create-hello-world-application-spring-3-mvc.html">Part 2: Create Hello World Application in Spring 3.0 MVC</a></li><li><a href="http://viralpatel.net/blogs/2010/07/spring-3-mvc-handling-forms.html">Part 3: Handling Forms in Spring 3.0 MVC</a></li><li><a href="http://viralpatel.net/blogs/2010/07/spring-3-mvc-tiles-plugin-tutorial-example-eclipse.html">Part 4: Spring 3 MVC Tiles Plugin Tutorial with Example in Eclipse</a></li><li><a href="http://viralpatel.net/blogs/2010/07/spring-3-mvc-internationalization-i18n-localization-tutorial-example.html">Part 5: Spring 3 MVC Internationalization & Localization Tutorial with Example in Eclipse</a></li><li><a href="http://viralpatel.net/blogs/2010/10/spring-3-mvc-themes-tutorial-example.html">Part 6: Spring 3 MVC Themes in Spring-Tutorial with Example</a></li><li><a href="http://viralpatel.net/blogs/2010/11/spring3-mvc-hibernate-maven-tutorial-eclipse-example.html">Part 7: Create Spring 3 MVC Hibernate 3 Example using Maven in Eclipse</a></li></ul></div></p><h2>Our Goal</h2><p>As describe above, our goal is to create a contact manager application which will allow the user to add a contact or remove it. The basic requirement of the Contact Manager app will be:</p><ol><li>Add new contact in the contact list.</li><li>Display all contacts from contact list.</li><li>Delete a contact from contact list.</li></ol><p>Following is the screenshot of end application.<br /> <img src="http://img.viralpatel.net/2010/10/spring3-hibernate-contact-manager.png" alt="spring3-hibernate-contact-manager" title="spring3-hibernate-contact-manager" width="423" height="475" class="aligncenter size-full wp-image-2108" /></p><h2>Application Architecture</h2><p>We will have a layered architecture for our demo application. The database will be accessed by a Data Access layer popularly called as DAO Layer. This layer will use Hibernate API to interact with database. The DAO layer will be invoked by a service layer. In our application we will have a Service interface called ContactService.<br /> <img src="http://img.viralpatel.net/2010/10/spring3-hibernate-application-architecture.png" alt="spring3-hibernate-application-architecture" title="spring3-hibernate-application-architecture" width="396" height="340" class="aligncenter size-full wp-image-2109" /></p><h2>Getting Started</h2><p>For our Contact Manager example, we will use MySQL database. Create a table contacts  in any MySQL database. This is very preliminary example and thus we have minimum columns to represent a contact. Feel free to extend this example and create a more complex application.</p><pre class="brush: sql; title: ; notranslate">
CREATE TABLE CONTACTS
(
    id              INT PRIMARY KEY AUTO_INCREMENT,
    firstname    VARCHAR(30),
    lastname    VARCHAR(30),
    telephone   VARCHAR(15),
    email         VARCHAR(30),
    created     TIMESTAMP DEFAULT NOW()
);
</pre><h2>Creating Project in Eclipse</h2><p>The contact manager application will use Maven for build and dependency management. For this we will use the <a href="http://viralpatel.net/blogs/2010/07/generate-dynamic-web-project-maven-eclipse-wtp.html" target="_blank">Maven Dynamic Web Project in Eclipse</a> as the base architecture of our application.</p><p>Download the below source code:<br /> <a href="http://viralpatel.net/blogs/download/j2ee/maven/MavenWeb.zip"><strong>Maven Dynamic Web Project</strong> (6.7 KB)</a></p><p><img src="http://img.viralpatel.net/2010/10/spring3-hibernate-project-structure.png" alt="spring3-hibernate-project-structure" title="spring3-hibernate-project-structure" width="259" height="493" class="alignright size-full wp-image-2111" />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. Create following packages under <strong>src/main/java</strong> folder.</p><ul><li><em>net.viralpatel.contact.controller</em> &#8211; This package will contain Spring Controller classes for Contact Manager application.</li><li><em>net.viralpatel.contact.form</em> &#8211; This package will contain form object for Contact manager application. Contact form will be a simple POJO class with different attributes such as firstname, lastname etc.</li><li><em>net.viralpatel.contact.service</em> &#8211; This package will contain code for service layer for our Contact manager application. The service layer will have one ContactService interface and its corresponding implementation class</li><li><em>net.viralpatel.contact.dao</em> &#8211; This is the DAO layer of Contact manager application. It consists of ContactDAO interface and its corresponding implementation class. The DAO layer will use Hibernate API to interact with database.</li></ul><h3>Entity Class &#8211; The Hibernate domain class</h3><p>Let us start with the coding of Contact manager application. First we will create a form object or hibernate POJO class to store contact information. Also this class will be an Entity class and will be linked with CONTACTS table in database.<br /> Create a java class Contact.java under net.viralpatel.contact.form package and copy following code into it.</p><p><i>File: src/main/java/net/viralpatel/contact/form/Contact.java</i></p><pre class="brush: java; title: ; notranslate">
package net.viralpatel.contact.form;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name=&quot;CONTACTS&quot;)
public class Contact {

    @Id
    @Column(name=&quot;ID&quot;)
    @GeneratedValue
    private Integer id;

    @Column(name=&quot;FIRSTNAME&quot;)
    private String firstname;

    @Column(name=&quot;LASTNAME&quot;)
    private String lastname;

    @Column(name=&quot;EMAIL&quot;)
    private String email;

    @Column(name=&quot;TELEPHONE&quot;)
    private String telephone;

    public String getEmail() {
        return email;
    }
    public String getTelephone() {
        return telephone;
    }
    public void setEmail(String email) {
        this.email = email;
    }
    public void setTelephone(String telephone) {
        this.telephone = telephone;
    }
    public String getFirstname() {
        return firstname;
    }
    public String getLastname() {
        return lastname;
    }
    public void setFirstname(String firstname) {
        this.firstname = firstname;
    }
    public void setLastname(String lastname) {
        this.lastname = lastname;
    }
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
}
</pre><p>The first thing you’ll 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 that’s what I’m using here.</p><ul><li>First we’ve annotated the class with <code>@Entity</code> which tells Hibernate that this class represents an object that we can persist.</li><li>The <code>@Table(name = "CONTACTS")</code> annotation tells Hibernate which table to map properties in this class to. The first property in this class on line 16 is our object ID which will be unique for all events persisted.  This is why we’ve annotated it with <code>@Id</code>.</li><li>The <code>@GeneratedValue</code> annotation says that this value will be determined by the datasource, not by the code.</li><li>The <code>@Column(name = "FIRSTNAME")</code> annotation is used to map this property to the FIRSTNAME column in the CONTACTS table.</li></ul><h3>The Data Access (DAO) Layer</h3><p>The DAO layer of Contact Manager application consist of an interface <code>ContactDAO</code> and its corresponding implementation class <code>ContactDAOImpl</code>. Create following Java files in <code>net.viralpatel.contact.dao</code> package.</p><p><i>File: src/main/java/net/viralpatel/contact/dao/ContactDAO.java</i></p><pre class="brush: java; title: ; notranslate">
package net.viralpatel.contact.dao;

import java.util.List;

import net.viralpatel.contact.form.Contact;

public interface ContactDAO {

    public void addContact(Contact contact);
    public List&lt;Contact&gt; listContact();
    public void removeContact(Integer id);
}
</pre><p><i>File: src/main/java/net/viralpatel/contact/dao/ContactDAOImpl.java</i></p><pre class="brush: java; title: ; notranslate">
package net.viralpatel.contact.dao;

import java.util.List;

import net.viralpatel.contact.form.Contact;

import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

@Repository
public class ContactDAOImpl implements ContactDAO {

    @Autowired
    private SessionFactory sessionFactory;

    public void addContact(Contact contact) {
        sessionFactory.getCurrentSession().save(contact);
    }

    public List&lt;Contact&gt; listContact() {

        return sessionFactory.getCurrentSession().createQuery(&quot;from Contact&quot;)
                .list();
    }

    public void removeContact(Integer id) {
        Contact contact = (Contact) sessionFactory.getCurrentSession().load(
                Contact.class, id);
        if (null != contact) {
            sessionFactory.getCurrentSession().delete(contact);
        }

    }
}
</pre><p>The DAO class in above code <code>ContactDAOImpl</code> implements the data access interface <code>ContactDAO</code> which defines methods such as <code>listContact()</code>, <code>addContact()</code> etc to access data from database.</p><p>Note that we have used two Spring annotations <code>@Repository</code> and <code>@Autowired</code>.</p><p>Classes marked with annotations are candidates for auto-detection by Spring when using annotation-based configuration and classpath scanning. The <code>@Component</code> annotation is the main stereotype that indicates that an annotated class is a &#8220;component&#8221;.</p><p>The <code>@Repository</code> annotation is yet another stereotype that was introduced in Spring 2.0. This annotation is used to indicate that a class functions as a repository and needs to have exception translation applied transparently on it. The benefit of exception translation is that the service layer only has to deal with exceptions from Spring&#8217;s DataAccessException hierarchy, even when using plain JPA in the DAO classes.</p><p>Another annotation used in ContactDAOImpl is <code>@Autowired</code>. This is used to autowire the dependency of the ContactDAOImpl on the SessionFactory.</p><h3>The Service Layer</h3><p>The Service layer of Contact Manager application consist of an interface ContactService and its corresponding implementation class ContactServiceImpl. Create following Java files in <code>net.viralpatel.contact.service</code> package.</p><p><i>File: src/main/java/net/viralpatel/contact/service/ContactService.java</i></p><pre class="brush: java; title: ; notranslate">
package net.viralpatel.contact.service;

import java.util.List;

import net.viralpatel.contact.form.Contact;

public interface ContactService {

    public void addContact(Contact contact);
    public List&lt;Contact&gt; listContact();
    public void removeContact(Integer id);
}
</pre><p><i>File: src/main/java/net/viralpatel/contact/service/ContactServiceImpl.java</i></p><pre class="brush: java; title: ; notranslate">
package net.viralpatel.contact.service;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import net.viralpatel.contact.dao.ContactDAO;
import net.viralpatel.contact.form.Contact;

@Service
public class ContactServiceImpl implements ContactService {

    @Autowired
    private ContactDAO contactDAO;

    @Transactional
    public void addContact(Contact contact) {
        contactDAO.addContact(contact);
    }

    @Transactional
    public List&lt;Contact&gt; listContact() {

        return contactDAO.listContact();
    }

    @Transactional
    public void removeContact(Integer id) {
        contactDAO.removeContact(id);
    }
}
</pre><p>In above service layer code, we have created an interface <code>ContactService</code> and implemented it in class <code>ContactServiceImpl</code>. Note that we used few Spring annotations such as <code>@Service</code>, <code>@Autowired</code> and <code>@Transactional</code> in our code. These annotations are called Spring stereotype annotations.</p><p>The <code>@Service</code> stereotype annotation used to decorate the ContactServiceImpl class is a specialized form of the <code>@Component</code> annotation. It is appropriate to annotate the service-layer classes with <code>@Service</code> to facilitate processing by tools or anticipating any future service-specific capabilities that may be added to this annotation.</p><h2>Adding Spring MVC Support</h2><p>Let us add Spring MVC support to our web application.</p><p>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.</p><p><em>File: /src/webapp/WEB-INF/web.xml</em></p><pre class="brush: xml; title: ; notranslate">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;web-app xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
	xmlns=&quot;http://java.sun.com/xml/ns/javaee&quot;
	xmlns:web=&quot;http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd&quot;
	xsi:schemaLocation=&quot;http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd&quot;
	id=&quot;WebApp_ID&quot; version=&quot;2.5&quot;&gt;
	&lt;display-name&gt;Spring3-Hibernate&lt;/display-name&gt;
	&lt;welcome-file-list&gt;
		&lt;welcome-file&gt;list.html&lt;/welcome-file&gt;
	&lt;/welcome-file-list&gt;
	&lt;servlet&gt;
		&lt;servlet-name&gt;spring&lt;/servlet-name&gt;
		&lt;servlet-class&gt;
			org.springframework.web.servlet.DispatcherServlet
		&lt;/servlet-class&gt;
		&lt;load-on-startup&gt;1&lt;/load-on-startup&gt;
	&lt;/servlet&gt;
	&lt;servlet-mapping&gt;
		&lt;servlet-name&gt;spring&lt;/servlet-name&gt;
		&lt;url-pattern&gt;/&lt;/url-pattern&gt;
	&lt;/servlet-mapping&gt;
&lt;/web-app&gt;
</pre><p>Once the web.xml is configured, let us add spring-servlet.xml and jdbc.properties files in /src/main/webapp/WEB-INF folder.<br /> <em>File: /src/main/webapp/WEB-INF/jdbc.properties</em></p><pre class="brush: xml; title: ; notranslate">
jdbc.driverClassName= com.mysql.jdbc.Driver
jdbc.dialect=org.hibernate.dialect.MySQLDialect
jdbc.databaseurl=jdbc:mysql://localhost:3306/ContactManager
jdbc.username=root
jdbc.password=testpass
</pre><p>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.</p><p><em>File: /src/main/webapp/WEB-INF/spring-servlet.xml</em></p><pre class="brush: xml; title: ; notranslate">
&lt;?xml  version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;beans xmlns=&quot;http://www.springframework.org/schema/beans&quot;
	xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
	xmlns:aop=&quot;http://www.springframework.org/schema/aop&quot;
	xmlns:context=&quot;http://www.springframework.org/schema/context&quot;
	xmlns:jee=&quot;http://www.springframework.org/schema/jee&quot;
	xmlns:lang=&quot;http://www.springframework.org/schema/lang&quot;
	xmlns:p=&quot;http://www.springframework.org/schema/p&quot;
	xmlns:tx=&quot;http://www.springframework.org/schema/tx&quot;
	xmlns:util=&quot;http://www.springframework.org/schema/util&quot;
	xsi:schemaLocation=&quot;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&quot;&gt;

	&lt;context:annotation-config /&gt;
	&lt;context:component-scan base-package=&quot;net.viralpatel.contact&quot; /&gt;

	&lt;bean id=&quot;jspViewResolver&quot;
		class=&quot;org.springframework.web.servlet.view.InternalResourceViewResolver&quot;&gt;
		&lt;property name=&quot;viewClass&quot;
			value=&quot;org.springframework.web.servlet.view.JstlView&quot; /&gt;
		&lt;property name=&quot;prefix&quot; value=&quot;/WEB-INF/jsp/&quot; /&gt;
		&lt;property name=&quot;suffix&quot; value=&quot;.jsp&quot; /&gt;
	&lt;/bean&gt;

	&lt;bean id=&quot;messageSource&quot;
		class=&quot;org.springframework.context.support.ReloadableResourceBundleMessageSource&quot;&gt;
		&lt;property name=&quot;basename&quot; value=&quot;classpath:messages&quot; /&gt;
		&lt;property name=&quot;defaultEncoding&quot; value=&quot;UTF-8&quot; /&gt;
	&lt;/bean&gt;
	&lt;bean id=&quot;propertyConfigurer&quot;
		class=&quot;org.springframework.beans.factory.config.PropertyPlaceholderConfigurer&quot;
		p:location=&quot;/WEB-INF/jdbc.properties&quot; /&gt;

	&lt;bean id=&quot;dataSource&quot;
		class=&quot;org.apache.commons.dbcp.BasicDataSource&quot; destroy-method=&quot;close&quot;
		p:driverClassName=&quot;${jdbc.driverClassName}&quot;
		p:url=&quot;${jdbc.databaseurl}&quot; p:username=&quot;${jdbc.username}&quot;
		p:password=&quot;${jdbc.password}&quot; /&gt;

	&lt;bean id=&quot;sessionFactory&quot;
		class=&quot;org.springframework.orm.hibernate3.LocalSessionFactoryBean&quot;&gt;
		&lt;property name=&quot;dataSource&quot; ref=&quot;dataSource&quot; /&gt;
		&lt;property name=&quot;configLocation&quot;&gt;
			&lt;value&gt;classpath:hibernate.cfg.xml&lt;/value&gt;
		&lt;/property&gt;
		&lt;property name=&quot;configurationClass&quot;&gt;
			&lt;value&gt;org.hibernate.cfg.AnnotationConfiguration&lt;/value&gt;
		&lt;/property&gt;
		&lt;property name=&quot;hibernateProperties&quot;&gt;
			&lt;props&gt;
				&lt;prop key=&quot;hibernate.dialect&quot;&gt;${jdbc.dialect}&lt;/prop&gt;
				&lt;prop key=&quot;hibernate.show_sql&quot;&gt;true&lt;/prop&gt;
			&lt;/props&gt;
		&lt;/property&gt;
	&lt;/bean&gt;

	&lt;tx:annotation-driven /&gt;
	&lt;bean id=&quot;transactionManager&quot;
		class=&quot;org.springframework.orm.hibernate3.HibernateTransactionManager&quot;&gt;
		&lt;property name=&quot;sessionFactory&quot; ref=&quot;sessionFactory&quot; /&gt;
	&lt;/bean&gt;
&lt;/beans&gt;
</pre><p>The spring-servlet.xml file contains different spring mappings such as transaction manager, hibernate session factory bean, data source etc.</p><ul><li><strong>jspViewResolver</strong> bean &#8211; This bean defined view resolver for spring mvc. For this bean we also set prefix as &#8220;/WEB-INF/jsp/&#8221; and suffix as &#8220;.jsp&#8221;. Thus spring automatically resolves the JSP from WEB-INF/jsp folder and assigned suffix .jsp to it.</li><li><strong>messageSource</strong> bean &#8211; To provide Internationalization to our demo application, we defined bundle resource property file called messages.properties in classpath. <br/><strong>Related:</strong> <a target="_blank" href="http://viralpatel.net/blogs/2010/07/spring-3-mvc-internationalization-i18n-localization-tutorial-example.html">Internationalization in Spring MVC</a></li><li><strong>propertyConfigurer</strong> bean &#8211; This bean is used to load database property file jdbc.properties. The database connection details are stored in this file which is used in hibernate connection settings.</li><li><strong>dataSource</strong> bean &#8211; This is the java datasource used to connect to contact manager database. We provide jdbc driver class, username, password etc in configuration.</li><li><strong>sessionFactory</strong> bean &#8211; This is Hibernate configuration where we define different hibernate settings. hibernate.cfg.xml is set a config file which contains entity class mappings</li><li><strong>transactionManager</strong> bean &#8211; We use hibernate transaction manager to manage the transactions of our contact manager application.</li></ul><p><em>File: /src/main/resources/hibernate.cfg.xml</em></p><pre class="brush: xml; title: ; notranslate">
&lt;?xml version='1.0' encoding='utf-8'?&gt;
&lt;!DOCTYPE hibernate-configuration PUBLIC
    &quot;-//Hibernate/Hibernate Configuration DTD//EN&quot;
    &quot;http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd&quot;&gt;

&lt;hibernate-configuration&gt;
    &lt;session-factory&gt;
        &lt;mapping class=&quot;net.viralpatel.contact.form.Contact&quot; /&gt;
    &lt;/session-factory&gt;

&lt;/hibernate-configuration&gt;
</pre><p><em>File: /src/main/resources/messages_en.properties</em></p><pre class="brush: xml; title: ; notranslate">
label.firstname=First Name
label.lastname=Last Name
label.email=Email
label.telephone=Telephone
label.addcontact=Add Contact

label.menu=Menu
label.title=Contact Manager
label.footer=&amp;copy; ViralPatel.net
</pre><h2>Spring MVC Controller</h2><p>We are almost done with our application. Just add following Spring controller class ContactController.java to net.viralpatel.contact.controller package.</p><p><em>File: /src/main/java/net/viralpatel/contact/controller/ContactController.java</em></p><pre class="brush: java; title: ; notranslate">
package net.viralpatel.contact.controller;

import java.util.Map;

import net.viralpatel.contact.form.Contact;
import net.viralpatel.contact.service.ContactService;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
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;

@Controller
public class ContactController {

	@Autowired
	private ContactService contactService;

	@RequestMapping(&quot;/index&quot;)
	public String listContacts(Map&lt;String, Object&gt; map) {

		map.put(&quot;contact&quot;, new Contact());
		map.put(&quot;contactList&quot;, contactService.listContact());

		return &quot;contact&quot;;
	}

	@RequestMapping(value = &quot;/add&quot;, method = RequestMethod.POST)
	public String addContact(@ModelAttribute(&quot;contact&quot;)
	Contact contact, BindingResult result) {

		contactService.addContact(contact);

		return &quot;redirect:/index&quot;;
	}

	@RequestMapping(&quot;/delete/{contactId}&quot;)
	public String deleteContact(@PathVariable(&quot;contactId&quot;)
	Integer contactId) {

		contactService.removeContact(contactId);

		return &quot;redirect:/index&quot;;
	}
}
</pre><p>The spring controller defines three methods to manipulate contact manager application.</p><ul><li><strong>listContacts</strong> method &#8211; This method uses Service interface ContactServer to fetch all the contact details in our application. It returns an array of contacts. Note that we have mapped request &#8220;/index&#8221; to this method. Thus Spring will automatically calls this method whenever it encounters this url in request.</li><li><strong>addContact</strong> method &#8211; This method adds a new contact to contact list. The contact details are fetched in <code>Contact</code> object using <code>@ModelAttribute</code> annotation. Also note that the request &#8220;/add&#8221; is mapped with this method. The request method should also be POST. Once the contact is added in contact list using <code>ContactService</code>, we redirect to /index page which in turn calls <code>listContacts()</code> method to display contact list to user. <br/> Related: <a target="_blank" href="http://viralpatel.net/blogs/2010/07/spring-3-mvc-handling-forms.html">Forms in Spring MVC</a></li><li><strong>deleteContact</strong> method &#8211; This methods removes a contact from the contact list. Similar to <code>addContact</code> this method also redirects user to /index page once the contact is removed. One this to note in this method is the way we have mapped request url using @RequestMapping annotation. The url &#8220;/delete/{contactId}&#8221; is mapped thus whenever user send a request /delete/12, the deleteCotact method will try to delete contact with ID:12.</li></ul><p>Finally add following JSP file to WEB-INF/jsp folder.</p><p><em>File: /src/main/webapp/WEB-INF/jsp/contact.jsp</em></p><pre class="brush: xml; title: ; notranslate">
&lt;%@taglib uri=&quot;http://www.springframework.org/tags&quot; prefix=&quot;spring&quot;%&gt;
&lt;%@taglib uri=&quot;http://www.springframework.org/tags/form&quot; prefix=&quot;form&quot;%&gt;
&lt;%@taglib uri=&quot;http://java.sun.com/jsp/jstl/core&quot; prefix=&quot;c&quot;%&gt;
&lt;html&gt;
&lt;head&gt;
	&lt;title&gt;Spring 3 MVC Series - Contact Manager | viralpatel.net&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;

&lt;h2&gt;Contact Manager&lt;/h2&gt;

&lt;form:form method=&quot;post&quot; action=&quot;add.html&quot; commandName=&quot;contact&quot;&gt;

	&lt;table&gt;
	&lt;tr&gt;
		&lt;td&gt;&lt;form:label path=&quot;firstname&quot;&gt;&lt;spring:message code=&quot;label.firstname&quot;/&gt;&lt;/form:label&gt;&lt;/td&gt;
		&lt;td&gt;&lt;form:input path=&quot;firstname&quot; /&gt;&lt;/td&gt;
	&lt;/tr&gt;
	&lt;tr&gt;
		&lt;td&gt;&lt;form:label path=&quot;lastname&quot;&gt;&lt;spring:message code=&quot;label.lastname&quot;/&gt;&lt;/form:label&gt;&lt;/td&gt;
		&lt;td&gt;&lt;form:input path=&quot;lastname&quot; /&gt;&lt;/td&gt;
	&lt;/tr&gt;
	&lt;tr&gt;
		&lt;td&gt;&lt;form:label path=&quot;email&quot;&gt;&lt;spring:message code=&quot;label.email&quot;/&gt;&lt;/form:label&gt;&lt;/td&gt;
		&lt;td&gt;&lt;form:input path=&quot;email&quot; /&gt;&lt;/td&gt;
	&lt;/tr&gt;
	&lt;tr&gt;
		&lt;td&gt;&lt;form:label path=&quot;telephone&quot;&gt;&lt;spring:message code=&quot;label.telephone&quot;/&gt;&lt;/form:label&gt;&lt;/td&gt;
		&lt;td&gt;&lt;form:input path=&quot;telephone&quot; /&gt;&lt;/td&gt;
	&lt;/tr&gt;
	&lt;tr&gt;
		&lt;td colspan=&quot;2&quot;&gt;
			&lt;input type=&quot;submit&quot; value=&quot;&lt;spring:message code=&quot;label.addcontact&quot;/&gt;&quot;/&gt;
		&lt;/td&gt;
	&lt;/tr&gt;
&lt;/table&gt;
&lt;/form:form&gt;

&lt;h3&gt;Contacts&lt;/h3&gt;
&lt;c:if  test=&quot;${!empty contactList}&quot;&gt;
&lt;table class=&quot;data&quot;&gt;
&lt;tr&gt;
	&lt;th&gt;Name&lt;/th&gt;
	&lt;th&gt;Email&lt;/th&gt;
	&lt;th&gt;Telephone&lt;/th&gt;
	&lt;th&gt;&amp;nbsp;&lt;/th&gt;
&lt;/tr&gt;
&lt;c:forEach items=&quot;${contactList}&quot; var=&quot;contact&quot;&gt;
	&lt;tr&gt;
		&lt;td&gt;${contact.lastname}, ${contact.firstname} &lt;/td&gt;
		&lt;td&gt;${contact.email}&lt;/td&gt;
		&lt;td&gt;${contact.telephone}&lt;/td&gt;
		&lt;td&gt;&lt;a href=&quot;delete/${contact.id}&quot;&gt;delete&lt;/a&gt;&lt;/td&gt;
	&lt;/tr&gt;
&lt;/c:forEach&gt;
&lt;/table&gt;
&lt;/c:if&gt;

&lt;/body&gt;
&lt;/html&gt;
</pre><h2>Download Source code</h2><p><a href="http://viralpatel.net/blogs/download/spring/spring-3-mvc-series/Spring3HibernateMaven.zip">Click here to download full source code of Contact manager application (16 KB)</a></p><h2>That&#8217;s All folks</h2><p>Compile and execute the Contact manager application in Eclipse.<br /> <img src="http://img.viralpatel.net/2010/10/spring3-hibernate-contact-manager.png" alt="spring3-hibernate-contact-manager" title="spring3-hibernate-contact-manager" width="423" height="475" class="aligncenter size-full wp-image-2108" /></p><p>If you read this far, you should <a rel="nofollow" href="http://twitter.com/viralpatelnet">follow me on twitter here.</a></p><div id="relatedpost"><h2  class="related_post_title">Related Posts</h2><ul class="related_post"><li><a href="http://viralpatel.net/blogs/2011/01/tutorial-save-get-blob-object-spring-3-mvc-hibernate.html" title="Tutorial:Saving/Retreving BLOB object in Spring 3 MVC and Hibernate">Tutorial:Saving/Retreving BLOB object in Spring 3 MVC and Hibernate</a></li><li><a href="http://viralpatel.net/blogs/2010/10/spring-3-mvc-themes-tutorial-example.html" title="Spring 3 MVC: Themes in Spring-Tutorial with Example">Spring 3 MVC: Themes in Spring-Tutorial with Example</a></li><li><a href="http://viralpatel.net/blogs/2010/07/spring-3-mvc-internationalization-i18n-localization-tutorial-example.html" title="Spring 3 MVC: Internationalization &#038; Localization Tutorial with Example">Spring 3 MVC: Internationalization &#038; Localization Tutorial with Example</a></li><li><a href="http://viralpatel.net/blogs/2010/07/spring-3-mvc-tiles-plugin-tutorial-example-eclipse.html" title="Spring 3 MVC: Tiles Plugin Tutorial with Example in Eclipse">Spring 3 MVC: Tiles Plugin Tutorial with Example in Eclipse</a></li><li><a href="http://viralpatel.net/blogs/2010/07/spring-3-mvc-handling-forms.html" title="Spring 3 MVC: Handling Forms in Spring 3.0 MVC">Spring 3 MVC: Handling Forms in Spring 3.0 MVC</a></li><li><a href="http://viralpatel.net/blogs/2010/06/spring-3-mvc-create-hello-world-application-spring-3-mvc.html" title="Spring 3 MVC: Create Hello World application in Spring 3.0 MVC">Spring 3 MVC: Create Hello World application in Spring 3.0 MVC</a></li><li><a href="http://viralpatel.net/blogs/2010/06/tutorial-spring-3-mvc-introduction-spring-mvc-framework.html" title="Spring 3 MVC – Introduction to Spring 3 MVC Framework">Spring 3 MVC – Introduction to Spring 3 MVC Framework</a></li></ul></div>]]></content:encoded> <wfw:commentRss>http://viralpatel.net/blogs/2010/11/spring3-mvc-hibernate-maven-tutorial-eclipse-example.html/feed</wfw:commentRss> <slash:comments>163</slash:comments> </item> <item><title>Spring 3 MVC: Themes in Spring-Tutorial with Example</title><link>http://viralpatel.net/blogs/2010/10/spring-3-mvc-themes-tutorial-example.html</link> <comments>http://viralpatel.net/blogs/2010/10/spring-3-mvc-themes-tutorial-example.html#comments</comments> <pubDate>Thu, 07 Oct 2010 09:28:14 +0000</pubDate> <dc:creator>Viral Patel</dc:creator> <category><![CDATA[Spring]]></category> <category><![CDATA[Spring 3 MVC]]></category> <category><![CDATA[spring mvc]]></category> <category><![CDATA[spring-3-mvc-series]]></category><guid isPermaLink="false">http://viralpatel.net/blogs/?p=2093</guid> <description><![CDATA[Welcome to Part 6 of Spring 3.0 MVC Series. In previous article we saw how to add Internationalization i18n and Localization L10n support to Spring 3.0 based web application. We used LocaleChangeInterceptor to intercept the change in locale and ReloadableResourceBundleMessageSource class to add message resources properties. In this part we will see how to add [...]]]></description> <content:encoded><![CDATA[<p>Welcome to Part 6 of <strong>Spring 3.0 MVC Series</strong>. In <a href="http://viralpatel.net/blogs/2010/07/spring-3-mvc-internationalization-i18n-localization-tutorial-example.html">previous article</a> we saw how to add Internationalization i18n and Localization L10n support to Spring 3.0 based web application. We used <code>LocaleChangeInterceptor</code> to intercept the change in locale and <code>ReloadableResourceBundleMessageSource</code> class to add message resources properties.</p><p>In this part we will see how to add Themes in Spring MVC. We will create three different themes and add functionality in our HelloWorldSpring project for user to select any of the available theme. Once user selects a theme, we can save it in cookies so that it can be persisted between different sessions.</p><style type="text/css">#spring{color:#222;width:98%;background-color:#EF9;padding:5px;-moz-border-radius:10px;-webkit-border-radius:10px}#spring
h3{font-size:18px;text-decoration:underline}#spring
ul{list-style:none}#spring ul
li{padding:3px}</style><div id="spring"><h3>Spring 3.0 MVC Series</h3><ul><li><a href="http://viralpatel.net/blogs/2010/06/tutorial-spring-3-mvc-introduction-spring-mvc-framework.html">Part 1: Introduction to Spring 3.0 MVC framework</a></li><li><a href="http://viralpatel.net/blogs/2010/06/spring-3-mvc-create-hello-world-application-spring-3-mvc.html">Part 2: Create Hello World Application in Spring 3.0 MVC</a></li><li><a href="http://viralpatel.net/blogs/2010/07/spring-3-mvc-handling-forms.html">Part 3: Handling Forms in Spring 3.0 MVC</a></li><li><a href="http://viralpatel.net/blogs/2010/07/spring-3-mvc-tiles-plugin-tutorial-example-eclipse.html">Part 4: Spring 3 MVC Tiles Plugin Tutorial with Example in Eclipse</a></li><li><a href="http://viralpatel.net/blogs/2010/07/spring-3-mvc-internationalization-i18n-localization-tutorial-example.html">Part 5: Spring 3 MVC Internationalization & Localization Tutorial with Example in Eclipse</a></li><li><a href="http://viralpatel.net/blogs/2010/10/spring-3-mvc-themes-tutorial-example.html">Part 6: Spring 3 MVC Themes in Spring-Tutorial with Example</a></li><li><a href="http://viralpatel.net/blogs/2010/11/spring3-mvc-hibernate-maven-tutorial-eclipse-example.html">Part 7: Create Spring 3 MVC Hibernate 3 Example using Maven in Eclipse</a></li></ul></div><h2>Introduction to Themes in Spring MVC</h2><p>A theme is a collection of static resources, typically style sheets and images, that affect the visual style of the application. We can apply Spring Web MVC framework themes to set the overall look-and-feel of application, thereby enhancing user experience.</p><p>To use themes in your web application, you must set up an implementation of the org.springframework.ui.context.ThemeSource  interface. The WebApplicationContext  interface extends ThemeSource but delegates its responsibilities to a dedicated implementation. By default the delegate will be an org.springframework.ui.context.support.ResourceBundleThemeSource  implementation that loads properties files from the root of the classpath. To use a custom ThemeSource  implementation or to configure the base name prefix of the ResourceBundleThemeSource, you can register a bean in the application context with the reserved name themeSource. The web application context automatically detects a bean with that name and uses it.</p><p>When using the ResourceBundleThemeSource, a theme is defined in a simple properties file. The properties file lists the resources that make up the theme. Here is an example:</p><h2>Our Goal</h2><p>Our goal is to change the Hello World Spring 3 MVC and add Theme support to it. User will have option to select theme from 3 predefined themes (default, black and blue).<br /> <img src="http://img.viralpatel.net/2010/07/spring-mvc-theme-demo2.png" alt="spring-mvc-theme-demo" title="spring-mvc-theme-demo" width="427" height="371" class="aligncenter size-full wp-image-2094" /></p><h2>Adding Theme support to Spring 3 MVC</h2><p>Let us configure our Spring 3 MVC application to add Theme support. For this we will add following code into spring-servlet.xml file.</p><p><em>File: WebContent/WEB-INF/spring-servlet.xml</em></p><pre class="brush: xml; title: ; notranslate">
	&lt;bean id=&quot;themeSource&quot;
		class=&quot;org.springframework.ui.context.support.ResourceBundleThemeSource&quot;&gt;
			&lt;property name=&quot;basenamePrefix&quot; value=&quot;theme-&quot; /&gt;
	&lt;/bean&gt;

	&lt;!-- Theme Change Interceptor and Resolver definition --&gt;
	&lt;bean id=&quot;themeChangeInterceptor&quot;
		class=&quot;org.springframework.web.servlet.theme.ThemeChangeInterceptor&quot;&gt;
		&lt;property name=&quot;paramName&quot; value=&quot;theme&quot; /&gt;
	&lt;/bean&gt;
	&lt;bean id=&quot;themeResolver&quot;
		class=&quot;org.springframework.web.servlet.theme.CookieThemeResolver&quot;&gt;
		&lt;property name=&quot;defaultThemeName&quot; value=&quot;default&quot; /&gt;
	&lt;/bean&gt;

	&lt;bean id=&quot;handlerMapping&quot;
		class=&quot;org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping&quot;&gt;
		&lt;property name=&quot;interceptors&quot;&gt;
			&lt;list&gt;
				&lt;ref bean=&quot;localeChangeInterceptor&quot; /&gt;
				&lt;ref bean=&quot;themeChangeInterceptor&quot; /&gt;
			&lt;/list&gt;
		&lt;/property&gt;
	&lt;/bean&gt;
</pre><p>In the above configuration, first we have added <strong>themeSource</strong> bean. Notice that this bean is an instance of class <code>ResourceBundleThemeSource</code> and we also have specified a property <strong>basenamePrefix</strong> with value <strong>&#8220;theme-&#8221;</strong>. ResourceBundleThemeSource class will load the property files containing theme definition starting with prefix &#8220;theme-&#8221;. Thus, if we have defined 3 new themes in our project (default, black and blue) then we will create 3 property files while will have certain configuration properties. Also these files will be placed under the project classpath.</p><p>Next, we defined an interceptor bean themeChangeInterceptor which is an instance of class <code>org.springframework.web.servlet.theme.ThemeChangeInterceptor</code>. Also note here that we have specified a property <strong>paramName</strong> with value <strong>theme</strong>. This interceptor is invoked whenever a request is made with parameter &#8220;theme&#8221; with different values.</p><p>Once the themeChangeInterceptor intercepts the change in the theme, the changes are then stored in the cookies using class <code>org.springframework.web.servlet.theme.CookieThemeResolver</code>. We have configured this class in our spring-servlet.xml configuration file. Also note that we have specified default theme name with this bean.</p><p>Now create following properties files in resources/ folder of the project.</p><p><img src="http://img.viralpatel.net/2010/08/spring-mvc-theme-directory-structure.png" alt="spring-mvc-theme-directory-structure" title="spring-mvc-theme-directory-structure" width="195" height="459" class="aligncenter size-full wp-image-2103" /></p><p><em>File: resources/theme-default.properties</em></p><pre class="brush: xml; title: ; notranslate">
css=themes/default.css
</pre><p><em>File: resources/theme-blue.properties</em></p><pre class="brush: xml; title: ; notranslate">
css=themes/blue.css
</pre><p><em>File: resources/theme-black.properties</em></p><pre class="brush: xml; title: ; notranslate">
css=themes/black.css
</pre><h2>CSS Stylesheet for different Themes</h2><p>Let us create 3 CSS stylesheet which will act as the theme files for our project. Create following CSS files in WebContent/themes folder.</p><p><em>File: WebContent/themes/default.css</em></p><pre class="brush: css; title: ; notranslate">
body {
    background-color: white;
    color: black;
}
</pre><p><em>File: WebContent/themes/blue.css</em></p><pre class="brush: css; title: ; notranslate">
body {
	background-color: #DBF5FF;
	color: #007AAB;
}
</pre><p><em>File: WebContent/themes/black.css</em></p><pre class="brush: css; title: ; notranslate">
body {
	background-color: #888;
	color: white;
}
</pre><h2>JSP View changes</h2><p>We are almost done with the changes and last bit that is remaining is to add a functionality for user to select the theme from UI. For this we will change the header.jsp file and add 3 links with different themes. User can click on any of this link and change the theme of webapplication.</p><p><em>File: WebContent/WEB-INF/jsp/header.jsp</em></p><pre class="brush: xml; title: ; notranslate">
&lt;%@taglib uri=&quot;http://www.springframework.org/tags&quot; prefix=&quot;spring&quot;%&gt;
&lt;%@taglib uri=&quot;http://java.sun.com/jsp/jstl/core&quot; prefix=&quot;c&quot;%&gt;

&lt;h3&gt;&lt;spring:message code=&quot;label.title&quot;/&gt;&lt;/h3&gt;

&lt;span style=&quot;float: right&quot;&gt;
    &lt;a href=&quot;?lang=en&quot;&gt;en&lt;/a&gt;
    |
    &lt;a href=&quot;?lang=de&quot;&gt;de&lt;/a&gt;
&lt;/span&gt;

&lt;span style=&quot;float: left&quot;&gt;
    &lt;a href=&quot;?theme=default&quot;&gt;def&lt;/a&gt;
    |
    &lt;a href=&quot;?theme=black&quot;&gt;blk&lt;/a&gt;
    |
    &lt;a href=&quot;?theme=blue&quot;&gt;blu&lt;/a&gt;
&lt;/span&gt;
</pre><p>Notice that in above JSP changes we created 3 links with argument &#8220;?theme=&#8221;. Thus whenever user will click these links, a new parameter will be passed in the request with the appropriate theme. The request interceptor of Spring will fetch this value and change the theme accordingly.</p><h2>That&#8217;s All Folks</h2><p>That’s pretty much it <img src='http://viralpatel.net/blogs/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> We just added Theme support to our demo Spring 3.0 MVC application. All you have to do is just execute the app in Eclipse. Press Alt + Shift + X, R.</p><p><img src="http://img.viralpatel.net/2010/07/spring-mvc-theme-demo2.png" alt="spring-mvc-theme-demo" title="spring-mvc-theme-demo" width="427" height="371" class="aligncenter size-full wp-image-2094" /></p><h2>Download Source Code</h2><p><a href="http://viralpatel.net/blogs/download/spring/spring-3-mvc-series/Spring3MVC-part6.zip">Click here to download Source code (21kb, zip)</a></p><div id="relatedpost"><h2  class="related_post_title">Related Posts</h2><ul class="related_post"><li><a href="http://viralpatel.net/blogs/2010/11/spring3-mvc-hibernate-maven-tutorial-eclipse-example.html" title="Tutorial:Create Spring 3 MVC Hibernate 3 Example using Maven in Eclipse">Tutorial:Create Spring 3 MVC Hibernate 3 Example using Maven in Eclipse</a></li><li><a href="http://viralpatel.net/blogs/2010/07/spring-3-mvc-internationalization-i18n-localization-tutorial-example.html" title="Spring 3 MVC: Internationalization &#038; Localization Tutorial with Example">Spring 3 MVC: Internationalization &#038; Localization Tutorial with Example</a></li><li><a href="http://viralpatel.net/blogs/2010/07/spring-3-mvc-tiles-plugin-tutorial-example-eclipse.html" title="Spring 3 MVC: Tiles Plugin Tutorial with Example in Eclipse">Spring 3 MVC: Tiles Plugin Tutorial with Example in Eclipse</a></li><li><a href="http://viralpatel.net/blogs/2010/07/spring-3-mvc-handling-forms.html" title="Spring 3 MVC: Handling Forms in Spring 3.0 MVC">Spring 3 MVC: Handling Forms in Spring 3.0 MVC</a></li><li><a href="http://viralpatel.net/blogs/2010/06/spring-3-mvc-create-hello-world-application-spring-3-mvc.html" title="Spring 3 MVC: Create Hello World application in Spring 3.0 MVC">Spring 3 MVC: Create Hello World application in Spring 3.0 MVC</a></li><li><a href="http://viralpatel.net/blogs/2010/06/tutorial-spring-3-mvc-introduction-spring-mvc-framework.html" title="Spring 3 MVC – Introduction to Spring 3 MVC Framework">Spring 3 MVC – Introduction to Spring 3 MVC Framework</a></li><li><a href="http://viralpatel.net/blogs/2205/change-spring-servlet-filename-configuration" title="Change spring-servlet.xml Filename (Spring Web Contenxt Configuration Filename)">Change spring-servlet.xml Filename (Spring Web Contenxt Configuration Filename)</a></li></ul></div>]]></content:encoded> <wfw:commentRss>http://viralpatel.net/blogs/2010/10/spring-3-mvc-themes-tutorial-example.html/feed</wfw:commentRss> <slash:comments>26</slash:comments> </item> </channel> </rss>
<!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Minified using disk: basic
Page Caching using disk: enhanced

Served from: viralpatel.net @ 2012-02-09 02:30:00 -->
