OGNL in Struts2 Tutorial

OGNL(Object-Graph Navigation language) is an expression language inherited by Struts from WebWork.

Use of OGNL

  • OGNL is used in struts to access model objects from a jsp page.
  • It can be used to bind GUI elements to model objects in struts framework.
  • It can be used to invoke methods of the model.
  • It can create lists,maps to be used with GUI.
  • Bind generic tags with model objects.

Value Stack

Value Stack is an object created prior to any struts action method is executed and is used to store actions and other objects. The struts framework stores the value stack in request attribute named “struts.valueStack” and is used by jsps to display action and other info.

Value Stack contains two logical units, the Object Stack and the Context Map.

valuestack

Action and other objects are pushed into the Object Stack where as maps (parameters, request, session, application, attr) are stored in Context Map.

Maps in the Context Map

  1. parameters. Is a map containing the parameters in the current request.
  2. request. Is a map containing attributes in the current request.
  3. session. Is a map containing the session attributes for the current user.
  4. application. Is a map containing the ServletContext attributes.
  5. attr. Is a map that searches for attributes in the the order: request, session, application.

OGNL can be used to access  objects in the Object Stack and the Context Map. To access Context Map properties we use a # in front of the OGNL expression, if not used search will take place from Object Stack.

eg #session.code returns the value of the session attribute code.

Accessing Object Stack object properties

[0].message,[0][“message”],or [0][‘message’] returns the message property value of the object on top.

[1].duration,[1].[“duration”],or [1][‘duration’] returns the duration property of the second object.

To print the duration property of the first stack object we can use <s:property value=”[0].duration”/>

Searching of property in Object Stack

[1].message–>starts searching for the message property from the 1st object in stack if not found searches in the next object at index position[2] and goes on.

[0].message is same as writing only message. In both cases the searching starts from the 1st object in the Value Stack.

Reading Object Properties in the Context Map

To access properties of Objects in the Context Map we can use any of the following forms.

#object.propertyName

#object[‘propertyName’]

#object[“propertyName”]

 

The folowing expression returns the firstName property of an employee object stored as the request attribute.

#request[“employee”][“firstName”]

 

The following expression will search for the lastAccessedTime attribute in the request object. If it doesn’t find in the request will search in the session and consequently in the application object.

#attr[‘lastAccessedTime’]

Accessing Methods an Fields using OGNL

Methods and fields can be accessed through OGNL. e.g @java.util.Calendar@DECEMBER is used to access the static property DECEMBER in Calendar class. To call a static function we use @pac1.pac2.Util@now(); if we have a static function called now() in the Util class in pac1.pac2 package.

To call a nonstatic field or function we use. object.fieldname or we can use [0].datepattern where [0] refers to the first object in the value stack.

How Struts2 Works

In Struts2 a filter called FilterDispatcher is used as the Front  Controller. To use this Dispatcher it has to be registered in the deployment descriptor as below.

Struts splits the task processing in its filter dispatcher into subcomponents called interceptors. Eg the work of the first interceptor is to populate the action object with the request parameters.

In Struts action method is executed after the the action’s properties are populated.

The method in the action returns a String. Eg if it returns a “Success” , or “failure”, depending upon the return value it can be forwarded to the result page. The forwarded result may not always be a jsp, it can even be a file to be downloaded.

Working of the Filter Dispatcher

The work of the Filter Dispatcher is to first verify the request URI and determine which action to invoke. Struts uses the configration file struts.xml which matches URIs with action classes. One has to create a struts.xml and put it in the WEB-INF/classes folder. In this xml file the action definitions,concrete action class name, URI to invoke the action should be placed. If the name of the method in the action is other then execute then it should be also mentioned in the web.xml.

The action class should have at least one result to tell what to do after the action method is executed. It can have multiple results if the action method returns different results depending upon the user input.

When struts starts it reads the struts.xml. When ever struts gets a request it checks the timestamp of the struts.xm. Itf it is recent then when it was last time loaded then it is reloaded, thereby if one makes changes to the struts.xml, restarting the server is not required.

During each action invocation the filter dispatcher does the following steps.

1) It consults the Configuration Manager to find out which action to execute depending on the request URI.
2)Invoke the interceptors registered with this action. First interceptor will populate the properties of the action.
3)Executes the action method.
4)Executes the result.

How Struts2 Works

Declarative Exception Handling in Struts

Declarative Exception Handling is the procedure of handling Exceptions declaratively through the help of xml files. It is not needed to include exception-handling code in the java code of the application. The way of handling the exception would be specified in the xml file. In case of struts it is specified in the struts-config.xml file. The benefit of Declarative Exception Handling is if ever there is need to change the exception handling mechanism, changes can be made to the xml file, without the need to recompile the java code. The exception handling mechanism is decoupled from the rest of the application, which is very important property of a good software design.

If one uses the old exception handling mechanism there would be a lot of exception handling code duplication. For example if 40 to 50 struts Action subclasses use a business logic that has a method that throws some exception, then there will be a lot of exception handling code duplicated in all these Action subclasses. If ever there is need to make some change in the exception handling code then it has to changed in all the Action subclasses. But in case of Declarative exception handling code changes can be easily done in one place and it will be visible everywhere.

Configuring Declarative Exception handling in Struts
Exception handler definition should be stated in the struts-config.xml as forward definitions are specified in it. Similar to forward definitions there are two type of exception handler definitions, they are global and local action specific exception handler definition. Global exception handlers are available to the whole application where as local action specific are available to that particular action.

E.g. of configuring

The code below should be included in the struts-config.xml for global exceptions.

Explanation:

“type”: holds the fully qualified class name of the exception that the handler will handle.

“key”: holds the key in the properties file that will help to produce the error message when this exception occurs.

“path” holds the page that will be opened when an exception occurs.

Below code should be included for action specific exception handling

Using the above technique

If there is a NoResultsFoundException type of object thrown outside SearchAction then only it cannot be caught by the handler. It can only be caught if it is thrown from inside the SearchAction. For Declarative exception handling the try and catch blocks that were used should be removed from the actions so that it will be handled by strutshandler.

Steps for creating a custom exception handler.
1) A new exception handler class is created
2) The definition of the new exception handler is added to the struts-config.xml.

Creating a new Exception Handler class.
A class should be created that extends the org.apache.struts.action.ExceptionHandler. The execute method should be overridden by functionality of our default handler.

Adding the definition of the new exception handler in the struts-config.xml.

 

Difference Between Struts 1 and Struts 2

1) ActionServlet is the Controller Servlet used in Struts 1. The same work is done by a Filter in Struts2.

2) ActonForms are used in Struts 1. These classes map with the jsp forms. The Action classes use the data in these ActonForms to populate Data Transfer Objects. But in Struts 2 Acton Forms are not used. The jsp forms direct map to POJO, and there is no need to create DTO, thereby the number of classes decreases leading to less maintenance.

3) Validation can be done in validate method of FormBean in Struts 1, but in Struts there is no FormBeans so validation code can be put in Action classes or Validator Framework can be used.

4) In Struts 1 the bean and logic tag libraries are often replaced by JSTL, but Struts 2 has such tag libraries that we don’t need to use JSTL.

5) Default location of the Single Configuration used in Struts 1 is the WEB-INF folder, whereas multiple configuration files can be used in struts 2 and should be put directly inside or sub directories in WEB-INF/classes.

6) Java 5 and servlet 2.4 are prerequisites for struts 2 because Annotation are heavily used in Struts 2.

7) In Struts 1 the action classes are made by subclassing the Action class but in struts 2 they are made by sub classing the ActionSupport class. An action class at the top can be used to service related actions.

Dependency Injection

Dependency Injection is a very popular Design pattern. It was earlier called Inversion of Control.
Explanation of Dependency Injection with an Example

Example.
The PersistenceManager class is used to persist objects to database

 

In the above example we have hardcoded the jndi name . It is not that all application will use the same jndi name. According to Dependency injection design pattern dependency should be injected to the using component.Here a DataSource object should be passed to the PersistenceManager instead of forcing it to create.

 

Now PersistenceManager is decoupled from DataSource so PersistenceManager becomes more reusuable

The User of the PersistenceManager class knows better what DataSource to use then the programmer. So the user will provide the DataSource instance whileusing the PersistenceManager.

DependencyInjection can used not only with constructor but also through setter methods in the PersistenceManager class.

Struts2 uses DependencyInjection to set the action properties with the request parameters.
So one won’t have to worry about populating the properties and can work on them present inside a method of the action.