<?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; Featured</title> <atom:link href="http://viralpatel.net/blogs/category/featured/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>Oracle 11G new feature: Virtual Column</title><link>http://viralpatel.net/blogs/2011/02/oracle-11g-new-feature-virtual-column.html</link> <comments>http://viralpatel.net/blogs/2011/02/oracle-11g-new-feature-virtual-column.html#comments</comments> <pubDate>Wed, 23 Feb 2011 09:07:22 +0000</pubDate> <dc:creator>Anuj Parashar</dc:creator> <category><![CDATA[Database]]></category> <category><![CDATA[Featured]]></category> <category><![CDATA[Oracle]]></category> <category><![CDATA[oracle-11g]]></category><guid isPermaLink="false">http://viralpatel.net/blogs/?p=2158</guid> <description><![CDATA[Oracle 11g introduced the concept of &#8216;Virtual Column&#8217; within a table. Virtual Columns are similar to normal table&#8217;s columns but with the following differences: They are defined by an expression. The result of evaluation of this expression becomes the value of the column. The values of the virtual column are not stored in the database. [...]]]></description> <content:encoded><![CDATA[<p><img src="http://img.viralpatel.net/2010/06/oracle-logo.jpg" alt="" width="268" height="41" class="alignright size-full wp-image-2070" /> Oracle 11g introduced the concept of &#8216;Virtual Column&#8217; within a table. Virtual Columns are similar to normal table&#8217;s columns but with the following differences:</p><ul><li>They are defined by an expression. The result of evaluation of this expression becomes the value of the column.</li><li>The values of the virtual column are not stored in the database. Rather, it&#8217;s computed at run-time when you query the data.</li><li>You can&#8217;t update (in SET clause of update statement) the values of virtual column. These are read only values, that are computed dynamically and any attempt to modify them will result into oracle error.</li></ul><p>The syntax for defining a virtual column is:</p><pre class="brush: sql; title: ; notranslate">
column_name [datatype] [GENERATED ALWAYS] AS [expression] [VIRTUAL]
</pre><p>where the parameters within [] are optional and can be omitted. If you don&#8217;t mention the datatype, Oracle will decide it based on the result of the expression.</p><p>Excepting the above points, a virtual column, exists just like any other column of a normal table and the following points apply to it:</p><ol><li>Virtual columns can be used in the WHERE clause of UPDATE and DELETE statement but they can&#8217;t be modified by DML.</li><li>Statistics can be collected on them.</li><li>They can be used as a partition key in virtual column based partitioning.</li><li>Indexes can be created on them. As you might have guessed, oracle would create function based indexes as we create on normal tables.</li><li>Constraints can be created on them.</li></ol><h2>Create table with Virtual Column</h2><p>For creating a virtual column, use the syntax mentioned above. Consider the following example:</p><pre class="brush: sql; title: ; notranslate">
CREATE TABLE EMPLOYEE
(
	empl_id        NUMBER,
	empl_nm        VARCHAR2(50),
	monthly_sal    NUMBER(10,2),
	bonus          NUMBER(10,2),
	total_sal      NUMBER(10,2) GENERATED ALWAYS AS (monthly_sal*12 + bonus)
);
</pre><p>Here we have defined a virtual column &#8220;total_sal&#8221; whose value would be dynamically calculated using the expression provided after the &#8220;generated always as&#8221; clause. Please note that this declaration is different than using &#8220;default&#8221; clause for a normal column as you can&#8217;t refer column names with &#8220;default&#8221; clause.</p><p>Lets check the data dictionary view:</p><pre class="brush: sql; title: ; notranslate">
SELECT column_name, data_type, data_length, data_default, virtual_column
  FROM user_tab_cols
 WHERE table_name = 'EMPLOYEE';

COLUMN_NAME | DATA_TYPE | DATA_LENGTH | DATA_DEFAULT             | VIRTUAL_COLUMN
EMPL_ID     | NUMBER    | 22          | null                     | NO
EMPL_NM     | VARCHAR2  | 50          | null                     | NO
MONTHLY_SAL | NUMBER    | 22          | null                     | NO
BONUS       | NUMBER    | 22          | null                     | NO
TOTAL_SAL   | NUMBER    | 22          | &quot;MONTHLY_SAL&quot;*12+&quot;BONUS&quot; | YES
</pre><p>The value &#8220;YES&#8221; for the column &#8220;virtual_column&#8221; tells us that this is a virtual column. Another optional keyword &#8220;VIRTUAL&#8221; can also be added to make it syntactically complete.</p><pre class="brush: sql; title: ; notranslate">
DROP TABLE EMPLOYEE PURGE;

CREATE OR REPLACE FUNCTION get_empl_total_sal ( p_monthly_sal   NUMBER,
                                                p_bonus         NUMBER)
   RETURN NUMBER
DETERMINISTIC
IS
BEGIN
   RETURN p_monthly_sal * 12 + p_bonus;
END;

CREATE TABLE EMPLOYEE
(empl_id     NUMBER,
 empl_nm     VARCHAR2(50),
 monthly_sal NUMBER(10,2),
 bonus       NUMBER(10,2),
 total_sal   NUMBER(10,2) AS (get_empl_total_sal(monthly_sal, bonus)) VIRTUAL
);
</pre><p>We have included the &#8220;VIRTUAL&#8221; clause in the table definition. Please note that instead of using an expression, I have used a deterministic function. A deterministic function, when passed certain inputs, will always return the exact same output. &#8220;DETERMINISTIC&#8221; keyword is needed in order to mark a function as a candidate to be used in a function based index.</p><p>You can also create indexes on the virtual columns. Here is an example:</p><pre class="brush: sql; title: ; notranslate">
CREATE INDEX idx_total_sal ON employee(total_sal);

SELECT index_name, index_type
  FROM user_indexes
 WHERE table_name = 'EMPLOYEE';

INDEX_NAME     INDEX_TYPE
IDX_TOTAL_SAL  FUNCTION-BASED NORMAL
</pre><p>Note that even this function is used as part of table definition, you can still drop it. But this in turn will make the table inaccessible.</p><pre class="brush: sql; title: ; notranslate">
DROP FUNCTION get_empl_total_sal;

SELECT * FROM employee;
*
Error at line 0
ORA-00904: &quot;schema&quot;.&quot;GET_EMPL_TOTAL_SAL&quot;: invalid identifier
</pre><p>You can alter the table with virtual column as you would modify a table with normal columns. Lets add the same column using the ALTER command:</p><pre class="brush: sql; title: ; notranslate">
DROP TABLE EMPLOYEE PURGE;

CREATE TABLE EMPLOYEE
(empl_id     NUMBER,
 empl_nm     VARCHAR2(50),
 monthly_sal NUMBER(10,2),
 bonus       NUMBER(10,2)
);

ALTER TABLE EMPLOYEE ADD (total_sal AS (monthly_sal * 12 + bonus));
</pre><p>Note that the datatype of the new column is not declared. It will be assigned a datatype based on the result of the expression (in this case, it would be NUMBER). Now let&#8217;s insert some data in the table:</p><pre class="brush: sql; title: ; notranslate">
INSERT INTO employee (empl_id, empl_nm, monthly_sal, bonus)
   WITH DATA AS
        (SELECT 100 empl_id, 'AAA' empl_nm, 20000 monthly_sal, 3000 bonus
           FROM DUAL
         UNION
         SELECT 200, 'BBB', 12000, 2000
           FROM DUAL
         UNION
         SELECT 300, 'CCC', 32100, 1000
           FROM DUAL
         UNION
         SELECT 400, 'DDD', 24300, 5000
           FROM DUAL
         UNION
         SELECT 500, 'EEE', 12300, 8000
           FROM DUAL)
   SELECT *
     FROM DATA;

SELECT * FROM employee;

EMPL_ID | EMPL_NM | MONTHLY_SAL | BONUS | TOTAL_SAL
100     | AAA     | 20000       | 3000  | 243000
200     | BBB     | 12000       | 2000  | 146000
300     | CCC     | 32100       | 1000  | 386200
400     | DDD     | 24300       | 5000  | 296600
500     | EEE     | 12300       | 8000  | 155600
</pre><p>Here we have populated the table columns except the virtual column with some values. Upon selecting the data, we get the value for &#8220;total_sal&#8221;. Remember that this data is not actually stored in the database but evaluated dynamically. Lets try updating this value of this virtual column:</p><pre class="brush: sql; title: ; notranslate">
UPDATE employee
   SET total_sal = 2000;

ORA-54017: UPDATE operation disallowed on virtual columns
</pre><p>As mentioned before, the statistics can also be gathered for the virtual columns.</p><pre class="brush: sql; title: ; notranslate">
EXEC DBMS_STATS.GATHER_TABLE_STATS(user, 'EMPLOYEE');

SELECT column_name, num_distinct,
       display_raw (low_value, data_type)  low_value,
       display_raw (high_value, data_type) high_value
  FROM dba_tab_cols
 WHERE table_name = 'EMPLOYEE';

COLUMN_NAME | NUM_DISTINCT | LOW_VALUE | HIGH_VALUE
TOTAL_SAL   | 5            | 146000    | 386200
BONUS       | 5            | 1000      | 8000
MONTHLY_SAL | 5            | 12000     | 32100
EMPL_NM     | 5            | AAA       | EEE
EMPL_ID     | 5            | 100       | 500
</pre><h2>Limitations on Virtual Columns</h2><p><em>**The query above uses a wonderful function &#8220;display_raw&#8221; by &#8220;Greg Rahn&#8221; to display the high/low values. Please check the references at the last to see it&#8217;s definition.</em></p><ol><li>A virtual column can only be of scalar datatype or XMLDATATYE. It can&#8217;t be a user defined type, LOB or RAW.</li><li>All columns mentioned as part of the virtual column expression should belong to the same table.</li><li>No DMLs are allowed on the virtual columns.</li><li>The virtual column expression can&#8217;t reference any other virtual column.</li><li>Virtual columns can only be created on ordinary tables. They can&#8217;t be created on index-organized, external, object, cluster or temporary tables.</li><li>If a deterministic function is used as virtual column expression, that virtual column can&#8217;t be used as a partitioning key for virtual column-based partitioning.</li></ol><h2>Virtual Column-Based Partitioning</h2><p>Prior releases of Oracle only allowed a table to be partitioned based on a physical column. Oracle 11g, with the addition of virtual columns, now allows a partition key based on an expression, using one or more existing columns of the table. A virtual column can now be used as a partitioning key. Lets partition our table based on the virtual column &#8220;total_sal&#8221;:</p><pre class="brush: sql; title: ; notranslate">
DROP TABLE EMPLOYEE PURGE;

CREATE TABLE employee
(empl_id     NUMBER,
 empl_nm     VARCHAR2(50),
 monthly_sal NUMBER(10,2),
 bonus       NUMBER(10,2),
 total_sal   NUMBER(10,2) AS (monthly_sal*12 + bonus)
)
PARTITION BY RANGE (total_sal)
    (PARTITION sal_200000 VALUES LESS THAN (200000),
     PARTITION sal_400000 VALUES LESS THAN (400000),
     PARTITION sal_600000 VALUES LESS THAN (600000),
     PARTITION sal_800000 VALUES LESS THAN (800000),
     PARTITION sal_default VALUES LESS THAN (MAXVALUE));

INSERT INTO employee (empl_id, empl_nm, monthly_sal, bonus)
   WITH DATA AS
        (SELECT 100 empl_id, 'AAA' empl_nm, 20000 monthly_sal, 3000 bonus
           FROM DUAL
         UNION
         SELECT 200, 'BBB', 12000, 2000
           FROM DUAL
         UNION
         SELECT 300, 'CCC', 32100, 1000
           FROM DUAL
         UNION
         SELECT 400, 'DDD', 24300, 5000
           FROM DUAL
         UNION
         SELECT 500, 'EEE', 12300, 8000
           FROM DUAL)
   SELECT *
     FROM DATA;

EXEC DBMS_STATS.GATHER_TABLE_STATS(user,'EMPLOYEE',granularity =&amp;gt; 'PARTITION');

SELECT   table_name, partition_name, num_rows
    FROM user_tab_partitions
   WHERE table_name = 'EMPLOYEE'
ORDER BY partition_name;

TABLE_NAME | PARTITION_NAME | NUM_ROWS
EMPLOYEE   | SAL_200000     | 2
EMPLOYEE   | SAL_400000     | 3
EMPLOYEE   | SAL_600000     | 0
EMPLOYEE   | SAL_800000     | 0
EMPLOYEE   | SAL_DEFAULT    | 0
</pre><p>So far, everything looks fine, lets now try to update monthly salary of one employee and in turn the value of total_sal.</p><pre class="brush: sql; title: ; notranslate">
UPDATE employee
   SET monthly_sal = 30000
 WHERE empl_id = 500;

ORA-14402: updating partition key column would cause a partition change
</pre><p>What happened? The reason is simple, updating the &#8220;monthly_sal&#8221; would result into change in &#8220;total_sal&#8221; of the employee and thus a partition change is required. This can be handled by enabling the row movement in the current definition of the table.</p><pre class="brush: sql; title: ; notranslate">
ALTER TABLE employee ENABLE ROW MOVEMENT;

UPDATE employee
   SET monthly_sal = 80000
 WHERE empl_id = 500;

1 row updated.
</pre><p>The update works fine. As mentioned before, a deterministic function can&#8217;t be used as virtual column expression which is to be used as a partitioning key. It has to be an expression defined on the columns of the table as done in the previous example. The following syntax will result in oracle error:</p><pre class="brush: sql; title: ; notranslate">
CREATE TABLE employee_new
(empl_id     NUMBER,
 empl_nm     VARCHAR2(50),
 monthly_sal NUMBER(10,2),
 bonus       NUMBER(10,2),
 total_sal   NUMBER(10,2) AS (get_empl_total_sal(monthly_sal, bonus))
)
PARTITION BY RANGE (total_sal)
    (PARTITION sal_200000 VALUES LESS THAN (200000),
     PARTITION sal_400000 VALUES LESS THAN (400000),
     PARTITION sal_600000 VALUES LESS THAN (600000),
     PARTITION sal_800000 VALUES LESS THAN (800000),
     PARTITION sal_default VALUES LESS THAN (MAXVALUE));

ORA-54021: Cannot use PL/SQL expressions in partitioning or subpartitioning columns
</pre><h3>References:</h3><p><a rel="nofollow" target="_new" href="http://structureddata.org/2007/10/16/how-to-display-high_valuelow_value-columns-from-user_tab_col_statistics/">Greg Rahn&#8217;s display_raw function</a><br /> <a rel="nofollow" target="_new" href="http://download.oracle.com/docs/cd/B28359_01/server.111/b32024/part_avail.htm#BJEFFAGH">Oracle Documentation</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/row-data-multiplication-in-oracle.html" title="Row Data Multiplication in Oracle">Row Data Multiplication in Oracle</a></li><li><a href="http://viralpatel.net/blogs/2010/07/generating-random-data-in-oracle.html" title="Generating Random Data in Oracle">Generating Random Data in Oracle</a></li><li><a href="http://viralpatel.net/blogs/2010/06/deleting-duplicate-rows-in-oracle.html" title="Deleting Duplicate Rows in Oracle">Deleting Duplicate Rows in Oracle</a></li><li><a href="http://viralpatel.net/blogs/2010/06/invisible-indexes-in-oracle-11g.html" title="Invisible Indexes in Oracle 11g">Invisible Indexes in Oracle 11g</a></li><li><a href="http://viralpatel.net/blogs/2010/06/oracle-data-compression.html" title="Oracle Data Compression">Oracle Data Compression</a></li><li><a href="http://viralpatel.net/blogs/2010/02/understanding-primary-keypk-constraint-in-oracle.html" title="Understanding Primary Key(PK) Constraint in Oracle">Understanding Primary Key(PK) Constraint in Oracle</a></li><li><a href="http://viralpatel.net/blogs/2009/05/fetch-random-rows-from-database-mysql-oracle-ms-sql-postgresql-example.html" title="Fetch Random rows from Database (MySQL, Oracle, MS SQL, PostgreSQL)">Fetch Random rows from Database (MySQL, Oracle, MS SQL, PostgreSQL)</a></li></ul></div>]]></content:encoded> <wfw:commentRss>http://viralpatel.net/blogs/2011/02/oracle-11g-new-feature-virtual-column.html/feed</wfw:commentRss> <slash:comments>1</slash:comments> </item> <item><title>Your first Play! &#8211; GAE &#8211; Siena application: Tutorial with Example</title><link>http://viralpatel.net/blogs/2011/01/first-play-framework-gae-siena-application-tutorial-example.html</link> <comments>http://viralpatel.net/blogs/2011/01/first-play-framework-gae-siena-application-tutorial-example.html#comments</comments> <pubDate>Tue, 25 Jan 2011 13:00:48 +0000</pubDate> <dc:creator>Viral Patel</dc:creator> <category><![CDATA[Featured]]></category> <category><![CDATA[JavaEE]]></category> <category><![CDATA[Play Framework]]></category> <category><![CDATA[GAE]]></category> <category><![CDATA[Google App Engine]]></category> <category><![CDATA[JQuery]]></category> <category><![CDATA[Play-framework]]></category> <category><![CDATA[Siena]]></category> <category><![CDATA[Tutorial]]></category><guid isPermaLink="false">http://viralpatel.net/blogs/?p=2135</guid> <description><![CDATA[Convention over configuration has became a buzz word these days. It is a software design paradigm which seeks to decrease the number of decisions that developers need to make, gaining simplicity, but not necessarily losing flexibility. More and more web frameworks are using this approach and making web development simple. Ruby on rails, DJango, Grails, [...]]]></description> <content:encoded><![CDATA[<p><img src="http://img.viralpatel.net/2011/01/Play-framework.png" alt="Play-framework" title="Play-framework" width="200" height="79" class="alignleft size-full wp-image-2136" /><strong>Convention over configuration</strong> has became a buzz word these days. It is a software design paradigm which seeks to decrease the number of decisions that developers need to make, gaining simplicity, but not necessarily losing flexibility. More and more web frameworks are using this approach and making web development simple. Ruby on rails, DJango, Grails, CakePHP, ASP .NET, Apache Wicket etc are few in top demand these days.</p><h2>What&#8217;s Play!?</h2><p>One of the newest one is <strong>Play! framework</strong>. Play is heavily inspired by Ruby on Rails and Django. A developer familiar with any of these frameworks will feel at home. Play leverages the power of Java to build web applications in an environment that is not <u>Java Enterprise Edition-centric</u>. By lifting away the Java EE constraints, Play provides developers with an easy-to-develop and elegant stack aimed at productivity.</p><p>I have worked in CakePHP and I am a big fan of it. I believe Play! is bringing the same experience of fast web application development to the Java world, right from hello world baby steps to create a full production ready application and writing tests.</p><p>When you visit <a rel="nofollow" target="_blank" href="http://www.playframework.org/documentation/1.1/overview">Play!&#8217;s overview</a> webpage on their site, the very first line will surely catch your attention.</p><p><em>The Play framework is a clean alternative to <strong>bloated Enterprise Java stacks</strong>. It focuses on developer productivity and targets RESTful architectures. Play is a perfect companion to agile software development.<br /> </em></p><p>Although the words <em>&#8220;bloated Enterprise Java stacks&#8221;</em> may offend many Java developers who are very used to work with <a href="http://viralpatel.net/blogs/2010/06/tutorial-spring-3-mvc-introduction-spring-mvc-framework.html">Spring MVC</a>, <a href="http://viralpatel.net/blogs/2009/12/introduction-to-struts-2-framework.html">Struts</a> of <a href="http://viralpatel.net/blogs/2009/02/tutorial-creating-javaserver-faces-jsf-application-in-eclipse-jsf-project-jsf-tutorial.html">JavaServer Faces</a>;  I think its more of less correct and many of us already feels so working for years now in Spring / Struts and realizing how much boiler plate code is being pushed into system and how complex things became over period of time.</p><p>What I like most about Play! framework is the flexibility of this new framework and how easy it makes the life of developer. The application development becomes a piece of cake (like most CakePHP developers will feel). And the best part is all this you can do with Java without switching your favorite language and shifting to other like Rube or PHP.</p><h2>Highlights of Play! framework</h2><p>Let us see few differences of Play! from other Java frameworks <span style="color:#999">(Courtesy Wiki)</span>:</p><ul><li>Play is fully RESTful &#8211; there is no Java EE session per connection. This makes Play more outwardly-scalable than many other frameworks.</li><li>No configuration: download, unpack and develop &#8211; it&#8217;s that simple.</li><li>Easy round trips: no need to deploy to an application server, just edit the code and press the refresh button on the browser.</li><li>Integrated unit testing: unit testing is at the core of Play!</li><li>Elegant API: rarely will a developer need to import any third party library &#8211; Play comes with all the typical stuff built-in.</li><li>CRUD module: easily build administration UI with little code.</li><li>Play is a web framework: it is language agnostic and currently supports Java and Scala.</li><li>Modular architecture</li></ul><h2>Your first Play! application</h2><p>Hello world in Play! is straight forward. I will not spend much time in describing steps for installing and configuring Play!. On its homepage, Play! framework developer <em>Guillaume Bort</em> has made this wonderful getting started screencast which you can follow to create your very first Play! application.</p><p><iframe src="http://player.vimeo.com/video/7087610?title=0&amp;byline=0&amp;portrait=0" width="600" height="337" frameborder="0"></iframe></p><p>Few points I would like to highlight here is:</p><ul><li>Play is a real &#8220;Share nothing&#8221; system. Ready for REST, it is easily scaled by running multiple instances of the same application on several servers.</li><li>Play! loads the code dynamically. Just fix the bug in Java file and hit reload and voila, the change will get reflected instantly on webpage. No need to go through those sluggish rebuild / deployment / server restart.</li><li>Play! comes with a very efficient template system. The template system is based on Groovy as an expression language. It provides template inheritence, includes and tags.</li><li>A fully functional stack of modules are available in Play!. Provides integration with Hibernate, OpenID, Memcached&#8230; And a plugin system to create your own customize plugin or include one from hundreds of freely available ones.</li><li>Error discovery is very easy with Play!. When an error occurs, play shows you the source code and the exact line containing the problem. Even in templates.</li></ul><h2>Your first Play! &#8211; GAE &#8211; Siena application</h2><p>For this tutorial, I have chosen a little complex example which we develop in Play! and deploy on <strong>Google App Engine</strong> (GAE). The GAE offers fast development and deployment; simple administration, with no need to worry about hardware, patches or backups; and effortless scalability. The Google app engine does not support SQL or RDBMS. The App Engine datastore provides robust, scalable storage for your web application, with an emphasis on read and query performance. An application creates entities, with data values stored as properties of an entity. The app can perform queries over entities. All queries are pre-indexed for fast results over very large data sets.</p><p>Our demo application called <strong>eazyBookmark</strong> is already running on Google App engine. This is a Bookmark application where user can login and save their bookmarks. Click below image to visit online demo.</p><h3>Online Demo</h3><p><a href="http://eazybookmark.appspot.com/"><img src="http://img.viralpatel.net/2011/01/eazybookmark-logo.bmp" alt="eazybookmark-logo" title="eazybookmark-logo" class="aligncenter size-full wp-image-2137" /></a><br /> Link: <a target="_blank" href="http://eazybookmark.appspot.com/">http://eazybookmark.appspot.com/</a></p><p>Following are the functional aspects of <strong>eazyBookmark</strong> app.</p><ol><li>User can login to eazyBookmark using their Google account. No need to remember password for new account.</li><li>Using &#8220;Add link&#8221; functionality, user can add any URL and save as bookmark.</li><li>Any bookmark can be tagged with multiple tags. This way user can organize the links easily.</li><li>A bookmark once added can later be Edited or deleted.</li><li>A small bookmarklet script is available for user to add it in browser favorites. This bookmarklet can be later used by User to bookmark any webpage. Read <a href="http://eazybookmark.appspot.com/tools.html" target="_blank">Tools</a> page of <strong>eazyBookmark</strong>.</li></ol><p><img src="http://img.viralpatel.net/2011/01/eazybookmark-screen.png" alt="eazybookmark-screen" title="eazybookmark-screen" width="561" height="435" class="aligncenter size-full wp-image-2139" /></p><h2>Getting started</h2><p>Create a blank application in Play! using play create eazybookmark commnd.</p><pre>
C:\Play>play new eazybookmark
~        _            _
~  _ __ | | __ _ _  _| |
~ | '_ \| |/ _' | || |_|
~ |  __/|_|\____|\__ (_)
~ |_|            |__/
~
~ play! 1.1, http://www.playframework.org
~
~ The new application will be created in C:\Play\eazybookmark
~ What is the application name? [eazybookmark]
~
~ OK, the application is created.
~ Start it with : play run eazybookmark
~ Have fun!
~
</pre><p>The above Hello World video shows in depth how to install and use Play and create your first application.</p><h2>Adding Google App Engine (GAE) and Siena module to Play!</h2><p>We need two modules for our eazybookmark application. One is Google App engine (GAE) and another one is Siena. You can install these modules by running following command with Play!.</p><pre>
C:\Play> play install gae
..
..
C:\Play> play install siena
</pre><p>The above commands will install latest version of these modules. If you are behind proxy than the above command may fails. Currently there is no way of setting up proxy with Play! (v1.1) so you can manually download <a rel="nofollow" target="_blank" href="http://www.playframework.org/modules/gae">gae</a> and <a rel="nofollow" target="_blank" href="http://www.playframework.org/modules/siena">siena</a> from its homepage and copy them in /modules directory of your Play!.</p><p>Once the modules are installed successfully, you can add following lines in eazybookmark apps /conf/application.conf file.</p><pre>
# ---- Google app engine module ----
module.gae=${play.path}/modules/gae-1.4
# ---- Siena module ----
module.siena=${play.path}/modules/siena-1.3
</pre><p>You may want to restart the Play application to reflect the changes of the modules.</p><p>Once the application is restarted, the GAE module creates <code>/war/WEB-INF/appengine-web.xml</code> file. You need to update this file and add the application id of GAE. In our case we will have following data.<br /> File: /war/WEB-INF/appengine-web.xml</p><pre class="brush: xml; title: ; notranslate">
&lt;appengine-web-app xmlns=&quot;http://appengine.google.com/ns/1.0&quot;&gt;
	&lt;application&gt;eazybookmark&lt;/application&gt;
	&lt;version&gt;1&lt;/version&gt;
&lt;/appengine-web-app&gt;
</pre><p>You may want to replace eazybookmark with your own GAE Application ID.</p><h2>Play! and Siena models</h2><p>Let us first review the model classes we going to use for our application. We will have four model classes.</p><ul><li><strong>User</strong> &#8211; This is a User model. All user related information such as email, name, etc will get stored here.</li><li><strong>Link</strong> &#8211; This is Link model. All links related information such as URL, title, description etc will get stored here.</li><li><strong>Tag</strong> &#8211; This is Tag model. All the tags related information such as tagname etc will get stored here.</li><li><strong>LinkTag</strong> &#8211; This is a mapping model which maps Links with Tag. In Siena to create Many to Many relationship we need to create three classes. This class maps Link and Tag and add a many to many relationship to these entities.</li></ul><p>Here is the code for each of the models.</p><p><em>File: /app/model/User.java</em></p><pre class="brush: java; title: ; notranslate">
package models;

import siena.*;

public class User extends Model {

    @Id
    public Long id;

    public String email;
    public String name;
    public Date created;
    public Date modified;

    static Query&lt;User&gt; all() {
        return Model.all(User.class);
    }

    public static User findById(Long id) {
        return all().filter(&quot;id&quot;, id).get();
    }

    public static User findByEmail(String email) {
        return all().filter(&quot;email&quot;, email).get();
    }
	public User() {
		super();
	}
    public User(String email) {
		this.email = email;
    }

    public String toString() {
        return email;
    }
}
</pre><p>The User model has few attributes like email, name, created and modified which define a user. Few methods like <code>findById()</code> and <code>findByEmail()</code> select the User based on Id and email respectively.</p><p><em>File: /app/model/Link.java</em></p><pre class="brush: java; title: ; notranslate">
package models;

import java.util.*;
import siena.*;

public class Link extends Model {

    @Id(Generator.AUTO_INCREMENT)
    public Long id;

    public String url;
    public String title;
    public String description;

	public Date created;

	public Date modified;

    @Filter(&quot;link&quot;)
    public Query&lt;LinkTag&gt; linktags;

    @Index(&quot;user_index&quot;)
    public User user;

    public Link(User user, String url) {
    	super();
    	this.url = url;
        this.user = user;
    }
	public Link() {
		super();
	}
    static Query&lt;Link&gt; all() {
        return Model.all(Link.class);
    }

    public static Link findById(Long id) {
        return all().filter(&quot;id&quot;, id).get();
    }

    public static List&lt;Link&gt; findByUser(User user) {

        return all().filter(&quot;user&quot;, user).order(&quot;-created&quot;).fetch();
    }

	public static void addTag(Link link, Tag tag) {
			LinkTag linkTag = new LinkTag(link, tag);
			linkTag.insert();
	}

    public String toString() {
        return url;
    }

	public List&lt;Tag&gt; findTagsByLink() {

		List&lt;Tag&gt; tags = LinkTag.findByLink(this);

		return tags;

	}

	public static void addTagsFromCSV(Link link, String tagcsv, User user) {
		Collection&lt;Tag&gt; tags = null;
		if(null != tagcsv || !tagcsv.equalsIgnoreCase(&quot;&quot;)) {
			String [] tagArr = tagcsv.split(&quot;,&quot;);
			tags = new ArrayList&lt;Tag&gt;();
			for(String tagstr : tagArr) {
				tagstr = play.templates.JavaExtensions.slugify(tagstr.trim()).trim();
				if(null != tagstr &amp;&amp; !tagstr.equals(&quot;&quot;)) {
					Link.addTag(link, Tag.findOrCreateByName(tagstr,user));
				}

			}
		}
	}
}
</pre><p>The Link model class is similar to User. It has its own attributes such as url, title, description etc. Also note that Link model has few methods like <code>findById()</code>, <code>findTagsByLink()</code>, <code>addTag()</code>, <code>addTagsFromCSV()</code> etc. These methods are used from the controller to manipulate the link data. The Link has a many to many relationship with Tag. One link can have multiple tags attached to it.</p><p><em>File: /app/model/Tag.java</em></p><pre class="brush: java; title: ; notranslate">
package models;

import siena.*;
import java.util.*;

public class Tag extends Model {

    @Id(Generator.AUTO_INCREMENT)
    public Long id;

    public String name;

	@Index(&quot;user_index&quot;)
	public User user;

    public static Query&lt;Tag&gt; all() {
        return Model.all(Tag.class);
    }

	public static Tag findOrCreateByName(String name, User user) {
        Tag tag = all().filter(&quot;user&quot;, user).filter(&quot;name&quot;, name).get();
        if(null == tag) {
			tag = new Tag();
			tag.name = name;
			tag.user = user;
			tag.insert();
		}
		return tag;
	}

	public static Tag findById(Long id) {
		return  all().filter(&quot;id&quot;, id).get();
	}

    public static Tag findByName(String name, User user) {
        return all().filter(&quot;user&quot;, user).filter(&quot;name&quot;, name).get();
    }

    public static List&lt;Tag&gt; findByUser(User user) {
        return all().filter(&quot;user&quot;, user).fetch();
    }

    public String toString() {
        return name;
    }
}
</pre><p>The Tag model has one attribute tag name. This can be anything like travel, leisure, technology, news etc. Also note that each tag has one to one mapping with User. This is defined by <code>@Index("user_index")</code> annotation with object User. The Tag has usual methods <code>findById</code>, <code>findByName</code>, <code>findByUser</code>, <code>findOrCreateByName</code> etc which is used from controller to manipulate the Tag data.</p><p><em>File: /app/model/LinkTag.java</em></p><pre class="brush: java; title: ; notranslate">
package models;

import java.util.*;
import siena.*;

public class LinkTag extends Model {

    @Id
    public Long id;

    @NotNull
    @Column(&quot;link_id&quot;)
    @Index(&quot;link_index&quot;)
    public Link link;

    @NotNull
    @Column(&quot;tag_id&quot;)
    @Index(&quot;tag_index&quot;)
    public Tag tag;

	public LinkTag(Link link, Tag tag) {
		super();
		this.link = link;
		this.tag = tag;
	}

	public static Query&lt;LinkTag&gt; all() {
		return Model.all(LinkTag.class);
	}

	public static List&lt;Tag&gt; findByLink(Link link) {
		List&lt;LinkTag&gt; linkTags =  all().filter(&quot;link&quot;, link).fetch();
		List&lt;Tag&gt; tags = new ArrayList&lt;Tag&gt;();
		for(LinkTag linkTag : linkTags) {
			tags.add(Tag.findById(linkTag.tag.id));
		}

		return tags;
	}
	public static List&lt;Link&gt; findByTag(Tag tag) {
		List&lt;LinkTag&gt; linkTags =  all().filter(&quot;tag&quot;, tag).fetch();
		List&lt;Link&gt; links = new ArrayList&lt;Link&gt;();
		for(LinkTag linkTag : linkTags) {
			links.add(Link.findById(linkTag.link.id));
		}

		return links;
	}

	public String toString() {
		return link.toString() + &quot; : &quot; + tag.toString();
	}

	public static void deleteByLink(Link link) {

		List&lt;LinkTag&gt; linkTags = all().filter(&quot;link&quot;, link).fetch();
		if(null != linkTags) {
			for(LinkTag linktag : linkTags) {
					linktag.delete();
			}
		}
	}
}
</pre><p>The LinkTag model links the models Link and Tag. It adds the Many-to-many relationship between these models. We have few useful methods like <code>findByLink</code>, <code>findByTag</code> to get the list of relationship.</p><h2>The Play! Controllers</h2><p>The controller in Play! framework handles all the request / response between client and web server. It is a plain Java class which extends Controller class of Play!. In our application we will use two controller classes: <strong>Application</strong> and <strong>Profile</strong>. We will also have a helper class called Auth which has few useful methods to determine is a user is logged in, or to get email address of logged in user. This class invoke GAE module to get the authentication details and route user to Google page for authentication.</p><p><em>File: /app/controller/Auth.java</em></p><pre class="brush: java; title: ; notranslate">
package controllers;

import play.modules.gae.*;
import com.google.appengine.api.users.*;

public class Auth {

	public static boolean isLoggedIn() {
		return GAE.isLoggedIn();
	}
	public static String getEmail() {
		return GAE.getUser().getEmail();
	}
	public static User getUser() {
		return GAE.getUser();
	}

    public static void login(String action) {
        GAE.login(action);
    }

    public static void logout(String action) {
        GAE.logout(action);
    }
}</pre><p>Note that above <code>Auth</code> class is not part of controller (We haven&#8217;t extended it with Controller). It is just a utility class that we can use from other controllers to access user information. You may want to create your own package <code>utils</code> and keep this class there. For sake of simplicity, I am keeping this in <code>controllers</code> package.</p><p><em>File: /app/controller/Application.java</em></p><pre class="brush: java; title: ; notranslate">
package controllers;

import play.mvc.*;

import models.*;
import models.User;
import java.util.*;

public class Application extends Controller {

    public static void index() {
        if(Auth.isLoggedIn()) {
            User user = User.findByEmail(Auth.getEmail());
			if(null == user) {
				user = new User();
				user.email = Auth.getEmail();
				user.created = new Date();
				user.insert();
				Profile.edit(user.id);
				return;
			}
            Profile.index(null);
        }
        render();
    }

    public static void login() {
        Auth.login(&quot;Application.index&quot;);
    }

    public static void logout() {
        Auth.logout(&quot;Application.index&quot;);
    }
}</pre><p>Check the Application controller which is the entry point to our application. The index() method will be called whenever user request homepage /. In <code>index()</code> method we are checking if user is logged in. If not, then we show her a Login page using <code>render()</code> method. This method renders the default view of this action. We will see this view later in our example. Also note that if user is authenticated, we redirect it to <code>Profile.index</code> action. If user has logged in for first time in eazyBookmark, she will be redirected to Edit Profile page where she can select username for her profile.</p><p><em>File: /app/controller/Profile.java</em></p><pre class="brush: java; title: ; notranslate">
package controllers;

import models.*;
import play.*;
import play.mvc.*;
import java.util.*;

import play.data.validation.*;
import java.net.*;
import net.htmlparser.jericho.*;
import java.io.*;

import play.Logger;
import models.Tag;

public class Profile extends Application {

    @Before
    static void checkConnected() {
        if(Auth.getUser() == null) {
            Application.login();
        } else {
            renderArgs.put(&quot;user&quot;, Auth.getEmail());
        }
    }

    public static void index(String tag) {
		User user = getUser();

		List&lt;Link&gt; links = null;
		if(null == tag || tag.equalsIgnoreCase(&quot;&quot;)) {
			links = Link.findByUser(user);
		} else {
			links = LinkTag.findByTag(Tag.findByName(tag, user));
		}

		List&lt;Tag&gt; tags = Tag.findByUser(user);

        render(user, links, tags);
    }
//...
//...
}
</pre><p>The Profile controller is extended from Application controller to take advantage of login() / logout() method. Also note that this is not the full code for Profile.java. You can check the full source in the project source code.</p><h2>The View</h2><p>All the view files in Play! framework as saved in /views/ folder with .html extension. These are the plain HTML files with certain groovy template tags. Read more about built-in template tags in Play! <a rel="nofollow" target="_blank" href="http://www.playframework.org/documentation/1.1/tags">here</a>. There is a file main.html in /views folder which act as the template for all other views. Following is the content of main.html for eazyBookmark.</p><p><em>File: /views/main.html</em></p><pre class="brush: xml; title: ; notranslate">
&lt;!DOCTYPE html&gt;
&lt;html&gt;
    &lt;head&gt;
        &lt;title&gt;#{get 'title' /}&lt;/title&gt;
        &lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=utf-8&quot;&gt;
        &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; media=&quot;screen&quot; href=&quot;@{'/public/stylesheets/main.css'}&quot;&gt;

        #{get 'moreStyles' /}
        &lt;link rel=&quot;shortcut icon&quot; type=&quot;image/png&quot; href=&quot;@{'/public/images/favicon.ico'}&quot;&gt;
        &lt;script src=&quot;https://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js&quot; type=&quot;text/javascript&quot; charset=&quot;utf-8&quot;&gt;&lt;/script&gt;
        #{get 'moreScripts' /}

    &lt;/head&gt;
    &lt;body&gt;
		&lt;div id=&quot;pagewidth&quot; &gt;
			&lt;div id=&quot;headerbar&quot;&gt;
				&lt;div id=&quot;headercol&quot;&gt;
					&lt;div id=&quot;logo&quot;&gt;
						&lt;h3&gt;&lt;a href=&quot;/&quot;&gt;eazyBookmark&lt;/a&gt;&lt;/h3&gt;
					&lt;/div&gt;
					&lt;div id=&quot;headerlink&quot;&gt;
						#{if user}
								${user} &lt;span class=&quot;sep&quot;&gt;|&lt;/span&gt; &lt;a href=&quot;@{Application.logout()}&quot;&gt;Logout&lt;/a&gt;
						#{/if}
						#{else}
							&lt;a href=&quot;@{Application.login()}&quot;&gt;Login&lt;/a&gt;
						#{/else}
					&lt;/div&gt;
				&lt;/div&gt;
			&lt;/div&gt;
			&lt;div id=&quot;wrapper&quot; class=&quot;clearfix&quot;&gt;
					&lt;div id=&quot;maincol&quot;&gt;
						#{if flash.error}
							&lt;p class=&quot;error&quot;&gt;${flash.error}&lt;/p&gt;
						#{/if}
						#{if flash.success}
							&lt;p class=&quot;success&quot;&gt;${flash.success}&lt;/p&gt;
						#{/if}
				        #{doLayout /}
					&lt;/div&gt;
			&lt;/div&gt;
			&lt;div id=&quot;footer&quot;&gt;
				&lt;p&gt; Copyright &amp;copy; ${new Date().format('yyyy')}
 					&lt;a href=&quot;http://eazybookmark.appspot.com&quot;&gt;eazyBookmark&lt;/a&gt; &lt;/p&gt;
			&lt;/div&gt;
		&lt;/div&gt;
    &lt;/body&gt;
&lt;/html&gt;
</pre><p>In above template main.html file, we have <code>#{doLayout /}</code> tag which renders the content. Also note that we are displaying error / success message using flash mechanism of Play!.</p><p>For each controller, we create a separate folder in views/ folder. And these folders will contain the view file for each action in given controller. Thus in <code>/views/Application</code> folder we will have <code>index.html</code> and in <code>/views/Profile</code> folder we will have <code>edit.html</code>, <code>editlink.html</code> and <code>index.html</code>. Download these html files from the source code attached at the end of tutorial.</p><h2>Deploying Play! app in Google App Engine (GAE)</h2><p>We are done with the coding of our eazyBookmark application. Now we can deploy this app in our GAE account. For that follow the basic steps given here:</p><ol><li>Get yourself a GAE account and set up an application. you will need the ID.</li><li>Download the <a rel="nofollow" target="_blank" href="http://code.google.com/appengine/downloads.html#Google_App_Engine_SDK_for_Java">GAE SDK for Java</a></li><li>run play war myappname -o myappname-war</li><li>run APPENGINE_SDK_DIR/bin/appcfg update myappname-war/</li><li>Log in to your <a rel="nofollow" target="_blank" href="http://appengine.google.com/">app engine console</a> and check out your application!</li></ol><p>You can check the Online Demo here: <a rel="nofollow" target="_blank" href="http://eazybookmark.appspot.com"><strong>http://eazybookmark.appspot.com</strong></a></p><h2>Download full Source Code</h2><p><a href="http://viralpatel.net/blogs/download/play/eazybookmark.zip">Click here to download eazyBookmark application</a></p><div id="relatedpost"><h2  class="related_post_title">Related Posts</h2><ul class="related_post"><li><a href="http://viralpatel.net/blogs/2009/04/tutorial-handle-browser-events-using-jquery-javascript-framework.html" title="Tutorial: Handle browser events using jQuery JavaScript framework">Tutorial: Handle browser events using jQuery JavaScript framework</a></li><li><a href="http://viralpatel.net/blogs/2008/12/ajax-post-method-example-using-javascript-jquery.html" title="AJAX Post Method example using Javascript &#038; jQuery">AJAX Post Method example using Javascript &#038; jQuery</a></li><li><a href="http://viralpatel.net/blogs/2008/12/creating-orkut-style-status-update-div-textbox-using-jquery.html" title="Creating orkut style status update div-textbox using jQuery.">Creating orkut style status update div-textbox using jQuery.</a></li><li><a href="http://viralpatel.net/blogs/2012/01/scroll-fix-header-jquery-facebook.html" title="Facebook Style Scroll Fixed Header in JQuery">Facebook Style Scroll Fixed Header in JQuery</a></li><li><a href="http://viralpatel.net/blogs/2012/01/play-framework-modules.html" title="Play Framework Modules: Divide and Conquer">Play Framework Modules: Divide and Conquer</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/clearable-textbox-jquery.html" title="Create a Clearable TextBox with jQuery">Create a Clearable TextBox with jQuery</a></li></ul></div>]]></content:encoded> <wfw:commentRss>http://viralpatel.net/blogs/2011/01/first-play-framework-gae-siena-application-tutorial-example.html/feed</wfw:commentRss> <slash:comments>14</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>Introduction to HTML5 DOMStorage API with Example</title><link>http://viralpatel.net/blogs/2010/10/introduction-html5-domstorage-api-example.html</link> <comments>http://viralpatel.net/blogs/2010/10/introduction-html5-domstorage-api-example.html#comments</comments> <pubDate>Tue, 12 Oct 2010 09:46:20 +0000</pubDate> <dc:creator>Viral Patel</dc:creator> <category><![CDATA[Featured]]></category> <category><![CDATA[Web 2.0]]></category> <category><![CDATA[domstorage]]></category> <category><![CDATA[html]]></category> <category><![CDATA[html5]]></category><guid isPermaLink="false">http://viralpatel.net/blogs/?p=2105</guid> <description><![CDATA[HTML5 is a standard for structuring and presenting content on the World Wide Web. The new standard incorporates features like video playback and drag-and-drop that have been previously dependent on third-party browser plug-ins such as Adobe Flash and Microsoft Silverlight. HTML5 introduces a number of new elements and attributes that reflect typical usage on modern [...]]]></description> <content:encoded><![CDATA[<p><img src="http://img.viralpatel.net/2010/10/html5-image.jpg" alt="" title="html5-image" width="263" height="138" class="alignright size-full wp-image-2106" />HTML5 is a standard for structuring and presenting content on the World Wide Web. The new standard incorporates features like video playback and drag-and-drop that have been previously dependent on third-party browser plug-ins such as Adobe Flash and Microsoft Silverlight. HTML5 introduces a number of new elements and attributes that reflect typical usage on modern websites. Some of them are semantic replacements for common uses of generic block (<code>&lt;div&gt;</code>) and inline (<code>&lt;span&gt;</code>) elements, for example <code>&lt;nav&gt;</code> (website navigation block) and <code>&lt;footer&gt;</code> (usually referring to bottom of web page or to last lines of html code). Other elements provide new functionality through a standardized interface, such as the multimedia elements <code>&lt;audio&gt;</code> and <code>&lt;video&gt;</code>.</p><p>In addition to specifying markup, HTML5 specifies scripting application programming interfaces (APIs). Existing document object model (DOM) interfaces are extended and de facto features documented.</p><h2>What is DOM Storage?</h2><p>DOM Storage is a way to store meaningful amounts of client-side data in a persistent and secure manner.  It is a W3C draft which covers exactly how saving information on the client-side should be done. It was initially part of the HTML 5 specification, but was then taken out to be independent. Web Storage, or the somewhat confusing popular name DOM Storage, is a great way to save information for the current session and window, or for returning users.</p><p>The DOM Storage provides mechanism to securely store data in the form of key/value pairs and later retrieve to use. The main goal of this feature is to provide a comprehensive means through which interactive applications can be built (including advanced abilities, such as being able to work &#8220;offline&#8221; for extended periods of time).</p><p>DOM Storage provides a powerful way of storing and retrieving data at client side using JavaScript like APIs which are easy to use.</p><h2>Scope of DOM Storage</h2><p>DOM Storage provides different mechanism to store the client data using in-built storage objects which provides wide range of scope. For example, using DOM Storage it is possible to store data for a Session of user request, or for all the pages of a website.</p><p>DOMStorage storage mechanism is accessed by global variables of <code>window</code> object. Following are the objects available which provides different scope of data storage.</p><h3>sessionStorage</h3><p>The <code>sessionStorage</code> object can be accessed by directly referencing it by name of through <code>window.sessionStorage</code>. This is a global object (<code>sessionStorage</code>) that maintains a storage area that&#8217;s available for the duration of the page session. A page session lasts for as long as the browser is open. Opening a page in a new tab or window will cause a new session to be initiated. Note that <code>sessionStorage</code> can survive browser restart thus it is most useful for hanging on to temporary data that should be saved and restored if the browser is accidentally refreshed.</p><p><strong>Example:</strong> Save a string value &#8220;Hello, World&#8221; and display it on browser refresh.</p><pre class="brush: jscript; title: ; notranslate">
//Store the data in sessionStorage object
 sessionStorage.hello = “Hello, World!”; 

 //Retrieve the data from sessionStorage object on
 //browser refresh and display it
 window.onload = function() {
     if(sessionStorage.hello)
         alert(sessionStorage.hello);
 }
</pre><h3>localStorage</h3><p>The <code>localStorage</code> object is useful when one wants to store data that spans multiple windows and persists beyond the current session. The <code>localStorage</code> provides persistent storage area for domains.</p><p>For example: data stored at <code>localStorage['viralpatel.net']</code> can be retrieved by any script hosted at level Viralpatel.net. Similarly data stored at <code>localStorage['net']</code> can be accessed by scripts at any .net TLD level websites. Data stored as <code>localStorage['']</code> can be accessed by all the pages on all sites.</p><p><strong>Example:</strong> Following script will store a value hello at Viralpatel.net level. Thus all the scripts hosted at Viralpatel.net and its sub-domain level can both read and write the values.</p><pre class="brush: jscript; title: ; notranslate">
 //Store the data in localStorage object
 localStorage['viralpatel.net'].hello = &quot;Hello, World!&quot;;
</pre><h2>DOM Storage API</h2><p>DOM Storage objects sessionStorage and localStorage provides certain useful properties and methods API. Following are the list of such APIs.</p><ul><li><code>getItem()</code> Method – Get the value of item passed as key to the method</li><li><code>length</code> Property – Returns the length of number of items</li><li><code>remainingSpace</code> Property – Return the remaining storage space in bytes, for the storage object</li><li><code>clear()</code> Method – Remove all the key/value pairs from DOM Storage</li><li><code>key()</code> Method – Retrieves the key at specified index</li><li><code>removeItem()</code> Method – Remove the key/value pair from DOM Storage</li><li><code>setItem()</code> Method – Sets a key/value pair</li></ul><h2>Comparing HTTP Cookies with DOM Storage</h2><p>Following are few comparison points between HTTP Cookies and DOM Storage.</p><ul><li>HTTP Cookies can store limited amount of user data (e.g. 4KB) where as modern browser such as IE 8 supports up to 10MB of data being stored with DOM Storage</li><li>Cookies limits the accessibility of data to a certain domain name or a URL path where as DOM Storage can limit the access to a certain domain name, or to domain TLD (like .org) or for given user session.</li><li>The keys stored with HTTP Cookies can be retrieved by using APIs. It is possible to iterate through all the key/value pairs in HTTP Cookies. Whereas in DOM Storage it is not possible to iterate through keys. Data cannot be retrieved unless key is known.</li><li>Data stored as HTTP Cookies can be retrieved at Server as this data is passed with request. Whereas the DOMStorage is more of client data and is not possible to retrieve it directly at server side.</li></ul><h2>Web Browser Support</h2><p>Currently modern browsers such as Firefox 3.5, Internet Explorer 8 and Safari 4 fully support the DOM Storage specification. Following are the list of browsers and their corresponding values such as Storage size, Support, Survive Browser Restart.</p><style>.adtable{border:1px
solid #eee;border-collapse:collapse;width:550px;font-family:Calibri}.adtable
th{border:1px
solid #888;height:30px;background-color:#3275A8;text-align:center;vertical-align:middle;color:white}.adtable
tr{border:1px
solid #888}.adtable
tr.odd{background-color:#eee}.adtable
td{padding:2px;border:1px
solid #888}</style><table class="adtable"><tr><th>Browser</th><th>Storage Size</th><th>Storage Support</th><th>Survives Browser Restart</th></tr><tr><td>Firefox 2</td><td>5 MB</td><td>Yes</td><td>No</td></tr><tr class="odd"><td>Firefox 3</td><td>5 MB</td><td>Yes</td><td>No</td></tr><tr><td>Firefox 3.5</td><td>5 MB</td><td>Yes</td><td>Yes</td></tr><tr class="odd"><td>Safari 3</td><td>-</td><td>No</td><td>No</td></tr><tr><td>Safari 4</td><td>5 MB</td><td>Yes</td><td>Yes</td></tr><tr class="odd"><td>Chrome 2</td><td>-</td><td>No</td><td>No</td></tr><tr><td>IE 8</td><td>10 MB</td><td>Yes</td><td>Yes</td></tr><tr class="odd"><td>Opera 10</td><td>-</td><td>No</td><td>No</td></tr></table><h2>Demo Application</h2><p>Let us demonstrate the use of DOMStorage API and create a demo application.</p><h3>Application Requirement</h3><p>Application has a form called Client Form with some input elements. The requirement is to persist the values of the form in case the page is accidentally refreshed and restore the values back.</p><h3>User Interface</h3><p>Demo application will have a simple input form to enter Client information. The form will have few input fields to capture user input. In case of accidental refresh of the webpage the values should be persevered in the form.<br /> <img src="http://img.viralpatel.net/2010/10/html5-domstorage-api-demo.png" alt="html5-domstorage-api-demo" title="html5-domstorage-api-demo" width="359" height="394" class="aligncenter size-full wp-image-2107" /></p><h3>Source Code</h3><p>Following is the HTML Source code of web page containing Client Form:</p><pre class="brush: xml; title: ; notranslate">
&lt;HTML&gt;
  &lt;HEAD&gt;
    &lt;TITLE&gt;DOMStorage - Sample Application
    &lt;/TITLE&gt;
  &lt;/HEAD&gt;
  &lt;BODY&gt;
    &lt;H2&gt;Client Form
    &lt;/H2&gt;
    &lt;br/&gt;
    &lt;form name=&quot;clientForm&quot; id=&quot;clientForm&quot;&gt;
      &lt;table&gt;
        &lt;tr&gt;
          &lt;td&gt;First Name
          &lt;/td&gt;
          &lt;td&gt;
            &lt;input type=&quot;text&quot; name=&quot;firstname&quot;/&gt;
          &lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
          &lt;td&gt;Last Name
          &lt;/td&gt;
          &lt;td&gt;
            &lt;input type=&quot;text&quot; name=&quot;lastname&quot;/&gt;
          &lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
          &lt;td&gt;Date of Birth
          &lt;/td&gt;
          &lt;td&gt;
            &lt;input type=&quot;text&quot; name=&quot;dob&quot;/&gt;
          &lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
          &lt;td&gt;Gender
          &lt;/td&gt;
          &lt;td&gt;
            &lt;input name=&quot;gender&quot; type=&quot;radio&quot; value=&quot;M&quot;&gt;Male
          &lt;/input&gt;
          &lt;input name=&quot;gender&quot; type=&quot;radio&quot; value=&quot;F&quot;&gt;Female
        &lt;/input&gt;
          &lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
          &lt;td&gt;Designation
          &lt;/td&gt;
          &lt;td&gt;
            &lt;select name=&quot;designation&quot;&gt;
              &lt;option value=&quot;0&quot;&gt;Software Engineer
              &lt;/option&gt;
              &lt;option value=&quot;1&quot;&gt;Sr. Software Engineer
              &lt;/option&gt;
              &lt;option value=&quot;2&quot;&gt;Technical Architect
              &lt;/option&gt;
            &lt;/select&gt;
          &lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
          &lt;td colspan=&quot;2&quot;&gt;
            &lt;br/&gt;
            &lt;input name=&quot;submit&quot; type=&quot;button&quot; value=&quot;Submit&quot;/&gt;
            &lt;input name=&quot;reset&quot; type=&quot;reset&quot; value=&quot;Reset&quot;/&gt;
          &lt;/td&gt;
        &lt;/tr&gt;
      &lt;/table&gt;
    &lt;/form&gt;

&lt;script type=&quot;text/javascript&quot; src=&quot;domstorage-persist.js&quot;&gt;&lt;/script&gt;

  &lt;/BODY&gt;
&lt;/HTML&gt;
</pre><p>Following is JavaScript code (content of domstorage-persist.js)</p><pre class="brush: jscript; title: ; notranslate">
/**
 * Filename: domstorage-persist.js
 * Author: viralpatel.net
 * Description: HTML code independent form persistent
 * Usage:  persist(&lt;form object&gt;);
 */

function persist(form) {

/*
   * In case of page refresh,
   * store the values of form to DOMStorage
   */
    window.onbeforeunload = function () {
        var str = serialize(form);

        try {
            sessionStorage[form.name] = str;
        } catch (e) {}
    }

/*
   * If the form was refreshed and old values are available,
   * restore the old values in form
   */
    window.onload = function () {
        try {
            if (sessionStorage[form.name]) {
                var obj = eval(&quot;(&quot; + sessionStorage[form.name] + &quot;)&quot;);
                for (var i = 0; i &lt; obj.elements.length - 1; i++) {
                    var elementName = obj.elements[i].name;
                    document.forms[obj.formName].elements[obj.elements[i].name].value = obj.elements[i].value;
                }

            }
        } catch (e) {}
    }
}

/*
 * Convert form elements into JSON String
 */

function serialize(form) {
    var serialized = '{ &quot;formName&quot;:&quot;' + form.name + '&quot;, &quot;elements&quot;: [';
    for (var i = 0; i &lt; form.elements.length; i++) {

        serialized += '{';
        serialized += '&quot;name&quot;:&quot;' + form[i].name + '&quot;,';
        serialized += '&quot;value&quot;:&quot;' + form[i].value + '&quot;';
        serialized += '},';
    }
    serialized += '{&quot;name&quot;:0, &quot;value&quot;:0}';
    serialized += '] }';
    return serialized;
}

/*
 * Make the Client Form persistable.
 * i.e. Persist its values in case of page refresh
 */
persist(document.clientForm);
</pre><h2>References</h2><ul><li>W3C: Web Storage draft standard (<a rel="nofollow" target="_blank" href="http://dev.w3.org/html5/webstorage/">http://dev.w3.org/html5/webstorage/</a>)</li><li>Mozilla Developer Center: DOM Storage (<a rel="nofollow" target="_blank" href="https://developer.mozilla.org/En/DOM:Storage#Description">https://developer.mozilla.org/En/DOM:Storage#Description</a>)</li><li>MSDN: Introduction to DOM Storage ( <a rel="nofollow" target="_blank" href="http://msdn.microsoft.com/en-us/library/cc197062(VS.85).aspx#_dom">http://msdn.microsoft.com/en-us/library/cc197062(VS.85).aspx#_dom</a>)</li></ul><h2>Further Reading</h2><p>The given article focuses on the latest mechanism of DOMStorage being standardized by World Wide Web Consortium (W3C) as part of HTML5. There are few other similar technologies available which can be leveraged to store offline data in browser. Users who are interested in browser based storage are highly advisable to read about following technologies.</p><ul><li>HTTP Cookies (<a rel="nofollow" target="_blank" href="http://www.microsoft.com/info/cookies.mspx">http://www.microsoft.com/info/cookies.mspx</a>)</li><li>DOMCached &#8211; A memcached like caching system for JavaScript using DOM storage (<a rel="nofollow" target="_blank" href="http://www.domcached.com">http://www.domcached.com</a>)</li><li>Google Gears (<a rel="nofollow" target="_blank" href="http://gears.google.com/">http://gears.google.com/</a>)</li><li>Adobe Flash – Local Shared Objects (<a rel="nofollow" target="_blank" href="http://www.adobe.com/products/flashplayer/articles/lso/">http://www.adobe.com/products/flashplayer/articles/lso/</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/2009/05/html-5-the-new-html-kid-on-the-block.html" title="HTML 5: The new HTML kid on the block!">HTML 5: The new HTML kid on the block!</a></li><li><a href="http://viralpatel.net/blogs/2010/06/facebook-facts-you-didnt-know.html" title="Facebook: Facts you probably didnt know">Facebook: Facts you probably didnt know</a></li><li><a href="http://viralpatel.net/blogs/2010/01/oembed-open-format-web-developers.html" title="oEmbed: An Open Format Every Developer Should Know About">oEmbed: An Open Format Every Developer Should Know About</a></li><li><a href="http://viralpatel.net/blogs/2009/11/disable-back-button-browser-javascript.html" title="Disable Back Button in Browser using JavaScript">Disable Back Button in Browser using JavaScript</a></li><li><a href="http://viralpatel.net/blogs/2009/09/gartners-hype-cycle-special-report-2009.html" title=" Gartner&#8217;s Hype Cycle Special Report for 2009"> Gartner&#8217;s Hype Cycle Special Report for 2009</a></li><li><a href="http://viralpatel.net/blogs/2009/05/gravatar-manage-your-user-avatars-for-free.html" title="Gravatar: Manage your user avatars for free">Gravatar: Manage your user avatars for free</a></li><li><a href="http://viralpatel.net/blogs/2009/05/web-30-is-around-the-corner.html" title="Web 3.0 is around the corner !">Web 3.0 is around the corner !</a></li></ul></div>]]></content:encoded> <wfw:commentRss>http://viralpatel.net/blogs/2010/10/introduction-html5-domstorage-api-example.html/feed</wfw:commentRss> <slash:comments>1</slash:comments> </item> <item><title>Spring 3 MVC: Internationalization &amp; Localization Tutorial with Example</title><link>http://viralpatel.net/blogs/2010/07/spring-3-mvc-internationalization-i18n-localization-tutorial-example.html</link> <comments>http://viralpatel.net/blogs/2010/07/spring-3-mvc-internationalization-i18n-localization-tutorial-example.html#comments</comments> <pubDate>Wed, 14 Jul 2010 12:50:17 +0000</pubDate> <dc:creator>Viral Patel</dc:creator> <category><![CDATA[Featured]]></category> <category><![CDATA[Spring]]></category> <category><![CDATA[Spring 3 MVC]]></category> <category><![CDATA[internationalization]]></category> <category><![CDATA[spring mvc]]></category> <category><![CDATA[spring-3-mvc-series]]></category><guid isPermaLink="false">http://viralpatel.net/blogs/?p=2088</guid> <description><![CDATA[Welcome to Part 5 for Spring 3.0 MVC Series. In previous article we saw how to configure Tiles framework with Spring 3 MVC application. We used org.springframework.web.servlet.view.tiles2.TilesConfigurer class in bean definition to define the tiles configuration file. This divided our HelloWorld Spring MVC application in sections such as header, footer etc. In this part we [...]]]></description> <content:encoded><![CDATA[<p>Welcome to Part 5 for <strong>Spring 3.0 MVC Series</strong>. In <a href="http://viralpatel.net/blogs/2010/07/spring-3-mvc-tiles-plugin-tutorial-example-eclipse.html">previous article</a> we saw how to configure Tiles framework with Spring 3 MVC application. We used <code>org.springframework.web.servlet.view.tiles2.TilesConfigurer</code> class in bean definition to define the tiles configuration file. This divided our HelloWorld Spring MVC application in sections such as header, footer etc.</p><p>In this part we will discuss about Internationalization (I18N) and Localization (L10N) in Spring 3.0 MVC. We will add i18n support followed by l10n to our HelloWorld Spring application that we created in previous tutorials in this series. I strongly recommend you to go through previous articles and download the source code of our sample application.</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>What is i18n and L10n?</h2><p>In computing, internationalization and localization are means of adapting computer software to different languages and regional differences. Internationalization is the process of designing a software application so that it can be adapted to various languages and regions without engineering changes. Localization is the process of adapting internationalized software for a specific region or language by adding locale-specific components and translating text.</p><p>The terms are frequently abbreviated to the numeronyms  i18n (where 18 stands for the number of letters between the first i and last n in internationalization) and L10n respectively, due to the length of the words. The capital L in L10n helps to distinguish it from the lowercase i in i18n.</p><h2>Our Goal</h2><p>Our goal is to add Internationalization and Localization support to our Spring MVC application. Once finished our app will look like.<br /> <img src="http://img.viralpatel.net/2010/07/contact-manager-screen-de.png" alt="contact-manager-screen-de" title="contact-manager-screen-de" width="324" height="356" class="aligncenter size-full wp-image-2089" /></p><p>We will add two languages support to our application: English and German. Depending on the locale setting of users browser, the appropriate language will be selected. Also user will be able to select the language from top-right corner of the application.</p><h2>Message Resouces File</h2><p>We will create two properties file which will contain all the messages to be displayed in the application. These files are kept in a source folder called &#8220;resources&#8221;. Create a source folder in your project by <strong>Right click on Project name &gt; New &gt; Source Folder</strong> and name it <strong>resources</strong>.<br /> <img src="http://img.viralpatel.net/2010/07/message-resources-properties-spring-mvc.png" alt="message-resources-properties-spring-mvc" title="message-resources-properties-spring-mvc" width="217" height="119" class="aligncenter size-full wp-image-2090" /></p><p>Create two files <code>messages_en.properties</code> and <code>messages_de.properties</code> in this folder and copy following content into it.</p><p><em>File: 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><p><em>File: resources/messages_de.properties</em></p><pre class="brush: xml; title: ; notranslate">
label.firstname=Vorname
label.lastname=Familiename
label.email=Email
label.telephone=Telefon
label.addcontact=Addieren Kontakt 

label.title=Kontakt Manager
label.menu=Men&amp;#252;

label.footer=&amp;copy; ViralPatel.net
</pre><h2>Configuring Internationalization (i18n) / Localization (L10n) in Spring MVC</h2><p>Now we have created message resource properties for our application. We need to declare these files in spring configuration file. We will use class <code>org.springframework.context.support.ReloadableResourceBundleMessageSource</code> to define the message resources.</p><p>Also, note that we will provide a feature where user will be able to select language for the application. This is implemented by using <code>org.springframework.web.servlet.i18n.LocaleChangeInterceptor</code> class. The LocaleChangeInterceptor class will intercept any changes in the locale. These changes are then saved in cookies for future request. <code>org.springframework.web.servlet.i18n.CookieLocaleResolver</code> class will be used to store the locale changes in cookies.</p><p>Add following code in the 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;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;localeChangeInterceptor&quot;
		class=&quot;org.springframework.web.servlet.i18n.LocaleChangeInterceptor&quot;&gt;
		&lt;property name=&quot;paramName&quot; value=&quot;lang&quot; /&gt;
	&lt;/bean&gt;

	&lt;bean id=&quot;localeResolver&quot;
		class=&quot;org.springframework.web.servlet.i18n.CookieLocaleResolver&quot;&gt;
		&lt;property name=&quot;defaultLocale&quot; value=&quot;en&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;ref bean=&quot;localeChangeInterceptor&quot; /&gt;
		&lt;/property&gt;
	&lt;/bean&gt;
</pre><p>Note that in above configuration we have defined basename property in messageSource bean to classpath:messages. By this, spring will identify that the message resource  message_<locale> will be used in this application.</p><h2>Change the View &#8211; The JSPs</h2><p>Now as we have created two message resources files and configured it in Spring MVC, we will use these messages in the JSP files. Open all the JSP files of our demo application and update with following code.</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;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;
</pre><p><em>File:WebContent/WEB-INF/jsp/menu.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;p&gt;&lt;spring:message code=&quot;label.menu&quot;/&gt;&lt;/p&gt;
</pre><p><em>File:WebContent/WEB-INF/jsp/footer.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;spring:message code=&quot;label.footer&quot;/&gt;
</pre><p><em>File:WebContent/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;html&gt;
&lt;head&gt;
	&lt;title&gt;Spring 3 MVC Series - Contact Manager&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;

&lt;form:form method=&quot;post&quot; action=&quot;addContact.html&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;lastname&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;lastname&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;/body&gt;
&lt;/html&gt;
</pre><p>Note that in above JSP, we used <code>&lt;spring:message&gt;</code> tag to display the message from resource bundle.</p><p>One thing that we must note here is that in header.jsp file, we have specified two links to select language. The link sets a request parameter <strong>?lang=<language code></strong> when user click on this link. Note that spring identifies this request parameter by using <code>LocaleChangeInterceptor</code> interceptor and change the local accordingly. Also note that while configuring <code>LocaleChangeInterceptor</code> in spring-servlet.xml file, we have specified property &#8220;paramName&#8221; with value &#8220;lang&#8221;</p><pre class="brush: xml; title: ; notranslate">
&lt;property name=&quot;paramName&quot; value=&quot;lang&quot; /&gt;
</pre><p>Thus the Spring framework will look for a parameter called &#8220;lang&#8221; from request.</p><h2>That&#8217;s All Folks</h2><p>That&#8217;s pretty much it <img src='http://viralpatel.net/blogs/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> We just added Internationalization and Localization 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/contact-manager-screen-en.png" alt="contact-manager-screen-en" title="contact-manager-screen-en" width="320" height="355" class="aligncenter size-full wp-image-2091" /></p><p><img src="http://img.viralpatel.net/2010/07/contact-manager-screen-de.png" alt="contact-manager-screen-de" title="contact-manager-screen-de" width="324" height="356" class="aligncenter size-full wp-image-2089" /></p><h2>Download Source Code</h2><p><a href="http://viralpatel.net/blogs/download/spring/spring-3-mvc-series/Spring3MVC-part5.zip">Click here to download Source Code (10.2kb)</a></p><h2>Moving On</h2><p>Today 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. In the next part we will discuss Themes in Spring MVC and how to implement it. I hope you liked this article. Feel free to post your queries and comments in comment section.</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/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-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/07/spring-3-mvc-internationalization-i18n-localization-tutorial-example.html/feed</wfw:commentRss> <slash:comments>49</slash:comments> </item> <item><title>Invisible Indexes in Oracle 11g</title><link>http://viralpatel.net/blogs/2010/06/invisible-indexes-in-oracle-11g.html</link> <comments>http://viralpatel.net/blogs/2010/06/invisible-indexes-in-oracle-11g.html#comments</comments> <pubDate>Mon, 21 Jun 2010 12:59:02 +0000</pubDate> <dc:creator>Keshaba Kuntulu</dc:creator> <category><![CDATA[Database]]></category> <category><![CDATA[Featured]]></category> <category><![CDATA[Oracle]]></category> <category><![CDATA[database indexes]]></category><guid isPermaLink="false">http://viralpatel.net/blogs/?p=2061</guid> <description><![CDATA[The effective usage of an index is always a big question. There are instances in production environments, where an index may help the performance of just a single query, while it can degrade the performance of a number of queries. Always the Optimizer can’t guarantee the best suitable index required for the query in an [...]]]></description> <content:encoded><![CDATA[<p><img src="http://img.viralpatel.net/2010/06/oracle-invisible-index-11g.jpg" alt="oracle-invisible-index-11g" title="oracle-invisible-index-11g" width="210" height="196" class="alignright size-full wp-image-2062" />The effective usage of an index is always a big question. There are instances in production environments, where an index may help the performance of just a single query, while it can degrade the performance of a number of queries. Always the Optimizer can’t guarantee the best suitable index required for the query in an environment which is cluttered by too many indexes on a table.</p><p>One of the older solutions is to determine the effective usage of indexes in the database. Once the monitoring usage clause for the index is enabled, we can determine the usage of the index by querying <code>v$object_usage</code> data dictionary view. The index monitoring time again depends on the application, database usage and business hours. It varies from case to case. Some applications might require a few hours for monitoring the usage of indexes. Some might require even months to determine the perfect indexes that need to be retained and the ones that need to be detained.</p><p>If the usage of the index is at all, or it results a bad performance to other queries, one can easily drop the index. However in future, if some adhoc queries require the index badly (where the index dropped would have increased the performance dramatically), we need to think reinstating the index again. The recreation of an index is a very expensive one and requires a lot of database resources and consumes a lot of time as well.</p><p>One of the new features of oracle 11g, Invisible indexes is a perfect solution to the above problem. An index can be made invisible to the Optimizer, so that the optimizer can’t see it. If an adhoc query requires the usage of the index it can explicitly specify the index as a part of hint.</p><p>The following example demonstrates invisible index better.</p><pre class="brush: sql; title: ; notranslate">
SQL&gt; desc employee;
 Name                                      Null?    Type
 ----------------------------------------- -------- ---------

 EMPID                                              NUMBER
 DEPTNO                                             NUMBER
 EMPNAME                                            VARCHAR2(30)
 MGR_NAME                                           VARCHAR2(30)
 ADDRESS                                            VARCHAR2(100)
</pre><p>Let us create an index on EMPID column of the employee table.</p><pre class="brush: sql; title: ; notranslate">
SQL&gt; create index idx_empid on employee(empid);

Index created.
</pre><p>After creating the index let us fire this simple query:</p><pre class="brush: sql; title: ; notranslate">
SQL&gt; select * from employee where empid = 1001;

Execution Plan
-----------------------------------------------------------------------------------------
| Id  | Operation                   | Name      | Rows  | Bytes | Cost (%CPU)| Time     |
-----------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |           |     1 |   112 |     2   (0)| 00:00:01 |
|*  1 |  TABLE ACCESS BY INDEX ROWID| EMPLOYEE  |     1 |   112 |     2   (0)| 00:00:01 |
|*  2 |   INDEX RANGE SCAN          | IDX_EMPID |     1 |       |     1   (0)| 00:00:01 |
-----------------------------------------------------------------------------------------
</pre><p>The above execution plan confirms the usage of the index which we created on the empid column. Now let us make this index invisible to the optimizer. An index can be made invisible using the simple ALTER statement.</p><pre class="brush: sql; title: ; notranslate">
SQL&gt; alter index idx_empid invisible;

Index altered.
</pre><p>The invisibility status of the index can be checked by using the following query:</p><pre class="brush: sql; title: ; notranslate">
SQL&gt; select visibility from user_indexes where index_name = 'IDX_EMPID';

VISIBILITY
---------
INVISIBLE
</pre><p>Now let us fire the same query on the employee table. The below explain plan shows the index became invisible to the optimizer and a full table scan is performed instead of index scan.</p><pre class="brush: sql; title: ; notranslate">
SQL&gt; select * from employee where empid = 1001;

Execution Plan

------------------------------------------------------------------------------
| Id  | Operation         | Name     | Rows  | Bytes | Cost (%CPU)| Time     |
------------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |          |     1 |   112 |     3   (0)| 00:00:01 |
|*  1 |  TABLE ACCESS FULL| EMPLOYEE |     1 |   112 |     3   (0)| 00:00:01 |
------------------------------------------------------------------------------
</pre><p>Let us now try to give an index hint in our above query.</p><pre class="brush: sql; title: ; notranslate">
SQL&gt; select /*+ index(idx_empid) */ * from employee where empid = 1001;

Execution Plan

-----------------------------------------------------------------------------------------
| Id  | Operation                   | Name      | Rows  | Bytes | Cost (%CPU)| Time     |
-----------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |           |     1 |   112 |     2   (0)| 00:00:01 |
|*  1 |  TABLE ACCESS BY INDEX ROWID| EMPLOYEE  |     1 |   112 |     2   (0)| 00:00:01 |
|*  2 |   INDEX RANGE SCAN          | IDX_EMPID |     1 |       |     1   (0)| 00:00:01 |
-----------------------------------------------------------------------------------------
</pre><p>After giving the hint, the optimizer used the index once again and performed an index scan. From the above example it is clear that, when an index can be made invisible only to the Optimizer and not to the user. User can still use it by giving a hint to the optimizer where ever it is required.<br /> Alternatively, there is a session level parameter, <strong>optimizer_use_invisible_indexes</strong>. This parameter can be set to <strong>TRUE</strong>, so that all the invisible indexes can be made visible to the optimizer.</p><pre class="brush: sql; title: ; notranslate">
SQL&gt; alter session set optimizer_use_invisible_indexes = true;
</pre><h2>Advantages of Invisble Indexes</h2><ol><li>Invisible indexes can help to a great extent, in testing scenarios where the optimizer behavior needs to be tested without the index. This does not need dropping and recreating the index.</li><li>Indexes can be created for certain adhoc queries (queries that are fired very infrequently) and can be made invisible after the usage.</li></ol><p>However, invisible indexes behave the same like a normal index towards the DML operations. They need to be updated with each DML operation.</p><div id="relatedpost"><h2  class="related_post_title">Related Posts</h2><ul class="related_post"><li><a href="http://viralpatel.net/blogs/2010/02/understanding-primary-keypk-constraint-in-oracle.html" title="Understanding Primary Key(PK) Constraint in Oracle">Understanding Primary Key(PK) Constraint in Oracle</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><li><a href="http://viralpatel.net/blogs/2010/07/generating-random-data-in-oracle.html" title="Generating Random Data in Oracle">Generating Random Data in Oracle</a></li><li><a href="http://viralpatel.net/blogs/2010/06/deleting-duplicate-rows-in-oracle.html" title="Deleting Duplicate Rows in Oracle">Deleting Duplicate Rows in Oracle</a></li><li><a href="http://viralpatel.net/blogs/2010/06/oracle-data-compression.html" title="Oracle Data Compression">Oracle Data Compression</a></li><li><a href="http://viralpatel.net/blogs/2009/05/fetch-random-rows-from-database-mysql-oracle-ms-sql-postgresql-example.html" title="Fetch Random rows from Database (MySQL, Oracle, MS SQL, PostgreSQL)">Fetch Random rows from Database (MySQL, Oracle, MS SQL, PostgreSQL)</a></li><li><a href="http://viralpatel.net/blogs/2009/04/full-text-search-using-mysql-full-text-search-capabilities.html" title="Full-Text Search using MySQL: Full-Text Search Capabilities">Full-Text Search using MySQL: Full-Text Search Capabilities</a></li></ul></div>]]></content:encoded> <wfw:commentRss>http://viralpatel.net/blogs/2010/06/invisible-indexes-in-oracle-11g.html/feed</wfw:commentRss> <slash:comments>3</slash:comments> </item> <item><title>Spring 3 MVC – Introduction to Spring 3 MVC Framework</title><link>http://viralpatel.net/blogs/2010/06/tutorial-spring-3-mvc-introduction-spring-mvc-framework.html</link> <comments>http://viralpatel.net/blogs/2010/06/tutorial-spring-3-mvc-introduction-spring-mvc-framework.html#comments</comments> <pubDate>Mon, 21 Jun 2010 08:03:59 +0000</pubDate> <dc:creator>Viral Patel</dc:creator> <category><![CDATA[Featured]]></category> <category><![CDATA[Spring]]></category> <category><![CDATA[Spring 3 MVC]]></category> <category><![CDATA[framework]]></category> <category><![CDATA[spring mvc]]></category> <category><![CDATA[spring-3-mvc-series]]></category> <category><![CDATA[Tutorial]]></category><guid isPermaLink="false">http://viralpatel.net/blogs/?p=2053</guid> <description><![CDATA[Introduction to Spring 3 MVC Framework Spring MVC is the web component of Spring&#8217;s framework. It provides a rich functionality for building robust Web Applications. The Spring MVC Framework is architected and designed in such a way that every piece of logic and functionality is highly configurable. Also Spring can integrate effortlessly with other popular [...]]]></description> <content:encoded><![CDATA[<h2>Introduction to Spring 3 MVC Framework</h2><p>Spring MVC is the web component of Spring&#8217;s framework. It provides a rich functionality for building robust Web Applications. The Spring MVC Framework is architected and designed in such a way that every piece of logic and functionality is highly configurable. Also Spring can integrate effortlessly with other popular Web Frameworks like Struts, WebWork, Java Server Faces and Tapestry. It means that you can even instruct Spring to use any one of the Web Frameworks. More than that Spring is not tightly coupled with Servlets or JSP to render the View to the Clients. Integration with other View technologies like Velocity, Freemarker, Excel  or Pdf is also possible now.<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><p>In Spring Web MVC you can use any object as a command or form-backing object; you do not need to implement a framework-specific interface or base class. Spring&#8217;s data binding is highly flexible: for example, it treats type mismatches as validation errors that can be evaluated by the application, not as system errors. Thus you need not duplicate your business objects&#8217; properties as simple, untyped strings in your form objects simply to handle invalid submissions, or to convert the Strings properly. Instead, it is often preferable to bind directly to your business objects.</p><h2>Request Processing Lifecycle</h2><p><img src="http://img.viralpatel.net/2010/06/spring-mvc-request-process-lifecycle.png" alt="spring-mvc-request-process-lifecycle" title="spring-mvc-request-process-lifecycle" width="473" height="296" class="aligncenter size-full wp-image-2055" /><br /> Image courtesy: <a rel="nofollow"  target="_blank" href="http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/mvc.html">Springsource</a></p><p>Spring&#8217;s web MVC framework is, like many other web MVC frameworks, request-driven, designed around a central servlet that dispatches requests to controllers and offers other functionality that facilitates the development of web applications. Spring&#8217;s <code>DispatcherServlet</code> is completely integrated with Spring IoC container and allows us to use every other feature of Spring.</p><p>Following is the Request process lifecycle of Spring 3.0 MVC:</p><ol><li>The client sends a request to web container in the form of http request.</li><li>This incoming request is intercepted by <strong>Front controller</strong> (DispatcherServlet) and it will then tries to find out appropriate <strong>Handler Mappings</strong>.</li><li>With the help of Handler Mappings, the DispatcherServlet will dispatch the request to appropriate Controller.</li><li>The Controller tries to process the request and returns the Model and View object in form of <strong>ModelAndView</strong> instance to the Front Controller.</li><li>The Front Controller then tries to resolve the View (which can be JSP, Freemarker, Velocity etc) by consulting the <strong>View Resolver</strong> object.</li><li>The selected view is then rendered back to client.</li></ol><h2>Features of Spring 3.0</h2><ul><li>Spring 3.0 framework supports Java 5. It provides annotation based configuration support. Java 5 features such as generics, annotations, varargs etc can be used in Spring.</li><li>A new expression language Spring Expression Language SpEL is being introduced. The Spring Expression Language  can be used while defining the XML and Annotation based bean definition.</li><li>Spring 3.0 framework supports REST web services.</li><li>Data formatting can never be so easy. Spring 3.0 supports annotation based formatting. We can now use the  @DateFimeFormat(iso=ISO.DATE) and @NumberFormat(style=Style.CURRENCY) annotations to convert the date  and currency formats.</li><li>Spring 3.0 has started support to JPA 2.0.</li></ul><h2>Configuring Spring 3.0 MVC</h2><p>The entry point of Spring 3.0 MVC is the <code>DispatcherServlet</code>. DispatcherServlet is a normal servlet class which implements <code>HttpServlet</code> base class. Thus we need to configure it in <code>web.xml</code>.</p><pre class="brush: xml; title: ; notranslate">
&lt;web-app&gt;

    &lt;servlet&gt;
        &lt;servlet-name&gt;example&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;example&lt;/servlet-name&gt;
        &lt;url-pattern&gt;*.html&lt;/url-pattern&gt;
    &lt;/servlet-mapping&gt;
&lt;/web-app&gt;
</pre><p>In above code snippet, we have configure DispatcherServlet in web.xml. Note that we have mapped *.html url pattern with example DispatcherServlet. Thus any url with *.html pattern will call Spring MVC Front controller.<br /> <img src="http://img.viralpatel.net/2010/06/spring-architecture.png" alt="spring-3-mvc-architecture" title="spring-3-mvc-architecture" width="390" height="273" class="aligncenter size-full wp-image-2059" /><br /> Image courtesy: <a rel="nofollow"  target="_blank" href="http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/mvc.html">Springsource</a><br /> Once the DispatcherServlet is initialized, it will looks for a file names <code>[servlet-name]-servlet.xml</code> in WEB-INF folder of web application. In above example, the framework will look for file called <code>example-servlet.xml</code>.</p><p>Note the above architecture diagram. The <code>WebApplicationContext</code> specified in above diagram is an extension of the plain <code>ApplicationContext</code> with some extra feature necessary for web applications. The WebApplicationContext is capable of resolving themes and it is also associated with corresponding servlet. The WebApplicationContext is bound in the ServletContext, and by using static methods on the RequestContextUtils class you can always look up the WebApplicationContext.</p><h2>Moving On</h2><p>Now that we have idea about architecture of Spring 3.0 MVC framework and its lifecycle, in the <a rel="_new" href="http://viralpatel.net/blogs/2010/06/spring-3-mvc-create-hello-world-application-spring-3-mvc.html">next part we will create a working Spring 3.0 Hello World application</a> from scratch.</p><div id="relatedpost"><h2  class="related_post_title">Related Posts</h2><ul class="related_post"><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/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/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/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/06/tutorial-spring-3-mvc-introduction-spring-mvc-framework.html/feed</wfw:commentRss> <slash:comments>28</slash:comments> </item> <item><title>Writing a URL Shortner in Java Struts2 &amp; Hibernate</title><link>http://viralpatel.net/blogs/2010/02/create-url-shortner-in-java-struts2-hibernate.html</link> <comments>http://viralpatel.net/blogs/2010/02/create-url-shortner-in-java-struts2-hibernate.html#comments</comments> <pubDate>Wed, 17 Feb 2010 09:16:40 +0000</pubDate> <dc:creator>Viral Patel</dc:creator> <category><![CDATA[Featured]]></category> <category><![CDATA[Hibernate]]></category> <category><![CDATA[Struts 2]]></category> <category><![CDATA[Struts2]]></category><guid isPermaLink="false">http://viralpatel.net/blogs/?p=2029</guid> <description><![CDATA[This is an attempt to create a simple URL shortner service in pure JEE with Struts2 and Hibernate. Creating Base Framework I always have Basic framework ready which gives a kick start to the web app development. You don&#8217;t have to hassle about different configuration issues/jar file issues etc. Let us start with creating sample [...]]]></description> <content:encoded><![CDATA[<p>This is an attempt to create a simple URL shortner service in pure JEE with Struts2 and Hibernate.</p><p><img src="http://img.viralpatel.net/2010/02/shorty-url-shortner-struts2-hibernate.png" alt="shorty-url-shortner-struts2-hibernate" title="shorty-url-shortner-struts2-hibernate" width="523" height="189" class="aligncenter size-full wp-image-2031" /></p><h2>Creating Base Framework</h2><p>I always have Basic framework ready which gives a kick start to the web app development. You don&#8217;t have to hassle about different configuration issues/jar file issues etc. Let us start with creating sample base framework for our project. We will use Struts2 and Hibernate for this implementation.<br /> First lets create a Dynamic web project in eclipse.<br /> <img alt="Dynamic web project" src="http://img.viralpatel.net/2008/12/eclipse-new-project-struts-example.png" title="Dynamic web project" class="aligncenter" width="369" height="365" /><br /> We will name our project <strong>Shorty</strong>.</p><p>Then, we will add all the required Jar files for our project. Following is the list of Jars that I have included in the <strong>WEB-INF/lib</strong> folder.<br /> <img src="http://img.viralpatel.net/2010/02/shorty-struts2-hibernate-jars.png" alt="shorty-struts2-hibernate-jars" title="shorty-struts2-hibernate-jars" width="232" height="375" class="aligncenter size-full wp-image-2033" /></p><p>You can download all of the above JARs from <a rel="nofollow" target="_blank" href="http://www.ibiblio.org/maven/">http://www.ibiblio.org/maven/</a></p><p>Now lets us change the web.xml file and add Struts filter. This will add Struts support in our base framework.<br /> Following will be the web.xml content.<br /> <strong>WEB-INF/web.xml</strong></p><pre class="brush: xml; title: ; notranslate">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;web-app id=&quot;WebApp_ID&quot; version=&quot;2.4&quot;
	xmlns=&quot;http://java.sun.com/xml/ns/j2ee&quot;
	xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
	xsi:schemaLocation=&quot;http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd&quot;&gt;
	&lt;display-name&gt;Go&lt;/display-name&gt;
	&lt;welcome-file-list&gt;
		&lt;welcome-file&gt;index.jsp&lt;/welcome-file&gt;
	&lt;/welcome-file-list&gt;
 	&lt;filter&gt;
		&lt;filter-name&gt;struts2&lt;/filter-name&gt;
		&lt;filter-class&gt;
			org.apache.struts2.dispatcher.FilterDispatcher
		&lt;/filter-class&gt;
	&lt;/filter&gt;
	&lt;filter-mapping&gt;
		&lt;filter-name&gt;struts2&lt;/filter-name&gt;
		&lt;url-pattern&gt;/*&lt;/url-pattern&gt;
	&lt;/filter-mapping&gt;

&lt;/web-app&gt;
</pre><p>Now create a source folder called <strong>resources</strong>. Right click on your project in Project explorer -> New -> Source Folder.</p><p>Create a file hibernate.cfg.xml in the resources folder. This will be the configuration file of Hibernate which contains database connection strings and other related data.</p><p><strong>resources/hibernate.cfg.xml</strong></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 3.0//EN&quot;
        &quot;http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd&quot;&gt;

&lt;hibernate-configuration&gt;

	&lt;session-factory&gt;

		&lt;property name=&quot;connection.driver_class&quot;&gt;
			com.mysql.jdbc.Driver
		&lt;/property&gt;
		&lt;property name=&quot;connection.url&quot;&gt;
			jdbc:mysql://localhost:3306/shorty
		&lt;/property&gt;
		&lt;property name=&quot;connection.username&quot;&gt;username&lt;/property&gt;
		&lt;property name=&quot;connection.password&quot;&gt;password&lt;/property&gt;

		&lt;property name=&quot;connection.pool_size&quot;&gt;1&lt;/property&gt;
		&lt;property name=&quot;dialect&quot;&gt;
			org.hibernate.dialect.MySQLDialect
		&lt;/property&gt;
		&lt;property name=&quot;current_session_context_class&quot;&gt;thread&lt;/property&gt;
		&lt;property name=&quot;cache.provider_class&quot;&gt;
			org.hibernate.cache.NoCacheProvider
		&lt;/property&gt;
		&lt;property name=&quot;show_sql&quot;&gt;true&lt;/property&gt;
		&lt;property name=&quot;hbm2ddl.auto&quot;&gt;update&lt;/property&gt;

	&lt;/session-factory&gt;

&lt;/hibernate-configuration&gt;
</pre><p>Also lets create package structure for the source code in our base framework. We will create few packages in <strong>src</strong> folder.<br /> <img src="http://img.viralpatel.net/2010/02/url-shortner-base-framework-package.png" alt="url-shortner-base-framework-package" title="url-shortner-base-framework-package" width="203" height="84" class="aligncenter size-full wp-image-2035" /></p><p>Now we are ready with a basic framework that has Hibernate and Struts2 support. This can now be used to create any application using these two technologies.</p><p>Let us start with creating database design for our simplest URL shortner.</p><h2>Database Design for URL Shortner</h2><p>Our requirement is very simple. We will have a single table in database that holds the value for URLs and its shortcode. Following will be the DDL for LINKS table. Note that we will also track number of clicks on each URL.</p><pre class="brush: sql; title: ; notranslate">
CREATE TABLE LINKS
(
	id 		INT PRIMARY KEY AUTO_INCREMENT,
	shortcode 	VARCHAR(20),
	url 		VARCHAR(255),
	clicks		INT DEFAULT 0,
	created	TIMESTAMP DEFAULT NOW()
);
</pre><h2>Adding logic to create shortcode</h2><p>URL Shortner is all about creating short codes for a long url. The logic that we will use to create a short code is simple. We will add URL into database table with auto generating primary key. This primary key will be a unique number. Then we convert this number to a string representation of base48 with characters 0 to 9 a to z and A to Z. Following is the logic for this.</p><pre class="brush: java; title: ; notranslate">
	public static String base48Encode(Long no) {
		Double num = Double.valueOf(no);
		String charSet = &quot;23456789abcdefghijkmnpqrstuvwxyzABCDEFGHIJKLMNPQRSTUVWXYZ&quot;;
		Integer length = charSet.length();
		String encodeString = new String();
		while(num &gt; length) {
			encodeString = charSet.charAt(num.intValue() % length)+encodeString;
			 num = Math.ceil(new Double(num / length) - 1) ;
		}
		encodeString = charSet.charAt(num.intValue())+encodeString;

		return encodeString;
	}
</pre><p>In above method we have passed a long number (which will be auto generated primary key) and get string representation.</p><p>We will add this logic into a file ShortyUtil.java. Create ShortyUtil class under <em>net.viralpatel.shorty.util</em> package.</p><p><strong>net.viralpatel.shorty.util.ShortyUtil</strong></p><pre class="brush: java; title: ; notranslate">
package net.viralpatel.shorty.util;

public class ShortyUtil {
	public static String base48Encode(Long no) {
		Double num = Double.valueOf(no);
		String charSet = &quot;23456789abcdefghijkmnpqrstuvwxyzABCDEFGHIJKLMNPQRSTUVWXYZ&quot;;
		Integer length = charSet.length();
		String encodeString = new String();
		while(num &gt; length) {
			encodeString = charSet.charAt(num.intValue() % length)+encodeString;
			 num = Math.ceil(new Double(num / length) - 1) ;
		}
		encodeString = charSet.charAt(num.intValue())+encodeString;

		return encodeString;
	}

	public static String getShortCodeFromURL(String URL) {

		int index=0;
		for(index=URL.length()-1; index&gt;=0 &amp;&amp; URL.charAt(index)!= '/' ;index--);
		String shortCode = URL.substring(index+1);

		return shortCode;
	}
}
</pre><h2>Connecting to Database using Hibernate</h2><p>Adding Hibernate related code is easy.</p><p>First add <em>HibernateUtil</em> class in <em>net.viralpatel.shorty.util</em> that we will use to create SessionFactory object.</p><p><strong>net.viralpatel.shorty.util.HibernateUtil</strong></p><pre class="brush: java; title: ; notranslate">
package net.viralpatel.shorty.util;

import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;

public class HibernateUtil {

	private static final SessionFactory sessionFactory = buildSessionFactory();

	private static SessionFactory buildSessionFactory() {
		try {
			// Create the SessionFactory from hibernate.cfg.xml
			return new AnnotationConfiguration().configure().buildSessionFactory();
		} catch (Throwable ex) {
			// Make sure you log the exception, as it might be swallowed
			System.err.println(&quot;Initial SessionFactory creation failed.&quot; + ex);
			throw new ExceptionInInitializerError(ex);
		}
	}

	public static SessionFactory getSessionFactory() {
		return sessionFactory;
	}

}
</pre><p>Now create an entity class that will map to LINKS table in database. Create Link.java class under <code>net.viralpatel.shorty.model</code> package.</p><p><strong>net.viralpatel.shorty.model.Link</strong></p><pre class="brush: java; title: ; notranslate">
package net.viralpatel.shorty.model;

import java.io.Serializable;
import java.sql.Date;

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

@Entity
@Table(name=&quot;LINKS&quot;)
public class Link implements Serializable{

	private static final long serialVersionUID = -8767337896773261247L;

	private Long id;
	private String shortCode;
	private String url;
	private Long clicks;
	private Date created;

	@Id
	@GeneratedValue
	@Column(name=&quot;id&quot;)
	public Long getId() {
		return id;
	}
	@Column(name = &quot;shortcode&quot;)
	public String getShortCode() {
		return shortCode;
	}
	@Column(name = &quot;created&quot;)
	public Date getCreated() {
		return created;
	}
	@Column(name = &quot;url&quot;)
	public String getUrl() {
		return url;
	}
	@Column(name = &quot;clicks&quot;)
	public Long getClicks() {
		return clicks;
	}
	public void setClicks(Long clicks) {
		this.clicks = clicks;
	}
	public void setShortCode(String shortCode) {
		this.shortCode = shortCode;
	}
	public void setUrl(String url) {
		this.url = url;
	}
	public void setCreated(Date created) {
		this.created = created;
	}
	public void setId(Long id) {
		this.id = id;
	}
}
</pre><p>Now add the mapping for above entity class Link.java in hibernate.cfg.xml file. Add following link in &gt;session-factory&lt; tag:</p><pre class="brush: java; title: ; notranslate">
&lt;mapping class=&quot;net.viralpatel.shorty.model.Link&quot; /&gt;
</pre><p>Also we will need a controller class that we invoke from Struts action class to do read/write in database. Create LinkController.java under net.viralpatel.shorty.controller package.</p><p><strong>net.viralpatel.shorty.controller.LinkController</strong></p><pre class="brush: java; title: ; notranslate">
package net.viralpatel.shorty.controller;

import org.hibernate.Query;
import org.hibernate.classic.Session;

import net.viralpatel.shorty.model.Link;
import net.viralpatel.shorty.util.HibernateUtil;
import net.viralpatel.shorty.util.ShortyUtil;

public class LinkController extends HibernateUtil {

	public Link get(String shortCode) {

		Session session = HibernateUtil.getSessionFactory().getCurrentSession();
		session.beginTransaction();

		Query query = session.createQuery(&quot;from Link where shortcode = :shortcode&quot;);
		query.setString(&quot;shortcode&quot;, shortCode);
		Link link = (Link) query.uniqueResult();
		if(null != link) {
			link.setClicks(link.getClicks());
			session.save(link);
		}
		session.getTransaction().commit();

		return link;

	}

	public Link add(Link link) {

		Session session = HibernateUtil.getSessionFactory().getCurrentSession();
		session.beginTransaction();

		Query query = session.createQuery(&quot;from Link where url = :url&quot;);
		query.setString(&quot;url&quot;, link.getUrl());
		Link oldLink = (Link) query.uniqueResult();
		if(null != oldLink)
			return oldLink;

		session.save(link);
		if(null == link.getShortCode()) {
			link.setShortCode(ShortyUtil.base48Encode(link.getId()));
			session.save(link);
		}
		session.getTransaction().commit();
		return link;
	}
}
</pre><h2>Adding Struts2 Support</h2><p>The UI for our URL shortner is very simple. We will have a index.jsp page which has a textbox for entering long URL and a small <em>Shorten</em> button. Also we will add a functionality where we can see some statistics/details of any short url. For example if shortcode <em>http://&lt;shorturl&gt;q1d</em> points to http://viralpatel.net then <em>http://&lt;shorturl&gt;q1d+</em> will show a page with details about url http://viralpatel.net.<br /> <strong>Related:</strong> <a target="_blank" href="http://viralpatel.net/blogs/2009/12/tutorial-create-struts-2-application-eclipse-example.html">Tutorial: Create Struts 2 Application in Eclipse</a></p><p>Lets starts with creating Action class. Create a class <code>LinkAction.java</code> under <code>net.viralpatel.shorty.view</code> package.</p><p><strong>LinkAction.java</strong></p><pre class="brush: java; title: ; notranslate">
package net.viralpatel.shorty.view;

import javax.servlet.http.HttpServletRequest;
import org.apache.struts2.interceptor.ServletRequestAware;
import net.viralpatel.shorty.controller.LinkController;
import net.viralpatel.shorty.model.Link;
import net.viralpatel.shorty.util.ShortyUtil;

import com.opensymphony.xwork2.ActionSupport;

public class LinkAction extends ActionSupport implements ServletRequestAware {

	private static final long serialVersionUID = 1L;
	private final static String DETAIL = &quot;detail&quot;;
	private String url;
	private Link link;

	private LinkController linkController;

	private HttpServletRequest request;

	public LinkAction() {
		linkController = new LinkController();
	}
	public String add() {
		link = new Link();
		link.setUrl(this.url);
		link = linkController.add(link);

		return SUCCESS;
	}
	public String get() {

		String uri = request.getRequestURI();

		uri = ShortyUtil.getShortCodeFromURL(uri);

		if(uri.charAt(uri.length()-1) == '+') {
			uri = uri.substring(0, uri.length()-1);
			this.link = this.linkController.get(uri);
			return DETAIL;
		}

		this.link = this.linkController.get(uri);
		if(null == this.link) {
			addActionError(getText(&quot;error.url.unavailable&quot;));
			return INPUT;
		} else {

			setUrl(link.getUrl());
			return SUCCESS;
		}
	}
	public String getUrl() {
		return url;
	}

	public void setUrl(String url) {
		this.url = url;
	}

	public Link getLink() {
		return link;
	}

	public void setLink(Link link) {
		this.link = link;
	}
	public void setServletRequest(HttpServletRequest request) {
		this.request = request;
	}
}
</pre><p>Also create struts configuration file struts.xml under resources folder and copy following content into it.<br /> <strong>resources/struts.xml</strong></p><pre class="brush: xml; title: ; notranslate">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; ?&gt;
&lt;!DOCTYPE struts PUBLIC
    &quot;-//Apache Software Foundation//DTD Struts Configuration 2.0//EN&quot;
    &quot;http://struts.apache.org/dtds/struts-2.0.dtd&quot;&gt;

&lt;struts&gt;
	&lt;constant name=&quot;struts.enable.DynamicMethodInvocation&quot;
		value=&quot;false&quot; /&gt;
	&lt;constant name=&quot;struts.devMode&quot; value=&quot;false&quot; /&gt;
	&lt;constant name=&quot;struts.custom.i18n.resources&quot;
		value=&quot;MessageResources&quot; /&gt;

	&lt;package name=&quot;default&quot; extends=&quot;struts-default&quot; namespace=&quot;/&quot;&gt;
		&lt;action name=&quot;add&quot; class=&quot;net.viralpatel.shorty.view.LinkAction&quot;
			method=&quot;add&quot;&gt;
			&lt;result name=&quot;success&quot;&gt;index.jsp&lt;/result&gt;
		&lt;/action&gt;
		&lt;action name=&quot;*&quot; class=&quot;net.viralpatel.shorty.view.LinkAction&quot;
			method=&quot;get&quot;&gt;
			&lt;result name=&quot;success&quot; type=&quot;redirect&quot;&gt;${url}&lt;/result&gt;
			&lt;result name=&quot;input&quot;&gt;index.jsp&lt;/result&gt;
			&lt;result name=&quot;detail&quot;&gt;detail.jsp&lt;/result&gt;
		&lt;/action&gt;
	&lt;/package&gt;
&lt;/struts&gt;
</pre><p>Note that we have used wildcard mapping in Struts2 action class. This is to ensure we call LinkAction for any shortcode passed in url shortner service.</p><p>Create a resource bundle file MessageResources.properties which will hold value for domain name of our URL shortner and an error message.<br /> <strong>resources/MessageResources.properties</strong></p><pre class="brush: xml; title: ; notranslate">
shorty.base.url=http://shorty/
error.url.unavailable=Couldn't find the site's URL to redirect to.
</pre><p>You may want to change value of <em>key shorty.base.url</em> to your domain name.</p><p>Add following JSP files in WebContent folder.</p><p><strong>WebContent/index.jsp</strong></p><pre class="brush: xml; title: ; notranslate">
&lt;%@ taglib uri=&quot;/struts-tags&quot; prefix=&quot;s&quot;%&gt;
&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.01 Transitional//EN&quot;
&quot;http://www.w3.org/TR/html4/loose.dtd&quot;&gt;
&lt;html&gt;
&lt;head&gt;
&lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=UTF-8&quot;&gt;
&lt;title&gt;Shorty - An Open Source URL Shortner in Struts2/Hibernate | ViralPatel.net&lt;/title&gt;
&lt;link href=&quot;css/style.css&quot; rel=&quot;stylesheet&quot;/&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;h1 class=&quot;title&quot;&gt;Shorty&lt;/h1&gt;
&lt;br&gt;
&lt;p&gt;A Simple URL Shortner in Struts2/Hibernate/MySQL&lt;/p&gt;
&lt;br&gt;&lt;br&gt;
&lt;div id=&quot;link-container&quot;&gt;

	&lt;s:form action=&quot;add&quot; method=&quot;post&quot;&gt;
		&lt;s:actionerror/&gt;
		&lt;s:textfield name=&quot;url&quot; cssClass=&quot;link&quot;/&gt;
		&lt;s:submit value=&quot;Shorten&quot;/&gt;
	&lt;/s:form&gt;
	&lt;s:if test=&quot;link.shortCode != null&quot;&gt;
			&lt;h3&gt;&lt;s:text name=&quot;shorty.base.url&quot;/&gt;&lt;s:property value=&quot;link.shortCode&quot;/&gt;&lt;/h3&gt;
	&lt;/s:if&gt;

&lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;
</pre><p><strong>WebContent/detail.jsp</strong></p><pre class="brush: xml; title: ; notranslate">
&lt;%@ taglib uri=&quot;/struts-tags&quot; prefix=&quot;s&quot;%&gt;
&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.01 Transitional//EN&quot;
&quot;http://www.w3.org/TR/html4/loose.dtd&quot;&gt;
&lt;html&gt;
&lt;head&gt;
&lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=UTF-8&quot;&gt;
&lt;title&gt;Shorty - An Open Source URL Shortner in Struts2/Hibernate | ViralPatel.net&lt;/title&gt;
&lt;link href=&quot;css/style.css&quot; rel=&quot;stylesheet&quot; /&gt;
&lt;/head&gt;
&lt;body&gt;
	&lt;h1 class=&quot;title&quot;&gt;Shorty&lt;/h1&gt;

	Short Code: &lt;s:property value=&quot;link.shortCode&quot; /&gt; &lt;br /&gt;
	Original URL: &lt;s:property value=&quot;link.url&quot; /&gt; &lt;br /&gt;
	Clicks: &lt;s:property value=&quot;link.clicks&quot; /&gt; &lt;br /&gt;
	Created On: &lt;s:property value=&quot;link.created&quot; /&gt; &lt;br /&gt;

&lt;/body&gt;
&lt;/html&gt;
</pre><h2>That&#8217;s all Folks</h2><p>Execute the web project in your favorite container like Tomcat, Glassfish etc.<br /> <img src="http://img.viralpatel.net/2010/02/shorty-url-shortner-struts2-hibernate.png" alt="shorty-url-shortner-struts2-hibernate" title="shorty-url-shortner-struts2-hibernate" width="523" height="189" class="aligncenter size-full wp-image-2031" /></p><h2>Download</h2><p><a href="http://viralpatel.net/blogs/download/struts/shorty/Shorty.war"><strong>Download WAR File with Source Code</strong></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/01/tutorial-struts2-hibernate-example-eclipse.html" title="Tutorial: Create Struts2 Hibernate Example in Eclipse">Tutorial: Create Struts2 Hibernate Example in Eclipse</a></li><li><a href="http://viralpatel.net/blogs/2011/12/hibernate-inheritance-table-per-concrete-class-annotation-xml-mapping.html" title="Hibernate Inheritance: Table Per Concrete Class (Annotation &#038; XML mapping)">Hibernate Inheritance: Table Per Concrete Class (Annotation &#038; XML mapping)</a></li><li><a href="http://viralpatel.net/blogs/2011/12/hibernate-inheritance-table-per-subclass-annotation-xml-mapping.html" title="Hibernate Inheritance: Table Per Subclass (Annotation &#038; XML mapping)">Hibernate Inheritance: Table Per Subclass (Annotation &#038; XML mapping)</a></li><li><a href="http://viralpatel.net/blogs/2011/12/struts-2-override-default-theme.html" title="Struts 2 Tip: Override Default Theme">Struts 2 Tip: Override Default Theme</a></li><li><a href="http://viralpatel.net/blogs/2011/12/hibernate-inheritence-table-per-hierarchy-mapping.html" title="Hibernate Inheritance: Table Per Class Hierarchy (Annotation &#038; XML Mapping)">Hibernate Inheritance: Table Per Class Hierarchy (Annotation &#038; XML Mapping)</a></li><li><a href="http://viralpatel.net/blogs/2011/12/hibernate-self-join-annotation-mapping-many-to-many-example.html" title="Hibernate Self Join Many To Many Annotations mapping example">Hibernate Self Join Many To Many Annotations mapping example</a></li><li><a href="http://viralpatel.net/blogs/2011/12/hibernate-self-join-annotations-one-to-many-mapping.html" title="Hibernate Self Join Annotations One To Many mapping example">Hibernate Self Join Annotations One To Many mapping example</a></li></ul></div>]]></content:encoded> <wfw:commentRss>http://viralpatel.net/blogs/2010/02/create-url-shortner-in-java-struts2-hibernate.html/feed</wfw:commentRss> <slash:comments>5</slash:comments> </item> <item><title>Tutorial: Create Struts2 Hibernate Example in Eclipse</title><link>http://viralpatel.net/blogs/2010/01/tutorial-struts2-hibernate-example-eclipse.html</link> <comments>http://viralpatel.net/blogs/2010/01/tutorial-struts2-hibernate-example-eclipse.html#comments</comments> <pubDate>Fri, 15 Jan 2010 15:08:02 +0000</pubDate> <dc:creator>Viral Patel</dc:creator> <category><![CDATA[Featured]]></category> <category><![CDATA[Hibernate]]></category> <category><![CDATA[Struts 2]]></category> <category><![CDATA[Struts2]]></category> <category><![CDATA[Tutorial]]></category><guid isPermaLink="false">http://viralpatel.net/blogs/?p=1993</guid> <description><![CDATA[This is a demo Contact Manager application that we will create using Struts2 and Hibernate framework. In this article we will see how we can use Hibernate to perform Insert / Delete operations in Struts2 framework. Our Goal Our goal will be to demonstrate the use of Struts2 with Hibernate framework and to create a [...]]]></description> <content:encoded><![CDATA[<p>This is a demo Contact Manager application that we will create using Struts2 and Hibernate framework. In this article we will see how we can use Hibernate to perform Insert / Delete operations in Struts2 framework.</p><h2>Our Goal</h2><p>Our goal will be to demonstrate the use of Struts2 with Hibernate framework and to create a demo application &#8220;Contact Manager&#8221;. 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>Once we will build the application it will look like:<br /> <img src="http://img.viralpatel.net/2010/01/struts2-hibernate-contact-manager.png" alt="struts2-hibernate-contact-manager" title="struts2-hibernate-contact-manager" width="450" height="419" class="aligncenter size-full wp-image-1994" /></p><h2>Getting Started</h2><p>For our Contact Manager example, we will use MySQL database. Create a table <strong>contacts</strong> 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),
	cell_no		VARCHAR(15),
	email_id	VARCHAR(30),
	website		VARCHAR(150),
	birthdate	DATE,
	created		TIMESTAMP DEFAULT NOW()
);
</pre><h2>Creating Project in Eclipse</h2><p>Open Eclipse and goto File -> New -> Project and select <strong>Dynamic Web Project</strong> in the New Project wizard screen.<br /> <img alt="struts dynamic web project" src="http://img.viralpatel.net/2008/12/eclipse-new-project-struts-example.png" title="struts dynamic web project" class="aligncenter" width="369" height="365" /></p><p>After selecting Dynamic Web Project, press Next.<br /> <img alt="dynamic web project" src="http://img.viralpatel.net/2008/12/eclipse-new-dynamic-web-project-struts.png" title="dynamic web project" class="aligncenter" width="471" height="511" /></p><p>Write the name of the project. For example <strong>ContactManager</strong>. Once this is done, select the target runtime environment (e.g. Apache Tomcat v6.0). This is to run the project inside Eclipse environment. After this press <strong>Finish</strong>.</p><p>We will need a source folder called <strong>resources</strong>. Right click on Project in project explorer and select New -> Source Folder and create a folder with name <em>resources</em>.</p><p>Also we will create Java packages for our application. As we will use Struts2, we will follow MVC architecture. Create 4 packages in the sources.<br /> <img src="http://img.viralpatel.net/2010/01/struts2-hibernate-package.png" alt="struts2-hibernate-package" title="struts2-hibernate-package" width="253" height="154" class="aligncenter size-full wp-image-1998" /></p><p>We created 4 new packages. The <strong>net.viralpatel.contact.controller</strong> will hold the Java class that will act as controller and will fetch the data from database and pass it to view. The <strong>net.viralpatel.contact.model</strong> package will hold the Hibernate persistent model class. The <strong>net.viralpatel.contact.view</strong> will contain the struts2 action class. And finally the <strong>net.viralpatel.contact.util</strong> will have some hibernate related util file that will be see shortly.</p><h2>Required JAR Files</h2><p>Now copy all the required JAR files in WebContent -> WEB-INF -> lib folder. Create this folder if it does not exists.<br /> <img src="http://img.viralpatel.net/2010/01/struts2-hibernate-required-jar.png" alt="" title="struts2-hibernate-required-jar" width="235" height="392" class="aligncenter size-full wp-image-1997" /></p><h2>Create JSP for Contact Manager</h2><p>We will need only one JSP file for this tutorial. The JSP will include a form to add new contact as well as will list the contacts at the end. Create a JSP file <strong>index.jsp</strong> in <strong>WebContent</strong> folder and copy following content into it.<br /> <strong>WebContent/index.jsp</strong></p><pre class="brush: xml; title: ; notranslate">
&lt;%@ page contentType=&quot;text/html; charset=UTF-8&quot;%&gt;
&lt;%@ taglib prefix=&quot;s&quot; uri=&quot;/struts-tags&quot;%&gt;
&lt;html&gt;
&lt;head&gt;
	&lt;title&gt;Contact Manager - Struts2 Hibernate Example&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;

&lt;h1&gt;Contact Manager&lt;/h1&gt;
&lt;s:actionerror/&gt;

&lt;s:form action=&quot;add&quot; method=&quot;post&quot;&gt;
	&lt;s:textfield name=&quot;contact.firstName&quot; label=&quot;Firstname&quot;/&gt;
	&lt;s:textfield name=&quot;contact.lastName&quot; label=&quot;Lastname&quot;/&gt;
	&lt;s:textfield name=&quot;contact.emailId&quot; label=&quot;Email&quot;/&gt;
	&lt;s:textfield name=&quot;contact.cellNo&quot; label=&quot;Cell No.&quot;/&gt;
	&lt;s:textfield name=&quot;contact.website&quot; label=&quot;Homepage&quot;/&gt;
	&lt;s:textfield name=&quot;contact.birthDate&quot; label=&quot;Birthdate&quot;/&gt;
	&lt;s:submit value=&quot;Add Contact&quot; align=&quot;center&quot;/&gt;
&lt;/s:form&gt;

&lt;h2&gt;Contacts&lt;/h2&gt;
&lt;table&gt;
&lt;tr&gt;
	&lt;th&gt;Name&lt;/th&gt;
	&lt;th&gt;Email&lt;/th&gt;
	&lt;th&gt;Cell No.&lt;/th&gt;
	&lt;th&gt;Birthdate&lt;/th&gt;
	&lt;th&gt;Homepage&lt;/th&gt;
	&lt;th&gt;Delete&lt;/th&gt;
&lt;/tr&gt;
&lt;s:iterator value=&quot;contactList&quot; var=&quot;contact&quot;&gt;
	&lt;tr&gt;
		&lt;td&gt;&lt;s:property value=&quot;lastName&quot;/&gt;, &lt;s:property value=&quot;firstName&quot;/&gt; &lt;/td&gt;
		&lt;td&gt;&lt;s:property value=&quot;emailId&quot;/&gt;&lt;/td&gt;
		&lt;td&gt;&lt;s:property value=&quot;cellNo&quot;/&gt;&lt;/td&gt;
		&lt;td&gt;&lt;s:property value=&quot;birthDate&quot;/&gt;&lt;/td&gt;
		&lt;td&gt;&lt;a href=&quot;&lt;s:property value=&quot;website&quot;/&gt;&quot;&gt;link&lt;/a&gt;&lt;/td&gt;
		&lt;td&gt;&lt;a href=&quot;delete?id=&lt;s:property value=&quot;id&quot;/&gt;&quot;&gt;delete&lt;/a&gt;&lt;/td&gt;
	&lt;/tr&gt;
&lt;/s:iterator&gt;
&lt;/table&gt;
&lt;/body&gt;
&lt;/html&gt;
</pre><h2>Adding Hibernate Support</h2><p>For adding hibernate support, we will add following source code in Contact Manager application.<br /> <strong>hibernate.cfg.xml</strong> &#8211; This is the Hibernate configuration file. This file will contain configurations such as database connection information, persistence class info etc. Create <em>hibernate.cfg.xml</em> under <em>resources</em> folder and copy following content into it.</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 3.0//EN&quot;
        &quot;http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd&quot;&gt;

&lt;hibernate-configuration&gt;
	&lt;session-factory&gt;
		&lt;property name=&quot;connection.driver_class&quot;&gt;
			com.mysql.jdbc.Driver
		&lt;/property&gt;
		&lt;property name=&quot;connection.url&quot;&gt;
			jdbc:mysql://localhost:3306/ContactManager
		&lt;/property&gt;
		&lt;property name=&quot;connection.username&quot;&gt;root&lt;/property&gt;
		&lt;property name=&quot;connection.password&quot;&gt;root&lt;/property&gt;
		&lt;property name=&quot;connection.pool_size&quot;&gt;1&lt;/property&gt;
		&lt;property name=&quot;dialect&quot;&gt;
			org.hibernate.dialect.MySQLDialect
		&lt;/property&gt;
		&lt;property name=&quot;current_session_context_class&quot;&gt;thread&lt;/property&gt;
		&lt;property name=&quot;cache.provider_class&quot;&gt;
			org.hibernate.cache.NoCacheProvider
		&lt;/property&gt;
		&lt;property name=&quot;show_sql&quot;&gt;true&lt;/property&gt;
		&lt;property name=&quot;hbm2ddl.auto&quot;&gt;update&lt;/property&gt;

		&lt;mapping class=&quot;net.viralpatel.contact.model.Contact&quot; /&gt;

	&lt;/session-factory&gt;
&lt;/hibernate-configuration&gt;
</pre><p><strong>HibernateUtil.java</strong> &#8211; This is the Util file that we use to create connection with hibernate. Create HibernateUtil.java under package <strong>net.viralpatel.contact.util</strong> and copy following content into it.</p><pre class="brush: java; title: ; notranslate">
package net.viralpatel.contact.util;

import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;

public class HibernateUtil {

	private static final SessionFactory sessionFactory = buildSessionFactory();

	private static SessionFactory buildSessionFactory() {
		try {
			// Create the SessionFactory from hibernate.cfg.xml
			return new AnnotationConfiguration().configure()
					.buildSessionFactory();
		} catch (Throwable ex) {
			System.err.println(&quot;Initial SessionFactory creation failed.&quot; + ex);
			throw new ExceptionInInitializerError(ex);
		}
	}

	public static SessionFactory getSessionFactory() {
		return sessionFactory;
	}
}
</pre><p><strong>Contact.java</strong> &#8211; This is the persistence entity class that will map to Contacts table in MySQL. Create Contact.java under <strong>net.viralpatel.contact.model</strong> package and copy following content into it.</p><pre class="brush: java; title: ; notranslate">
package net.viralpatel.contact.model;

import java.io.Serializable;
import java.sql.Date;

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 implements Serializable{

	private static final long serialVersionUID = -8767337896773261247L;

	private Long id;
	private String firstName;
	private String lastName;
	private String emailId;
	private String cellNo;
	private Date birthDate;
	private String website;

	private Date created;

	@Id
	@GeneratedValue
	@Column(name=&quot;id&quot;)
	public Long getId() {
		return id;
	}
	@Column(name=&quot;firstname&quot;)
	public String getFirstName() {
		return firstName;
	}
	@Column(name=&quot;lastname&quot;)
	public String getLastName() {
		return lastName;
	}
	@Column(name=&quot;email_id&quot;)
	public String getEmailId() {
		return emailId;
	}
	@Column(name=&quot;cell_no&quot;)
	public String getCellNo() {
		return cellNo;
	}
	@Column(name=&quot;birthdate&quot;)
	public Date getBirthDate() {
		return birthDate;
	}
	@Column(name=&quot;website&quot;)
	public String getWebsite() {
		return website;
	}
	@Column(name=&quot;created&quot;)
	public Date getCreated() {
		return created;
	}
	public void setId(Long id) {
		this.id = id;
	}
	public void setFirstName(String firstName) {
		this.firstName = firstName;
	}
	public void setLastName(String lastName) {
		this.lastName = lastName;
	}
	public void setEmailId(String emailId) {
		this.emailId = emailId;
	}
	public void setCellNo(String cellNo) {
		this.cellNo = cellNo;
	}
	public void setBirthDate(Date birthDate) {
		this.birthDate = birthDate;
	}
	public void setCreated(Date created) {
		this.created = created;
	}
	public void setWebsite(String website) {
		this.website = website;
	}
}
</pre><p>Note how we have mapped Contact class with Contacts table using Java persistence API annotations.</p><h2>Adding Controller to access data</h2><p>We will add a controller class in Contact Manager application which will be used to get/save data from hibernate. This controller will be invoked from Struts action class. Create a file <strong>ContactManager.java</strong> under <strong>net.viralpatel.contact.controller</strong> package and copy following content into it.</p><pre class="brush: java; title: ; notranslate">
package net.viralpatel.contact.controller;

import java.util.List;

import org.hibernate.HibernateException;
import org.hibernate.classic.Session;

import net.viralpatel.contact.model.Contact;
import net.viralpatel.contact.util.HibernateUtil;

public class ContactManager extends HibernateUtil {

	public Contact add(Contact contact) {
		Session session = HibernateUtil.getSessionFactory().getCurrentSession();
		session.beginTransaction();
		session.save(contact);
		session.getTransaction().commit();
		return contact;
	}
	public Contact delete(Long id) {
		Session session = HibernateUtil.getSessionFactory().getCurrentSession();
		session.beginTransaction();
		Contact contact = (Contact) session.load(Contact.class, id);
		if(null != contact) {
			session.delete(contact);
		}
		session.getTransaction().commit();
		return contact;
	}

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

		Session session = HibernateUtil.getSessionFactory().getCurrentSession();
		session.beginTransaction();
		List&lt;Contact&gt; contacts = null;
		try {

			contacts = (List&lt;Contact&gt;)session.createQuery(&quot;from Contact&quot;).list();

		} catch (HibernateException e) {
			e.printStackTrace();
			session.getTransaction().rollback();
		}
		session.getTransaction().commit();
		return contacts;
	}
}
</pre><p>Note that how we have created different methods in controller class to add/delete/list the contacts. Also the ContactManager class is extending HibernateUtil class thus allowing it to access <strong>sessionFactory</strong> object.</p><h2>Adding Struts2 Support</h2><p>Let us add Struts2 support to our web application. For that, will add following entry in deployment descriptor (WEB-INF/web.xml).</p><h3> Add Struts2 Filter in web.xml</h3><pre class="brush: xml; title: ; notranslate">
&lt;filter&gt;
	&lt;filter-name&gt;struts2&lt;/filter-name&gt;
	&lt;filter-class&gt;
		org.apache.struts2.dispatcher.FilterDispatcher
	&lt;/filter-class&gt;
&lt;/filter&gt;
&lt;filter-mapping&gt;
	&lt;filter-name&gt;struts2&lt;/filter-name&gt;
	&lt;url-pattern&gt;/*&lt;/url-pattern&gt;
&lt;/filter-mapping&gt;
</pre><h3>Creating struts.xml</h3><p>We will need to create struts.xml file that will hold the action mapping for our example. Create a file <strong>struts.xml</strong> in resources folder and add following content into it.<br /> <strong>struts.xml</strong></p><pre class="brush: xml; title: ; notranslate">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; ?&gt;
&lt;!DOCTYPE struts PUBLIC
    &quot;-//Apache Software Foundation//DTD Struts Configuration 2.0//EN&quot;
    &quot;http://struts.apache.org/dtds/struts-2.0.dtd&quot;&gt;

&lt;struts&gt;
	&lt;constant name=&quot;struts.enable.DynamicMethodInvocation&quot;
		value=&quot;false&quot; /&gt;
	&lt;constant name=&quot;struts.devMode&quot; value=&quot;false&quot; /&gt;

	&lt;package name=&quot;default&quot; extends=&quot;struts-default&quot; namespace=&quot;/&quot;&gt;

		&lt;action name=&quot;add&quot;
			class=&quot;net.viralpatel.contact.view.ContactAction&quot; method=&quot;add&quot;&gt;
			&lt;result name=&quot;success&quot; type=&quot;chain&quot;&gt;index&lt;/result&gt;
			&lt;result name=&quot;input&quot; type=&quot;chain&quot;&gt;index&lt;/result&gt;
		&lt;/action&gt;

		&lt;action name=&quot;delete&quot;
			class=&quot;net.viralpatel.contact.view.ContactAction&quot; method=&quot;delete&quot;&gt;
			&lt;result name=&quot;success&quot; type=&quot;chain&quot;&gt;index&lt;/result&gt;
		&lt;/action&gt;

		&lt;action name=&quot;index&quot;
			class=&quot;net.viralpatel.contact.view.ContactAction&quot;&gt;
			&lt;result name=&quot;success&quot;&gt;index.jsp&lt;/result&gt;
		&lt;/action&gt;
	&lt;/package&gt;
&lt;/struts&gt;
</pre><p><strong>Related:</strong><br /> <a href="http://viralpatel.net/blogs/2008/12/tutorial-creating-struts-application-in-eclipse.html">Create Struts Application in Eclipse</a><br /> <a href="http://viralpatel.net/blogs/2009/12/tutorial-create-struts-2-application-eclipse-example.html">Create Struts2 Application in Eclipse</a></p><h3>Create Action class</h3><p>Up-till now we have almost completed our Contact Manager application in Struts2 and Hibernate. Only task left is to add Struts Action class. Create a class <strong>ContactAction.java</strong> under <strong>net.viralpatel.contact.view</strong> package and copy following content into it.</p><pre class="brush: java; title: ; notranslate">
package net.viralpatel.contact.view;

import java.util.List;

import net.viralpatel.contact.controller.ContactManager;
import net.viralpatel.contact.model.Contact;

import com.opensymphony.xwork2.ActionSupport;

public class ContactAction extends ActionSupport {

	private static final long serialVersionUID = 9149826260758390091L;
	private Contact contact;
	private List&lt;Contact&gt; contactList;
	private Long id;

	private ContactManager contactManager;

	public ContactAction() {
		contactManager = new ContactManager();
	}

	public String execute() {
		this.contactList = contactManager.list();
		System.out.println(&quot;execute called&quot;);
		return SUCCESS;
	}

	public String add() {
		System.out.println(getContact());
		try {
			contactManager.add(getContact());
		} catch (Exception e) {
			e.printStackTrace();
		}
		this.contactList = contactManager.list();
		return SUCCESS;
	}

	public String delete() {
		contactManager.delete(getId());
		return SUCCESS;
	}

	public Contact getContact() {
		return contact;
	}

	public List&lt;Contact&gt; getContactList() {
		return contactList;
	}

	public void setContact(Contact contact) {
		this.contact = contact;
	}

	public void setContactList(List&lt;Contact&gt; contactsList) {
		this.contactList = contactsList;
	}

	public Long getId() {
		return id;
	}

	public void setId(Long id) {
		this.id = id;
	}
}
</pre><p><code>ContactAction</code> class contains different methods that gets called by Struts2. The execute() method is the default method which gets called when we call /index action from browser. It fetches the list of contacts and display it in index.jsp. Similarly, when a new contact is added, add() method is called. If you check the action mapping entry in <code>struts.xml</code> for <code>add()</code> method, the &lt;result&gt; is mapped with <code>/index</code> action and the type is chain. This is because we want to display the list of contact once we add a new one. Hence we have done Action chaining and called <code>/index</code> action after <code>/add</code> action.</p><h2>The Contact Manager App</h2><p>That&#8217;s it. The app is ready, just compile and run the project in Eclipse Run -> Run As -> Run on Server. Set the URL to:<br /> <strong>http://localhost:&lt;port&gt;/&lt;project name&gt;/index</strong></p><p><img src="http://img.viralpatel.net/2010/01/struts2-hibernate-contact-manager.png" alt="struts2-hibernate-contact-manager" title="struts2-hibernate-contact-manager" width="450" height="419" class="aligncenter size-full wp-image-1994" /><br /> Fill the contact form and hit enter and the new contact will be persisted in database and will be shown in below table. Similarly, click on <em>delete</em> link next to a record. It will delete the record from database.</p><p>Let me know your input about this application.<br /> Cheers.</p><h2>Download Source</h2><p><a href="http://viralpatel.net/blogs/download/hibernate/StrutsHibernate.zip">Download Source without JAR files (19.2 KB)</a></p><p><a href="http://viralpatel-net-tutorials.googlecode.com/files/Struts2_Hibernate_with_JAR.zip" rel="nofollow">Download Source with JAR files (8.5 MB)</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/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/2010/02/create-url-shortner-in-java-struts2-hibernate.html" title="Writing a URL Shortner in Java Struts2 &#038; Hibernate">Writing a URL Shortner in Java Struts2 &#038; Hibernate</a></li><li><a href="http://viralpatel.net/blogs/2011/12/hibernate-inheritance-table-per-concrete-class-annotation-xml-mapping.html" title="Hibernate Inheritance: Table Per Concrete Class (Annotation &#038; XML mapping)">Hibernate Inheritance: Table Per Concrete Class (Annotation &#038; XML mapping)</a></li><li><a href="http://viralpatel.net/blogs/2011/12/hibernate-inheritance-table-per-subclass-annotation-xml-mapping.html" title="Hibernate Inheritance: Table Per Subclass (Annotation &#038; XML mapping)">Hibernate Inheritance: Table Per Subclass (Annotation &#038; XML mapping)</a></li><li><a href="http://viralpatel.net/blogs/2011/12/struts-2-override-default-theme.html" title="Struts 2 Tip: Override Default Theme">Struts 2 Tip: Override Default Theme</a></li><li><a href="http://viralpatel.net/blogs/2011/12/hibernate-inheritence-table-per-hierarchy-mapping.html" title="Hibernate Inheritance: Table Per Class Hierarchy (Annotation &#038; XML Mapping)">Hibernate Inheritance: Table Per Class Hierarchy (Annotation &#038; XML Mapping)</a></li><li><a href="http://viralpatel.net/blogs/2011/12/hibernate-self-join-annotation-mapping-many-to-many-example.html" title="Hibernate Self Join Many To Many Annotations mapping example">Hibernate Self Join Many To Many Annotations mapping example</a></li></ul></div>]]></content:encoded> <wfw:commentRss>http://viralpatel.net/blogs/2010/01/tutorial-struts2-hibernate-example-eclipse.html/feed</wfw:commentRss> <slash:comments>165</slash:comments> </item> <item><title>Struts 2 Ajax Tutorial with Example</title><link>http://viralpatel.net/blogs/2010/01/struts-2-ajax-tutorial-example-drop-down.html</link> <comments>http://viralpatel.net/blogs/2010/01/struts-2-ajax-tutorial-example-drop-down.html#comments</comments> <pubDate>Wed, 13 Jan 2010 09:46:27 +0000</pubDate> <dc:creator>Viral Patel</dc:creator> <category><![CDATA[Featured]]></category> <category><![CDATA[Struts 2]]></category> <category><![CDATA[AJAX]]></category> <category><![CDATA[Struts]]></category> <category><![CDATA[Struts2]]></category> <category><![CDATA[struts2-series]]></category><guid isPermaLink="false">http://viralpatel.net/blogs/?p=1985</guid> <description><![CDATA[Welcome to the last part of 7 article series of Struts 2 Framework tutorials. In previous article we saw how to implement File Upload functionality in Struts 2. In this article we will see how we can implement Ajax support in a webapplication using Struts2 framework. AJAX support in Struts 2 Struts 2 provides built-in [...]]]></description> <content:encoded><![CDATA[<p>Welcome to the last part of 7 article series of Struts 2 Framework tutorials. In <a href="http://viralpatel.net/blogs/2009/12/struts-2-file-upload-save-tutorial-with-example.html">previous article</a> we saw how to implement File Upload functionality in Struts 2. In this article we will see how we can implement Ajax support in a webapplication using Struts2 framework.<br /><style type="text/css">#struts{color:#222;width:98%;background-color:#EF9;padding:5px;-moz-border-radius:10px;-webkit-border-radius:10px}#struts
h3{font-size:18px;text-decoration:underline}#struts
ul{list-style:none}#struts ul
li{padding:3px}</style><div id="struts"><h3>Struts 2 Tutorials</h3><ul><li><a href="http://viralpatel.net/blogs/2009/12/introduction-to-struts-2-framework.html">Part 1: Introduction to Struts 2</a></li><li><a href="http://viralpatel.net/blogs/2009/12/tutorial-create-struts-2-application-eclipse-example">Part 2: Create Hello World Application in Struts 2</a></li><li><a href="http://viralpatel.net/blogs/2009/12/struts2-validation-framework-tutorial-example">Part 3: Struts 2 Validation Framework Tutorial with Example</a></li><li><a href="http://viralpatel.net/blogs/2009/12/struts-2-tiles-plugin-tutorial-with-example-in-eclipse.html">Part 4: Struts 2 Tiles Plugin Tutorial with Example</a></li><li><a href="http://viralpatel.net/blogs/2009/12/struts2-interceptors-tutorial-with-example.html">Part 5: Struts 2 Interceptors Tutorial with Example</a></li><li><a href="http://viralpatel.net/blogs/2009/12/struts-2-file-upload-save-tutorial-with-example.html">Part 6: Struts 2 File Upload and Save Example</a></li><li><a href="http://viralpatel.net/blogs/2010/01/struts-2-ajax-tutorial-example-drop-down.html">Part 7: Struts 2 Ajax Tutorial with Example</a></li></ul></div></p><h2>AJAX support in Struts 2</h2><p>Struts 2 provides built-in support to AJAX using Dojo Toolkit library. If you are new to Dojo, you may want to go through the <a href="http://viralpatel.net/blogs/2009/02/introduction-to-dojo-toolkit-javascript-framework.html">Introduction of DOJO Toolkit</a>.</p><p>Struts 2 comes with powerful set of Dojo AJAX APIs which you can use to add Ajax support. In order to add Ajax support, you need to add following JAR file in your classpath:<br /> <strong>struts2-dojo-plugin.jar</strong></p><p>Also once we add this JAR file, we need to add following code snippet in whatever JSP file we need to add AJAX support.</p><pre class="brush: xml; title: ; notranslate">
&lt;%@ taglib prefix=&quot;sx&quot; uri=&quot;/struts-dojo-tags&quot;%&gt;
</pre><p>First define the taglib sx which we will use to add AJAX enabled tags.</p><pre class="brush: xml; title: ; notranslate">
&lt;sx:head/&gt;
</pre><p>Add this head tag in your JSP between &lt;head&gt; &#8230; &lt;/head&gt; tags. This sx:head tag will include required javascript and css files to implement Ajax.</p><h2>AJAX Example: Struts2 Ajax Drop Down</h2><p>Let us add simple AJAX support in our StrutsHelloWorld web application. We will use the base code that we used in previous articles and add Ajax on top of it.</p><p>We will create a drop down which will Autocomplete and suggest the input. For this we will add Dojo support to our webapp.</p><h3>Step 1: Adding JAR file</h3><p>As discussed earlier we will add struts2-dojo-plugin.jar in classpath (WEB-INF/lib). Thus, following is the list of required jar files. Note that these jars are needed to run full application including all the samples of previous parts of this tutorial series.<br /> <img src="http://img.viralpatel.net/2010/01/struts2-ajax-jar-files.png" alt="struts2-ajax-jar-files" title="struts2-ajax-jar-files" width="228" height="288" class="aligncenter size-full wp-image-1986" /></p><h3>Step 2: Create AJAX Action class</h3><p>We will create an action class which will get called for our Ajax example. Create a file <code>AjaxAutocomplete.java</code> in <code>net.viralpatel.struts2</code> package and copy following content into it.<br /> <strong>AjaxAutocomplete.java</strong></p><pre class="brush: java; title: ; notranslate">
package net.viralpatel.struts2;

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

import com.opensymphony.xwork2.ActionSupport;

public class AjaxAutocomplete extends ActionSupport {
	private String data = &quot;Afghanistan, Zimbabwe, India, United States, Germany, China, Israel&quot;;
	private List&lt;String&gt; countries;
	private String country;

	public String execute() {
		countries = new ArrayList&lt;String&gt;();
		StringTokenizer st = new StringTokenizer(data, &quot;,&quot;);

		while (st.hasMoreTokens()) {
			countries.add(st.nextToken().trim());
		}
		return SUCCESS;
	}
	public String getCountry() {
		return this.country;
	}

	public List&lt;String&gt; getCountries() {
		return countries;
	}

	public void setCountries(List&lt;String&gt; countries) {
		this.countries = countries;
	}
	public void setCountry(String country) {
		this.country = country;
	}
}
</pre><p>In above code we have created a simple action class with attribute <code>String country</code> and <code>List countries</code>. The countries list will be populated with country names when execute() method is called. Here for this example, we have loaded static data. You may feel free to change this and add data from database.</p><h3>Step 3: Create JSP</h3><p>Create JSP file to display Autocomplete textbox for our Ajax action. Create AjaxDemo.jsp in WebContent directory.<br /> <strong>AjaxDemo.jsp</strong></p><pre class="brush: xml; title: ; notranslate">
&lt;%@ page contentType=&quot;text/html; charset=UTF-8&quot;%&gt;
&lt;%@ taglib prefix=&quot;s&quot; uri=&quot;/struts-tags&quot;%&gt;
&lt;%@ taglib prefix=&quot;sx&quot; uri=&quot;/struts-dojo-tags&quot;%&gt;
&lt;html&gt;
&lt;head&gt;
	&lt;title&gt;Welcome&lt;/title&gt;
	&lt;sx:head /&gt;
&lt;/head&gt;
&lt;body&gt;
	&lt;h2&gt;Struts 2 Autocomplete (Drop down) Example!&lt;/h2&gt;

	Country:
	&lt;sx:autocompleter size=&quot;1&quot; list=&quot;countries&quot; name=&quot;country&quot;&gt;&lt;/sx:autocompleter&gt;
	&lt;/action&gt;
&lt;/body&gt;
&lt;/html&gt;
</pre><p>In above JSP file we have used sx:autocompleter tag to render an autocomplete drop down which users Ajax class to fetch data internally. Note that we have mapped the <code>list</code> attribute with <code>List countries</code>.</p><h3>Step 4: Creating Struts.xml entry</h3><p>Add following action entry in Struts.xml file:</p><pre class="brush: xml; title: ; notranslate">
&lt;action name=&quot;ajaxdemo&quot; class=&quot;net.viralpatel.struts2.AjaxAutocomplete&quot;&gt;
	&lt;interceptor-ref name=&quot;loggingStack&quot;&gt;&lt;/interceptor-ref&gt;
	&lt;result name=&quot;success&quot; type=&quot;tiles&quot;&gt;/ajaxdemo.tiles&lt;/result&gt;
	&lt;result type=&quot;tiles&quot;&gt;/ajaxdemo.tiles&lt;/result&gt;
&lt;/action&gt;
</pre><p>Notice that we are using Tiles here in this example. You may want to use AjaxDemo.jsp instead of /ajaxdemo.tiles to render the output directly in JSP.</p><h2>That&#8217;s All Folks</h2><p>Compile and Run the application in eclipse.<br /> <img src="http://img.viralpatel.net/2010/01/struts2-ajax-drop-down.png" alt="struts2-ajax-drop-down" title="struts2-ajax-drop-down" width="448" height="517" class="aligncenter size-full wp-image-1987" /></p><h2>Download Source Code</h2><p><a href="http://viralpatel.net/blogs/download/struts/Part-7-StrutsHelloWorld.zip"><strong>Click here to download Source Code without JAR files (24KB)</strong></a></p><h2>Conclusion</h2><p>Struts2 Framework provides wide variety of features to create a rich web application. In this Struts2 series we saw different aspects of Struts 2 like <a href="http://viralpatel.net/blogs/2009/12/introduction-to-struts-2-framework.html">introduction of struts2</a>, <a href="http://viralpatel.net/blogs/2009/12/tutorial-create-struts-2-application-eclipse-example">hello world application</a>, <a href="http://viralpatel.net/blogs/2009/12/struts2-validation-framework-tutorial-example">validation framework</a>, <a href="http://viralpatel.net/blogs/2009/12/struts-2-tiles-plugin-tutorial-with-example-in-eclipse.html">tiles plugin</a>, <a href="http://viralpatel.net/blogs/2009/12/struts2-interceptors-tutorial-with-example.html">strurts2 interceptors</a>, <a href="http://viralpatel.net/blogs/2009/12/struts-2-file-upload-save-tutorial-with-example.html">file upload</a> and ajax support.</p><div id="relatedpost"><h2  class="related_post_title">Related Posts</h2><ul class="related_post"><li><a href="http://viralpatel.net/blogs/2009/12/struts2-interceptors-tutorial-with-example.html" title="Struts2 Interceptors Tutorial with Example">Struts2 Interceptors Tutorial with Example</a></li><li><a href="http://viralpatel.net/blogs/2009/12/struts-2-tiles-plugin-tutorial-with-example-in-eclipse.html" title="Struts 2 Tiles Plugin Tutorial with Example in Eclipse">Struts 2 Tiles Plugin Tutorial with Example in Eclipse</a></li><li><a href="http://viralpatel.net/blogs/2009/12/struts2-validation-framework-tutorial-example.html" title="Struts2 Validation Framework Tutorial with Example">Struts2 Validation Framework Tutorial with Example</a></li><li><a href="http://viralpatel.net/blogs/2011/12/struts-2-override-default-theme.html" title="Struts 2 Tip: Override Default Theme">Struts 2 Tip: Override Default Theme</a></li><li><a href="http://viralpatel.net/blogs/2009/12/struts-2-file-upload-save-tutorial-with-example.html" title="Struts 2 File Upload and Save Tutorial with Example">Struts 2 File Upload and Save Tutorial with Example</a></li><li><a href="http://viralpatel.net/blogs/2009/12/tutorial-create-struts-2-application-eclipse-example.html" title="Tutorial: Create Struts 2 Application in Eclipse">Tutorial: Create Struts 2 Application in Eclipse</a></li><li><a href="http://viralpatel.net/blogs/2010/12/jquery-ajax-handling-unauthenticated-request-ajax.html" title="jQuery Ajax &#8211; Handling unauthenticated requests via Ajax">jQuery Ajax &#8211; Handling unauthenticated requests via Ajax</a></li></ul></div>]]></content:encoded> <wfw:commentRss>http://viralpatel.net/blogs/2010/01/struts-2-ajax-tutorial-example-drop-down.html/feed</wfw:commentRss> <slash:comments>37</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 03:02:56 -->
