Struts 2: Introducing the framework - Part 1

Posted by jcargoo | Monday, October 20, 2008
| 0Delicious Twitter Reddit Digg Loading...


As I had already made the promise about the struts 2 annotations, I am pleased to present you in this post an example (I hope a clear one) regarding the utility of the annotations in struts.
The sample is to classic and easy to understand.
It consists of validating the login/password provided in a form against a hardcode values instead of a database (will be for another post).
The functional details of the application are

:
  • First Login page to invite the user to complete the login/password parameters and then clicks on the access button;
  • The validation of the submitted values is done in an action class. After this step, it is of course the role of this action to specify whichever of the pages (success/failure) sounds to be the correct one to be returned to the user. The hardcode value for login/password are : jcargoo/jcargoo;
  • Last step is an additional point which is the storing of the login value into the session. Since the application is classical, I wanted to add something which can be useful for other potential cases. Then, in the success page we can invoke the value of the stored session parameter (I mean the username).
Remark: To develop our application, I am using Myeclipse, Struts2, JRE5, MyEclipse Tomcat 6 (or you can use this : tomcat)
The architecture of the application is like the following:














  1. We start by creating a new web project named “struts2loginapplication”.
  2. Normally following the link mentioned above, you can get the Full Distribution of struts2. Just unzip it.
  3. Here are the “jar” files extracted from the unzipped full distribution of struts2 which you should select in the “add External JARS” under Properties/Java build Path/Libraries.





















Now we come back to the core of the application and will create the login page which has as name login.jsp and the code is:

<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<%@ taglib prefix="s" uri="/struts-tags"%>
<html>
<head>
<title>Login Application using Struts 2</title>
</head>
<body>
<s:form action=" annotatedLoginAuthentication " method="POST"
validate="true">
Please fill up the following access parameters
<s:actionerror />
<s:fielderror />
<s:textfield name="username" label="Username" />
<s:password name="password" label="Password" />
<s:submit value="Go!" />
</s:form>
</body>
</html>

This is simply the login success page to be displayed if the user has been correctly authenticated. The name of the page is success.jsp:

<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<%@ taglib prefix="s" uri="/struts-tags"%>
<html>
<head>
<title>Login Application using Struts 2</title>
</head>
<body>
Hi <s:property value="#session.username" />!, welcome to your first struts2 application.
</body>
</html>
Now let's develop the core of the application which is bluntly the main class to handle the login request. Its name will be AnnotatedLoginAuthentication and it will be packaged in the package name net.jcargoo.
ActionSupport class is provided by Struts2 framework to be extended by our class. It is a convenient helper class. ActionSupport represents a convenience class that provides default implementations of the Action interface and several other useful interfaces, giving us such things as data validation and localization of error message.
We have also imported the com.opensymphony.xwork2.validator.annotations package in order to use the annotations.

The use of Java annotations plays an important role in this zero-configuration scheme. Please refer to the following link for further details: Annotations.

Two annotations are needed in our application:

  1. Validation annotation: tells to Struts that the action in this class might need to be validated.
  2. RequiredStringValidator annotation: is used for the text input to hold a singular value.
  3. Result annotation: allows the definition of Action results in the Action class rather than an XML file.

Here is the code of our action:

package net.jcargoo;

/**
* @author JCargoo Community
*
*/

import java.util.Map;

import org.apache.struts2.config.Result;
import org.apache.struts2.config.Results;

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.validator.annotations.*;

@Validation
@Results( { @Result(name = "FAILURE", value = "/login.jsp"),
@Result(name = "SUCCESS", value = "/success.jsp") })
public class AnnotatedLoginAuthentication extends ActionSupport {

private String username = null;

private String password = null;

public String execute() throws Exception {

Map session = ActionContext.getContext().getSession();

if (!getUsername().equals("jcargoo")
|| !getPassword().equals("jcargoo")) {
addActionError("Invalid username and/or password! Please try again!");

return "FAILURE";

} else {
//Store the username value into the session to be used by //success page.
session.put("username", getUsername());
return "SUCCESS";
}

}

@RequiredStringValidator(message = "Please supply a username")
public String getUsername() {

return username;
}

public void setUsername(String value) {

username = value.trim();
}

@RequiredStringValidator(message = "Please supply a password")
public String getPassword() {

return password;
}

public void setPassword(String value) {

password = value;
}

}
Everything is clear now; the action is validating the values received from the login page. In case of it is Okay, it dispatches the user to the success page. Otherwise, it returns back to the login page requiring the user to validate again his authentication.

Now we should do the configuration of the action mapping in struts.xml. I know that I have told you about the zero-configuration scheme. But to be honest I wanted to use the “struts.xml” file in order to make clear how we can use this important configuration file. Be sure that this file is always useful even if we want to have the zero-configuration scheme as according to my experience, we can’t always have the zero-configuration and my further examples can confirm you this point.

struts.xml must be put in the classes directory (WebRoot/WEB-INF/classes)


<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>

<package name="LoginAuthentication" extends="struts-default">
<action name="LoginAuthentication">
<result>/login.jsp</result>
</action>
</package>


</struts>

Finally, here is the famous web.xml file:


<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<filter>
<filter-name>struts2</filter-name>
<filter-class>
org.apache.struts2.dispatcher.FilterDispatcher
</filter-class>

<init-param>
<param-name>actionPackages</param-name>
<param-value>net.jcargoo</param-value>
</init-param>

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

</web-app>


Of course now you know already the meaning of the FilterDispatcher as it was already discussed in this post.
The xml element init-param with value net.jcargoo tell Struts where to find annotations.

Let’s start now by using this URL (if you keep of course the by default Tomcat configuration…)
http://localhost:8080/struts2loginapplication/LoginAuthentication.action

Enjoy!:



















In this example we can define the LoginAuthentication action as an annotated action (then no need to define it in the struts.xml). Then it will be something like:

@Result( value="/login.jsp" )
public class AnnotatedLoginWelcomeAuthenticationAction extends ActionSupport {
/* EMPTY */
}

This action will be invoked like this: http://localhost:8080/struts2loginapplication/annotatedLoginWelcomeAuthentication.action

More enhancements can be brought to this application (CSS skin, resource files, Welcome html file…) but as you may know, this can be discussed in the comments.

If you check the html source code, you will find the following script added automatically:


<script type="text/javascript">
function validateForm_annotatedLoginAuthentication() {

}
</script>

Now you can really see the strength of the annotations.




How to encourage this blog if you like it:
  • Promote our sponsors;
  • Add any kind of comment or critic;
  • Ask me directly by email if you prefer.
Just do something like that, and I will have the huge pleasure to continue posting the best of the creativity I have.




Share this post ?

Digg Reddit Stumble Delicious Technorati Twitter Facebook

2 Previous Comments
  1. Anonymous | October 22, 2008 at 4:17 AM  

    hello
    i tested this exmple but i have error with filterdispatcher with this message
    GRAVE: Exception au d�marrage du filtre struts2
    java.lang.ClassNotFoundException: org.apache.struts2.dispatcher.FilterDispatcher
    at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1387)
    at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1233)
    at org.apache.catalina.core.ApplicationFilterConfig.getFilter(ApplicationFilterConfig.java:249)
    at org.apache.catalina.core.ApplicationFilterConfig.setFilterDef(ApplicationFilterConfig.java:397)
    at org.apache.catalina.core.ApplicationFilterConfig.init (ApplicationFilterConfig.java:108)
    at org.apache.catalina.core.StandardContext.filterStart(StandardContext.java:3709)
    at org.apache.catalina.core.StandardContext.start(StandardContext.java:4363)
    at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1045)
    at org.apache.catalina.core.StandardHost.start(StandardHost.java:719)
    at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1045)
    at org.apache.catalina.core.StandardEngine.start(StandardEngine.java:443)
    at org.apache.catalina.core.StandardService.start(StandardService.java:516)
    at org.apache.catalina.core.StandardServer.start(StandardServer.java:710)
    at org.apache.catalina.startup.Catalina.start(Catalina.java:578)

  2. jcargoo | October 22, 2008 at 4:25 AM  

    Hi,

    This error is very likely due to reason that you have not placed your struts.xml in right place, I mean in the classes folder.
    You have to pay attention that when you clean your project (compile it again) you loose all files under the folder classes. Just copy in again your struts.xml and it will works fine.


    Hope it clarifies.

    PS : The example above was tested and correctly been validated.

    Regards,