Showing posts with label struts 2. Show all posts
Showing posts with label struts 2. Show all posts

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>".


Thursday, August 15, 2013

Creating sample Struts 2 Web application and deploying on Tomcat 7

This blog is extension of Configuring Eclipse's Dynamic Web project for Struts 2 with Maven and deploying on Tomcat 7.. In the previous blog you would have learned how to configure an eclipse dynamic web project with maven. Now I will use the same project to configure a sample struts 2 application.


We are going to create a sample application, that will provide a login screen to the user and prompt them to login. Incase of error it will show the error page and do simple validation using struts.


Our Struts application will consist of following components:-

src/main/java/com.struts2.demo.action Actions:
  1. LoginAction extends ActionSupport - this action class will have the logic to validate the user name/pwd and direct the call.
  2. MissingAction extends ActionSupport - empty action class for redirecting empty requests to a missing page.

src/main/resources/ struts files:

  1. struts.xml file
  2. sampleapp.xml - included struts file, to break up the configuration file into multiple files


src/main/resources/com.struts2.demo.action resource files:

  1. LoginAction-validation.xml - struts validation xml file. Does simple required string validations.
  2. package.properties - localization support properties file

src/main/webapp/sampleapp jsp files:

  1. error.jsp
  2. Login.jsp
  3. Missing.jsp
  4. src/main/webapp/index.html

src/main/webapp/WEB-INF: web.xml

1 Action classes -  

LoginAction 

/**
 * 
 */
package com.struts2.demo.action;

import com.opensymphony.xwork2.ActionSupport;

/**
 * @author 
 *
 */
public class LoginAction extends ActionSupport {

public String execute() throws Exception {

        if (isInvalid(getUsername())) return INPUT;

        if (isInvalid(getPassword())) return INPUT;

        return SUCCESS;
    }

    private boolean isInvalid(String value) {
        return (value == null || value.length() == 0);
    }

    private String username;

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    private String password;

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }


}

MissingAction


package com.struts2.demo.action;

import com.opensymphony.xwork2.ActionSupport;


public class MissingAction extends ActionSupport {
}


2 Resource Files

LoginAction-validation.xml

<?xml version="1.0"?>
<!DOCTYPE validators PUBLIC
          "-//Apache Struts//XWork Validator 1.0.2//EN"
          "http://struts.apache.org/dtds/xwork-validator-1.0.2.dtd">
<validators>
  <field name="username">
    <field-validator type="requiredstring">
      <message key="requiredstring"/>
    </field-validator>
  </field>
  
  <field name="password">
    <field-validator type="requiredstring">
      <message key="requiredstring"/>
    </field-validator>
  </field>

</validators>


package.properties

requiredstring=  ${getText(fieldName)} is required.
password= Password
username= User Name
Missing.message=  You have successfully logged in.

Error.message= Login/Pwd is wrong.

struts.xml


<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
  <constant name="struts.enable.DynamicMethodInvocation" value="false"/>
  <constant name="struts.devMode" value="true"/>
  
  <include file="sampleapp.xml"/>
  
</struts>

sampleapp.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">

<struts>
  <package name="sampleapp" namespace="/sampleapp" extends="struts-default">
    <action name="Login_*" method="{1}" class="com.struts2.demo.action.LoginAction">
      <result name="input">/sampleapp/Login.jsp</result>
      <result type="redirectAction">Missing</result>
      <result name="error">/sampleapp/error.jsp</result>
    </action>

    <action name="*" class="com.struts2.demo.action.MissingAction">
      <result>/sampleapp/{1}.jsp</result>
    </action>
      
  </package>
</struts>

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app id="struts_blank" version="2.4"
         xmlns="http://java.sun.com/xml/ns/j2ee" 
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
  <display-name>Struts</display-name>

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

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

  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
  </welcome-file-list>
</web-app>


3. JSP files

error.jsp

<%@ page contentType="text/html; charset=UTF-8" %>
<%@ taglib prefix="s" uri="/struts-tags" %>
<html>
<head><title>Login error</title></head>

<body>
<p>
    <s:text name="Error.message"/>
</p>

<ul>
    <li><a href="<s:url action="Login_input"/>">Sign On</a></li>
    
</ul>

</body>

</html>

Login.jsp

<%@ page contentType="text/html; charset=UTF-8" %>
<%@ taglib prefix="s" uri="/struts-tags" %>
<html>
<head>
    <title>Sign On</title>
</head>

<body>
<s:form action="Login">
    <s:textfield key="username"/>
    <s:password key="password" />
    <s:submit/>
</s:form>
</body>
</html>

Missing.jsp

<%@ page contentType="text/html; charset=UTF-8" %>
<%@ taglib prefix="s" uri="/struts-tags" %>
<html>
<head>
    <title>Sign On</title>
</head>

<body>
<s:form action="Login">
    <s:textfield key="username"/>
    <s:password key="password" />
    <s:submit/>
</s:form>
</body>

</html>

index.html

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
    <META HTTP-EQUIV="Refresh" CONTENT="0;URL=sampleapp/Login_input.action">
</head>

<body>
<p>Loading ...</p>
</body>
</html>


Your project structure in Eclipse should look like this:


Now when you deploy this application on Tomcat, you can access it via url -  http://localhost:8080/strutsapplication/

This will direct you to URL - http://localhost:8080/strutsapplication/sampleapp/Login_input.action and show the login page.

If you enter 1 as the password, it leads to error page.

If you do not enter anything in login or pwd fields, then validation is kicked and error messages are shown.

Configuring Eclipse's Dynamic Web project for Struts 2 with Maven and deploying on Tomcat 7.

This post will introduce you to creating a new Struts 2 dynamic web application to run on Tomcat 7. 

The motivation behind this post was, that I was looking for a archetype to create a web app that could be configured on Eclipse as a Maven project in Facets form and could be run directly on Eclipse using Tomcat 7 configured on eclipse. This might seem very simple to many, but lot of people get confused in setting up project in facets form, which can be bundled using maven in a way that it can be easily deployed on tomcat.

If you intend to create a struts web app that you would want to run on jetty server for development then you can use following archetypes to create sample applications. 


  • struts2-archetype-convention
  • struts2-archetype-blank
Once created you can run these applications using mvn jetty:run command.

Now back to creating a struts 2 based dynamic web application on Eclipse, that will run on Tomcat 7. Before starting with the development, you will need following software configured or downloaded.

  1. Eclipse IDE
  2. Tomcat 7 or 6 configured in Eclipse IDE.
  3. Maven 3 on Eclipse
  4. jdk 6 or 7


We start with creating a new Dynamic Web project in Eclipse

Create a new dynamic web project, New->New Dynamic Web Project in eclipse



Click next and again click next. On Web Module section, click the checkbox for "Generate web.xml dd"



Now click Finish button.

Now the transformation of the dynamic web application to a struts 2 application that could be bundled using maven and run on Tomcat starts.

Right click on the project and scroll to Configure, then click on Convert to Maven Project... link.



Enter the groupid, artifact id and select the packaging as war. Then click Finish button.

Now your project has been converted to a maven project. You could achieve up to this stage by running a struts 2 archetype. But I wanted to explain you this, in case you wanted to setup a web project from scratch.


If you check in your project properties, Project Facets section - you will find at the project is in facets form with Dynamic Web Module 3.0, Java 1.6 & JavaScript 1.0 selected.






 If you would have used an archetype to create the maven project then you would have to convert the project into Facets form from this section. That would have been an additional step.

Now add following dependencies in your pom.xml



<properties>

<struts2.version>2.3.8</struts2.version>

</properties>

<dependencies>

<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-core</artifactId>
<version>${struts2.version}</version>
</dependency>

<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-config-browser-plugin</artifactId>
<version>${struts2.version}</version>
</dependency>

<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-junit-plugin</artifactId>
<version>${struts2.version}</version>
<scope>test</scope>
</dependency>

<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.1.1</version>
</dependency>

<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.5</version>
<scope>test</scope>
</dependency>
</dependencies>


Now we create required folders, so that everything could be bundled properly.

Right click on Java Resources in your project and create following new Source Folder

  • src/main/java
  • src/main/resources



Delete existing WebContent folder

Scroll to src folder, you will find src/main with java & resources folders. Create new webapp folder.

Now your folder structures in Eclipse should look exactly like this.




Previous step is important, because that is the structure of the project that we want to achieve. So make sure your project structure exactly matches this.

Your Eclipse Deployment Assembly should look like this:-


Now we start configuring the project so that our struts 2 application can run.

Create a WEB-INF folder inside webapp, and create a web.xml file. Content of your web.xml file will be as follows:-

<?xml version="1.0" encoding="UTF-8"?>

<web-app id="struts_blank" version="2.4"

         xmlns="http://java.sun.com/xml/ns/j2ee" 
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
  <display-name>Struts Blank</display-name>

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

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

  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
  </welcome-file-list>
</web-app>


As you see that I have added struts 2 filter and filter mapping. This is required to run the struts2 application.


Now try running maven build, run mvn build or install from eclipse. You will need internet connection so that maven can download these dependencies from repository.This will package your empty project as war and populate target folder.


If you are getting an error like - Cannot nest 'Project/src/main/java' inside library 'Project/src

Then go to org.eclipse.wst.common.component,xml file in .settings of your project (visible from Navigator view) and make sure the contents of the file look like this. Otherwise update.


<?xml version="1.0" encoding="UTF-8"?><project-modules id="moduleCoreId" project-version="1.5.0"> <wb-module deploy-name="strutsapplication"> <wb-resource deploy-path="/WEB-INF/classes" source-path="/src/main/java"/> <wb-resource deploy-path="/WEB-INF/classes" source-path="/src/main/resources"/> <wb-resource deploy-path="/" source-path="/src/main/webapp" tag="defaultRootSource"/>/> <property name="context-root" value="strutsapplication" />/> <property name="java-output-path" value="/strutsapplication/target/classes"/> </wb-module> </project-modules>


Now your project is ready for creating a sample web application using struts 2 to run on Tomcat 7. Check my new blog http://javaredhot.blogspot.com/2013/08/creating-sample-struts-2-web-application.html for the same.

Creating sample struts 2 web application