Monday, November 25, 2013

Struts 2 and Apache Tiles Integration

This is an extension of a series of blogs I have written on Struts 2. Feel free to go through them on this blog site to a better understanding of how to create a web application and use Struts 2.

In this blog, I will be introducing Apache Tiles integration with Struts 2.

Tiles is a templating system. It can be used to create a common look and feel for a web application. Tiles can also be used to create reusable view components.


Benefits of Tiles are:-

  • Screen definitions - Create a screen by assembling Tiles : header, footer, menu, body, etc.
  • Layouts - Define common page layouts and reuse them across your website.
  • Dynamic page building - Tiles can be gathered dynamically during page reload. It is possible to change any attribute: layout, list of Tiles in portal, list of menu items, etc.
  • Reuse of Tiles / Components - If well defined, a Tile can be reused across multiple applications.
  • Multi-channels - It is possible to load different Tiles according to a key.


Configuring Tiles:-

Configuring pom.xml

Following tiles artifacts need to be added.
I am using ${tiles.version} = 2.2.2


<dependency>
<groupId>org.apache.tiles</groupId>
<artifactId>tiles-api</artifactId>
<version>${tiles.version}</version>
</dependency>
<dependency>
<groupId>org.apache.tiles</groupId>
<artifactId>tiles-compat</artifactId>
<version>${tiles.version}</version>
</dependency>
<dependency>
<groupId>org.apache.tiles</groupId>
<artifactId>tiles-core</artifactId>
<version>${tiles.version}</version>
</dependency>
<dependency>
<groupId>org.apache.tiles</groupId>
<artifactId>tiles-jsp</artifactId>
<version>${tiles.version}</version>
</dependency>
<dependency>
<groupId>org.apache.tiles</groupId>
<artifactId>tiles-servlet</artifactId>
<version>${tiles.version}</version>

</dependency>
<dependency>
<groupId>org.apache.tiles</groupId>
<artifactId>tiles-template</artifactId>
<version>${tiles.version}</version>

</dependency>

      <dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-tiles-plugin</artifactId>
<version>2.2.1</version>

</dependency>


Configuring web.xml to use Tiles:-

Once we have added all the Tiles dependencies in pom.xml, we need to add Tiles in our web.xml

Add following entries with you strtus2 entry. Your web.xml should look like this:-



<context-param>
   <param-name>
      org.apache.tiles.impl.BasicTilesContainer.DEFINITIONS_CONFIG
   </param-name>
   <param-value>
      /WEB-INF/tiles.xml
   </param-value>
   </context-param>

   <listener>
   <listener-class>
      org.apache.struts2.tiles.StrutsTilesListener
   </listener-class>
   </listener>

  <filter>
    <filter-name>struts2</filter-name>
    <filter-class>
      org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter
    </filter-class>
  </filter>

  <filter-mapping>
    <filter-name>struts2</filter-name>
    <url-pattern>/*</url-pattern>

  </filter-mapping>




Creating Tiles template and different jsps that will be included as tiles.

My tiles template would look like the image below. It will have a header jsp that contains the corporation name and logo. Body jsp that contains the dynamic content and a footer jsp that contains copyright information.
baseLayout.jsp

This is the tiles jsp that will hold the other jsps and act like a template page.

You see how I am using divs and css to create a table. It is always advisable to use div tables rather than normal html tables.


<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
 <head>
  <title> Struts2 Tiles sample</title>
 <style type="text/css">
    .divInner1{

        text-align:center;
        border: .1px solid;
        float:left;

    }
div.page {
width: 11in;
height: 8.5in;
padding: .5cm auto;
margin: .1cm auto;
border: 1px #D3D3D3 solid;
border-radius: 5px;
background: white;
box-shadow: 0 0 5px rgba(0, 0, 0, 0.1);
}
    </style>
 </head>

 <body>
 <div class="page">
<div style="display: table; ">
<div style="display: table-row; ">
<div class='divInner1' style="width: 11in; height: 1.5in;" >
<tiles:insertAttribute name="header" />
</div>
</div>
</div>
<div style="display: table;  float:left;">
<div style="display: table-row;">
<div class='divInner1' style="width: 11in; height: 4.5in;" >
<tiles:insertAttribute name="body" />
</div>
</div>
</div>
<div style="display: table; width: 7in; height: 6.5in; float:left;">
<div style="display: table-row;">
<div class='divInner1' style="width: 11in; height: .5in;">
<tiles:insertAttribute name="footer" />
</div>   
</div>
</div>
 </body>

</html>



header.jsp

Following is the code for header.jsp marked as "header" in tiles tag in baseLayout.jsp page above.

<div class="header">

<p>This is the header</p>

</div>

<style>

div.header

{

padding:2px 3px; 

background:white;

}

p {font-size:30px;font-family:Arial;font-weight:bolder;color:blue;}

</style>

footer.jsp

Following is the html code for footer.

<div class="footer">

<p>This is the footer</p>
</div>

<style>

div.footer

{

padding:2px 3px; 

background:white;

}

p {font-size:30px;font-family:Arial;font-weight:bolder;color:blue;}

</style>


body.jsp

This is the html code for body page.

<div class="body">
<p>This is the body area</p>
</div>
<style>
div.body
{
padding:2px 3px; 
background:white;
         }
p {font-size:30px;font-family:Arial;font-weight:bolder;color:blue;}
</style>


Configuring Tiles configuration file - tiles.xml

Now a tiles.xml file has to be created and kept along with web.xml in WEB-INF. This file tells about the configuration of tiles and corresponding jsp pages.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE tiles-definitions PUBLIC
   "-//Apache Software Foundation//DTD Tiles Configuration 2.0//EN"
   "http://tiles.apache.org/dtds/tiles-config_2_0.dtd">

<tiles-definitions>

   <definition name="baseLayout" template="/myapp/baseLayout.jsp">
      <put-attribute name="title"  value="Tiles Page"/>
      <put-attribute name="header" value="/myapp/header.jsp"/>
      <put-attribute name="body" value="/myapp/body.jsp"/>
      <put-attribute name="footer"   value="/myapp/footer.jsp"/>
   </definition>

   <definition name="success" extends="baseLayout">
   </definition>
  
</tiles-definitions>


Configuring struts.xml

Once you have created the baseLayout page, other tiles pages and configured the tiles.xml, now you will proceed to configuring the struts.xml so that everything could work.



<package name="sampleapp" namespace="/" extends="struts-default,json-default">
<result-types>
                    <result-type name="tiles"  class="org.apache.struts2.views.tiles.TilesResult" />

              </result-types>
                  ....
                  ....
                  <action name="/sampleapp/*" method="execute"  class="com.myorg.action.SampleAppAction">
<result name="success" type="tiles">success</result>
                   ....
                   ....
                   </action>
           </package>
                 


As you see in the code above, we define tiles with class TilesResult and then in our action, we direct result that are "success" to type="tiles".

This completes the sample implementation of tiles. 

Tiles framework is much more flexible and provided with much more feature, which you can try out after this sample implementation works.






Friday, November 22, 2013

Struts 2 -Repopulating a page with updated data after form submit

This post is an extension of my previous post( Creating sample Struts 2 Web Application ) that talks about creating Struts 2 web application. In this post I will talk about a much smaller and simpler trick to reload the submitted page with some updated content. I have seen on lots of forums, this question being asked that how do we show the same submitted page with new content.

 For that you need following entry as your struts.xml entry:-
<action name="loginaction" method="execute"  class="com.myorg.LoginAction">
<result name="input" >/sampleapp/Login.jsp</result>
<result name="success">/sampleapp/Login.jsp</result>
</action>


Now the entry in your Login.jsp page is, 


    <body>
              <s:form action="loginaction" method="post" > 
              <label for="name"><p>Enter your Name</p></label>
              <input type="text" size="50" name="id"/>
             <s:submit value="Submit" />
            </s:form>
      <s:if test="%{id != null}">
         <br/><p>Hello 
         <s:property value="id"/></h3>
     </s:if>

</body>


Your action class looks like this:-


public String execute() throws Exception {

if(null != id)
this.id = "Dear "+id;

        return SUCCESS;

    }


Now when you submit your page, and you have entered a name, it will be go to the action, and then repopulated on the refreshed Login page with text "Hello Dear <yourname>".