Monday, July 16, 2007

Java 6.0 Features

1) Introduction
This article covers the various new features of Java 6, also known as Mustang. This article assumes that readers have sufficient knowledge over the concepts and terminologies in Java 5.0. For more information on Java 5.0, readers can vist the resources available in javabeat here. Though there is no significant changes at the Language Level, though Mustang comes with a bunch of enhancements in the other areas like Core, XML and Desktop. Most of the features are applicable both to J2SE and J2EE Platforms.
2) Java 6 Features
A feature or an enhancement in Java is encapsulated in the form of a JSR. JSR, which stands for Java Specification Request is nothing but a formal proposal which details the need for a specific functionality to be available in the Java Platform that can be used by Applications. These JSR’s will be reviewed and released by a committee called Java Expert Groups (JEG). This article covers the following list of features (or JSRs') that comes along with the Java 6 Platform.
Pluggable Annotation Processing API (JSR 269)
Common Annotations (JSR 250)
Java API for XML Based Web Services - 2.0 (JSR 224)
JAXB 2.0 (JSR 222)
Web Services Metadata (JSR 181)
Streaming API for XML (JSR 173)
XML Digital Signature (JSR 105)
Java Class File Specification Update (JSR 202)
Java Compiler API (JSR 199)
JDBC 4.0 (JSR 221)
Scripting in the Java Platform (JSR 223)
The JSRs' that are covered in this article are Common Annotations, JDBC 4.0 and Scripting in the Java Platform. Rest of the JSRs' will be covered in the subsequent article.
3) Common Annotations
The aim of having Common Annotations API in the Java Platform is to avoid applications defining their own Annotations which will result in having larger number of Duplicates. This JSR is targeted to cover Annotations both in the Standard as well the Enterprise Environments. The packages that contain the annotations are javax.annotation and javax.annotation.security . Let us discuss in brief the commonly used Annotations that are available in this JSR in the next subsequent sections.
3.1) @Generated Annotation
Not all the source files or the source code in an application is hand-written by Developers. With the increasing number of Tools and Frameworks, most of the common Boiler-Plate Code is generated by the Tools or the Frameworks itself if they have been properly instructed. Such Tool Generated Code can be marked with @Generated Annotation. Consider the following sample code snippet,
JavaBeat Forums
Buy Whizlabs SCJP 5.0 Preparation Kit
Enter your email address: Latest JavaBeat Articles Delivered by FeedBurner
MyClass.java
public class MyClass{
public void developerCode(){
}
@Generated(
value = "ClassNameThatGeneratedThisCode",
comments = "This is Tool Generated Code",
date = "5 June 2007"
)
public void toolGeneratedCode(){
}
}

The value for the @Generated Annotation would be usually the class name that generated this code. Optionally, comments and date can be given to add more clarity to the generated code. Note this @Generated Annotation is not limited to a method definition, it can also be defined for Package Declaration, Class Declaration, Interface Declaration, Local Variable Declaration, Field Declaration, Parameter Declaration etc.
3.2) @Resource and @Resources Annotation
Any Class or Component that provides some useful functionality to an Application can be thought of as a Resource and the same can be marked with @Resource Annotation. This kind of Annotation can be seen normally in J2EE Components such as Servlets, EJB or JMS. For example consider the following code snippet,

@Resource(name = "MyQueue", type = javax.jms.Queue,
shareable = false,
authenticationType = Resource.AuthenticationType.CONTAINER,
description = "A Test Queue"
)
private javax.jms.Queue myQueue;

Queue is a class available as part of JMS API and it serves as a target for Asynchronous Messages being sent by Applications. The various properties to note in @Resource Annotation are: 'name' which is the JNDI Name of this resource, 'type' which is the type of the resource which usually points to the Fully Qualified Class Name, 'shareable' which tells whether this resource can be shared by other components in the Application or not, 'authenticationType' which indicates the type of authentication to be performed either by the Container or by the Application and the Possible values are AuthenticationType.CONTAINER and AuthenticationType.APPLICATION and 'description' which is a string that describes the purpose of this resource.
When the Application containing the @Resource Annotations are deployed to a Server, the Container will scan for all the Resource references during the time of Application loading and then will populate the @Resource References by assigning new instances.
@Resources is nothing but a collection of @Resource entries. Following is a sample code that defines @Resources Annotation,

@Resources({
@Resource(name = "myQueue" type = javax.jms.Queue),
@Resource(name = "myTopic" type = javax.jms.Topic),
})

3.3) @PostConstruct and @PreDestroy
J2EE Components are usually created by the Container or the Framework on which they are deployed. Container creates new components by calling the Default or the No Argument Constructor. It is a very common need that a component needs to get initialized with some default values after it has been created. @PostConstruct Annotation serves that purpose. It is a Method-Level Annotation, meaning that this Annotation can be applied only to a Method and it will be fired immediately as soon the Component is created by invoking the Constructor.
Consider the following set of code,
MyDbConnectionComponent.java
public class MyDbConnectionComponent{
public MyDbConnectionComponent(){
}
@PostConstruct()
public void loadDefaults(){
// Load the Driver Class.
// Get the Connection and Do other stuffs.
}
}

We can see that @PostConstruct Annotation is normally used to Initialize the Resources that are Context specific. The loadDefaults() method which is marked with @PostConstruct Annotation will be called immediately by the Container as soon as an instance of MyDbConnectionComponent is created. There are certain guidelines to be followed while defining the PostConstruct method such as: the method should not be marked as static, return type should be void, it cannot throw any CheckedExceptions etc.
The counterpart to @PostConstruct Annotation is the @PreDestroy Annotation. From the name of the Annotation itself, we can infer that the method that is marked with this Annotation will be called before an object is about to be removed or destroyed by the Container. Like the @PostConstruct Annotation, this is also a Method-Level Annotation and the following code snippet proves this,
MyDbConnectionComponent.java
public class MyDbConnectionComponent{
public MyDbConnectionComponent(){
}
@PreDestroy()
public void releaseResources(){
// Close the Connection.
// Unload the Class Driver from the System
}
}

The method releaseResources() will be called by the Container before the object is about to be Destroyed. Resource releasing code are ideal candidates to be placed in the @PreDestroy Annotation method.
3.4) Role Based Annotations
The following sections discuss the various Role-based Annotations that are very common in Applications that are very concerned about Security. A Typical Application is accessed by a wide range of Users and Users themselves fall into Several Roles. Considering an IT Organization, all Employees fall into the General Category of Roles namely Admin, Director, Manager, Engineer, Programmer etc. It is very common to see Applications following Role-Based Security Model. The Annotations @DeclareRoles, @RolesAllowed, @PermitAll, @DenyAll and @RunAs are Role-Based Annotations and are covered here.
3.4.1) @DeclareRoles Annotations
This is a Class-Level Annotation meaning that this Annotation is applicable only to a Class Declaration. If applied to a Class or a Component, it essentially declares the valid Set of Roles that are available for this Component. Consider the following code which will clarify this,
LeaveService.java
@DeclareRoles(value = {"Director", "Manager", "Others" })
public class LeaveService{
@Resource
private Context context;

public void applyLeave(){
// Any employee can apply for leave. So no need for any
// conditional check.
}
public void grantLeave(){
if(checkUserInRole()){
// Grant Leave.
}
}
public void cancelLeave(){
if(checkUserInRole()){
// Cancel Leave.
}
}
private boolean checkUserInRole(){
if( (context.isCallerInRole("Director") )
(context.isCallerinRole("Manager")) ){
return true;
}
return false;
}
}

In the above example, the component LeaveService has been marked with @DeclareRoles Annotations with Role Name values namely Director and Manager. It has three services namely: applying for leave (applyLeave()), granting for leave (grantLeave()) and cancellation of leave (cancelLeave()). It is acceptable that only Employees in the Superior Role (Director or Manager) can grant or deny leaves to their sub-ordinates. So additional conditional checks are done to ensure that whether the User who is accessing the grantLeave() or the cancelLeave() service belongs to either of the defined Roles(Director or Manager). Since any employee in a company can apply for a leave, (whose Role Name is given as Others), no conditional checks are done in applyLeave() method.
3.4.2) @RolesAllowed Annotation
This is a Class/Method Level Annotation which is used to grant access to some Service(s) to the defined set of Users who are mentioned by their Role Names in the Annotation. Let us get into the following example straightaway,
LeaveService.java
@DeclareRoles("A", "B", "C", "X", "Y", "Z")
@RolesAllowed("A", "B", "C")
public class MyServiceComponent{
@RolesAllowed(value = {"A", "X", "Y"} )
public void myService1(){
}
@RolesAllowed(value = {"B", "Y", "Z"} )
public void myService2(){
}
@RolesAllowed(value = {"X", "Y", "Z"} )
public void myService3(){
}
public void myService4(){
}
}

The above code declares various roles namely "A", "B", "C", "X", "Y" and "Z" for the component MyServiceComponent. The @RolesAllowed Annotation when applied to a method grant Access to Users who are in that Roles only. For example, only Users with Roles "A" or "X" or "Y" are allowed to access the method myService1(). In the case of myService2(), "B", "Y" or "Z" role Users are allowed to access it and so on.
What happens in the case of myService4()??
No @RolesAllowed is specified for this method. The fact is that, if a method doesn’t have @RolesAllowed Annotation attached to it, then it will inherit this property from the class where it has been defined. So, in our case, Users in the Role "A", "B" or "C" can access the method myService4() becuase these set of Roles have been defined at the Class Level. What if the Class Declaration itself doesn’t have the @RolesAllowed Annotation declared? The answer is simple: it will take all the Roles that are defined in @DeclareRoles.
3.4.3) @PermitAll and @DenyAll Annotation
These are Class/Method Level Annotations and if applied to a Class Declaration will affect all the methods in the class, and when applied to a method will affect that method only.
Consider the following sample,
MyClass.java
@DeclareRoles(value = {"A", "B", "C"} )
class MyClass{
@PermitAll()
public void commonService(){
}
@DenyAll
public void confidentialService(){
}
}

From the above code, it is inferred that commonService() method can be accessible by all Users irrespective of their Roles as it is marked with @PermitAll() annotation and no one can access the confidentialService() because it has been marked with @DenyAll() annotation.
4) Scripting Language for the Java Platform
4.1) Introduction
Java 6 provides the Common Scripting Language Framework for integrating various Scripting Languages into the Java Platform. Most of the popular Scripting Languages like Java Script, PHP Script, Bean Shell Script and PNuts Script etc., can be seamlessly integrated with the Java Platform. Support for Intercommunication between Scripting Languages and Java Programs is possible now because of this. It means that Scripting Language Code can access the Set of Java Libraries and Java Programs can directly embed Scripting Code. Java Applications can also have options for Compiling and Executing Scripts which will lead to good performance, provided the Scripting Engine supports this feature. Let us have a high-level overview of this JSR before going in detail.
Following sections provide the two core components of the Scripting engine namely,
Language Bindings
The Scripting API
4.2) Language Bindings
The Language Bindings provides mechanisms for establishing communications between the Java Code and the Script Code. More specifically, it deals with how actually a Java Object creating by a Script Code is stored and maintained by the Scripting Engine, how the Script Arguments are converted back and forth, how the Calls that are made to the Java Methods from within the Scripting Code got translated and how the return values from the Java Code are made available to the Scripting code. To illustrate on this further, consider the JavaScript Code,
JavaBeat Forums
Buy Whizlabs SCJP 5.0 Preparation Kit
Enter your email address: Latest JavaBeat Articles Delivered by FeedBurner

var aJavaString = new String("A Test String");

This piece of code essentially creates a new Java String object and assigns it to a JavaScript object called aJavaString which is of var type. As soon as the Rhino Script Engine (which is the Scripting Engine name for JavaScript) parses this Script Code, it has to create a new instance of String object and should store it somewhere. The place where Java Objects and Script objects are stored are referred to as Bindings in Java Scripting Terminology. Here, aJavaString acts as a Proxy Object for the real java.lang.String object.
Again consider the following code,

var aJavaString = new java.lang.String('A Test String');
var length = aJavaString.substring(7, 13);

So many Micro-Level Tasks are involved if we analyse the above piece of code carefully. They are listed as follows,
Script Arguments are Converted to Java Arguments
Java Method to be invoked is identified
Logic is performed on the invoked Java Method
Return Values, if any, are sent back to the Scripting Code
The first line indicates that a new instance of java.lang.String object is created and it is stored in a Java Script object called aJavaString. Here aJavaString acts as a Proxy Object for the original java.lang.String object. After that we can see that the arguments 7 and 13 are passed from the Script Code to the method String.substring(int,int). The Engine will now convert the arguments that are to be sent to the Java method by using the Default Script-Java Mappings which is very specific to every Script Engine. After that, the Scripting Engine must ensure the availability of the method String.substring(int,int) at the run-time by abundantly depending on the Java Reflection API. Now the method is invoked and the logic gets executed. The return values are then converted using the Java-Script Mappings as defined by the Script Engine and will get populated in the length JavaScript object.
4.3) Scripting API
This API allows Java Programs to take the full advantage of Directing Embedding Scripting Code into the Applications. It also provides a framework wherein New Scripting Engines can be easily plugged-in. The entire API is available in the javax.script package.
ScriptEngineManager class provides mechanisms for Searching and Adding Scripting Engines into the Java Platform. Convenient methods are available for Discovering Existing Scripting Engines. For example, the following code will iterate and will list down all the Script Engines that are available in the Java 6 Distribution.

List allFactories = ScriptEngineManager.getEngineFactories();
for(ScriptEngineFactory engineFactory : allFactories){
System.out.println("Engine Name" + engineFactory.getEngineName());
}

The ScriptEngineFactory is the Factory Class for creating ScriptEngine objects. As such, two different ways are there to get instances of ScriptEngine classes. One way is to call the method ScriptEngineFactory.getScriptEngine(). The other direct way is to depend on the ScriptEngineManager itself to call getEngineByName().

// First Way
ScriptEngineFactory rhinoFactory = getScriptEngineFactory();
ScriptEngine rhinoEngine = rhinoFactory.getScriptEngine();
// Second Way
String name = "javascript";
ScriptEngine rhinoEngine = ScriptEngineManager.getEngineByName(engineName);

Execution of scripts can be done by calling the ScriptEngine.eval(String) method.
Bindings as represented by javax.script.Bindings, provide key/name information to ScriptEngines. Two types of Binding Scopes are available, one is the Global Scope and the other is the Engine Scope. By default, the ScriptEngineManager manages some set of Default bindings, which can be obtained by making a call to ScriptManager.getBindings(). The Bindings that are obtained in this manner (i.e from ScriptEngineManager) are called Global Bindings. Following is the code to get a reference to the Global-Bindings object and to populate it with application-specific values.

Bindings globalBindings = scriptEngineManager.getBindings();
globalBindings.put("key1", "value1");
globalBindings.put("key2", "value2");

It is also possible to customize the Binding information on Engine-by-Engine basis. For example, to obtain Bindings that is very specific to a particular Engine, a call to ScriptEngine.getBindings() can be made. These Bindings that are obtained in this way are called Engine Bindings.
4.4) Sample Code
This following Sample Application demonstrates how to directly embed Scripting Code in Java Applications. Argument passing between the Java Code and the Script Code are illustrated in this Sample.

package test;
import javax.script.*;
public class ScriptTest{
public static void main(String[] args){
try{
// Create an instance of the Scripting manager.
ScriptEngineManager manager = new ScriptEngineManager();
// Get the reference to the rhino scripting engine.
ScriptEngine rhinoEngine = manager.getEngineByName("javascript");
// Get the Binding object for this Engine.
Bindings bindings = rhinoEngine.getBindings(ScriptContext.ENGINE_SCOPE);
// Put the input value to the Binding.
bindings.put("strValue", "A Test String");
// Populate the script code to be executed.
StringBuilder scriptCode = new StringBuilder();
scriptCode.append("var javaString = new java.lang.String(strValue);");
scriptCode.append("var result = javaString.length();");
// Evaluate the Script code.
rhinoEngine.eval(scriptCode.toString());
// Take the output value from the script, i.e from the Bindings.
int strLength = (Integer)bindings.get("result");
System.out.println("Length is " + strLength);
}catch(Exception exception){
exception.printStackTrace();
}
}
}

In the above code, a new instance of ScriptEngineManager is created in the very first line. Then, the Scripting Engine that comes shipped with the Mustang, (i.e, Rhino Java Script Engine) is obtained by calling ScriptEngineManager.getEngineByName("javascript"). Arguments are passed from and to the Java Code with the help of Bindings. The input string to be processed is added to the Bindings with the call to Bindings.put("strValue", "A Test String"). Notice how the input string is populated within the script code at run-time, var javaString = new java.lang.String(strValue). It means that at run-time the Script code becomes var javaString = new java.lang.String('A Test String'). Then the script is executed by calling the ScriptEngine.eval(String) method. The output which is the length of the input string is now in the Script variable called result. And as mentioned previously, since all the Script and the Java Objects will be maintained and controlled by the Bindings, it is possible to get the value of the Script object result directly by calling Bindings.get("result").
5) New Features in JDBC API
5.1) Introduction
Java Database Connectivity allows Application Programs to interact with the Database to access the Relational Data. JDBC provides the Pluggable Architecture wherein any type of Java Compliant Drivers can be plugged-in even during the run-time. The JDBC API provides functionality to establish Connection to the back-end Database session which can execute the Queries to get the Results. The new version of JDBC that comes along with Mustang is JDBC 4.0. JDBC 4.0 is one of the areas that were great affected with the new set of features. Let us look into the major features one by one.
5.2) No need for Class.forName("DriverName")
Before the advent of JDBC 4.0, Application Programmers have to manually load the Database Driver before making any Database Calls. The following code shows how to load a Database Driver before JDBC 4.0

Class.forName("FullyQualifiedNameOfTheDriverClass");

This has one major dis-advantage. Suppose if the Database Driver Vendor wishes to change the class name of the Driver, then it will result in Code change. But with the help of Service Provider Mechanism (which is available from Java 5), there is no need for the programmers to manually load the Driver. The Driver will be Loaded Automatically by the JVM if the Jar files that correspond to the Driver Class are in the appropriate class path.
Let us explain how the Service Provider Mechanism works. Two entities are of much interest in the Service Provider Mechanism. One is the Service itself which mostly contains a set of interfaces that deals with what the Service is all about and the other one is the Provider who will give a concrete and a well-defined Implementation for the Service. This Mechanism forces the Provider to package the service as a Jar which has to maintain a Directory Structure like this,

\\META-INF\\services\\FullNameOfTheService

Suppose if the JDBC Driver Provider wishes to make his implementation as a Service, then the Vendor should maintain a Directory Structure along with the file name like this,

\\META-INF\\services\\java.sql.Driver

Note that java.sql.Driver is the name of the File, and the file should contain only one entry which is the Name of the Provider Class that implements the Driver. For example, in the case of My SQL, the content of the file will be looking like the following,
File - Java.sql.Driver
com.mysql.jdbc.Driver # Class name of the Driver

JavaBeat Forums
Buy Whizlabs SCJP 5.0 Preparation Kit
Enter your email address: Latest JavaBeat Articles Delivered by FeedBurner
Through this mechanism, the JDBC Drivers will get Automatically Loaded by the Java Program. If there are Multiple Drivers in the Application’s class-path, then the first matching Driver will be taken into consideration and the rest of them will just be ignored.
5.3) Changes in Connection and Statement Interface
Certain new useful methods are added to the Connection interface. The following sections list down the commonly used methods. To check whether an Connection object is still valid/active or not, then the following method can be used,

int tenSeconds = 10;
Connection.isValid(tenSeconds);

The argument to Connection.isValid(int) is the Timeout value, which specifies the time duration the API should take to find out whether the Connection is valid. If the timeout interval exceeds, then false will be returned. A value of 0 for the time-out interval specifies an Infinite Time-out Duration.
Also there are methods for populating and retrieving the Client Information that a particular Driver supports with the help of Connection.getClientInfo() and Connection.setClientInfo(Properties) methods. Client information can also be set and retrieved individually using Connection.setClientInfo(String,String) and Connection.getClientInfo(String) methods.
The following methods are added into the Statement interface, Statement.isClosed(), Statement.setPoolable(boolean) and Statement.isPoolable(). Statement.isClosed() will return true if the Statement Object is closed by calling the Statement.close() method. By default, only PreparedStatement and CallableStatement are pooled by the Implementation. The call to Statement.setPoolable(true) will only act as a request to the Implementation to pool this Statement Object for better performance. Not all the implementations may support this feature and hence Applications should not depend on this feature always.
5.3) Enhanced SQL Exception Handling
Exception handling in JDBC has been enhanced a lot in JDBC 4.0. The following are the major areas where the enhancements are done.
Iterable SQL Exception
Concreate Sub Classes for specific SQL Exception
5.3.1) Iterable SQL Exception
The java.sql.SQLException now implements the Iterable interface which means that it can be iterated over to get the Next Set of Exceptions and can also be used in Enhanced For-Loops (available from Java 5.0). Consider the following piece of code,

try{
// Some Database Access Code
}catch(SQLException exception){
for(Throwable throwable: exception){
System.out.println(throwable.getMessage());
}
}

Before JDBC 4.0, Applications depended on SQLException.getNextException() to get the next Exception and looped over until the returned exception is not null.

try{
// Some Database Access Code
}catch(SQLException exception){
System.out.println(exception.getMessage());
SQLException nextException = exception.getNextException();
while (nextException != null){
System.out.println(nextException.getMessage());
nextException = nextException.getNextException();
}
}

5.3.2) Concreate Sub Class for specific SQL Exception
More number of SQL Exception related Sub-Classes are added to the API which encapsulates the State of the SQL Error. In general, these Exceptions fall into 3 categories namely Transient, Recoverable and Non-Transient.
Assume that some kind of SQL Exception has occurred during the Program run-time. If again when a try is made and if there is a possibility such that the program can recover from the Exception without making any application specific change, then it is a kind of Transient Exception. This exception is represented by the java.sql.TransientException class and the following are the identified Transient Exceptions in the JDBC 4.0 API.
SQLTimeoutException
SQLTransactionRollbackException
SQLTransientConnectionException
Minute variation of this Transient Exception is the Recoverable Exception which is represented by java.sql.SQLRecoverableException. Here the exception that has happened can be recovered by performing some Application Specific Recovery.
The last flavour of SQL Exception is the Non-Transient Exception and it is represented by java.sql.TransientException. It tells that an exception can never be recovered even though Infinite Number of Tries is performed by the Application Program. The following are the Exceptions available in this Category,
SQLDataException
SQLFeatureNotSupportedException
SQLIntegrityConstraintViolationException
SQLInvalidAuthorizationSpecException
SQLNonTransientConnectionException
SQLSyntaxErrorException
5.3.3) Support for SQL RowId
Most of the popular Databases support the concept of a Row Id. A Row Id is an unique Identifier which is used to identify a Row. Support for Retrieving and setting the Row Id for a row is made available from JDBC 4.0 version. For example, consider the following piece of code, which will retrieve the value of the Row Id for a particular Row.

String selectQuery = " select rowid from Employees where id ='123' ";
ResultSet resultSet = statement.executeQuery("selectQuery");
java.sql.Rowid rowId = resultSet.getRowId();

The Row Id is represented by java.sql.RowId class. Before doing any kind of manipulation on the Row Id, it is wise to check whether the under-lying Database implementation provides Support for Row Id(s), as well as the Lifetime of the Row Id objects. The life-time of the Row Id determines how long the Row Id is valid, whether the Row Id exists only for a particluar Session or for a Set of Transactions within a Session or Outside the Database Session etc. This availability can be known with the help of DatabaseMetaData like the following,

RowIdLifeTime rowIdLifeTime = DatabaseMetaData.getRowIdLifetime();
if (rowIdLifeTime != ROWID_UNSUPPORTED){
// Row Id support is there for this Data source.
}

The returned RowIdLifeTime is an Enum which tells about the Life-Time of the Row Id object. Possible values are ROWID_UNSUPPORTED, ROWID_VALID_FOREVER, ROWID_VALID_OTHER, ROWID_VALID_SESSION, ROWID_VALID_TRANSACTION and ROWID_VALID_FOREVER.
6) Conclusion
This article covered some of the new features available in Java 6. It started off with the JSR that aimed in defining the Common Set of Annotations that can be used by Application Programs. Each and every Annotation in this package is briefly explained and examples were given to make it more understandable. Then, the Common Scripting Language Framework for the Java Platform is given in depth discussion along with the concept of Bindings, Scripting API and with a Sample Program. Then the new existing features of JDBC 4.0 like the Automatic Driver Loading, various new methods added to Connection/Statement interface and Enhanced SQL Exception Handling are also explained.


Java 6.0 Features Part - 2 : Pluggable Annotation Processing API

1) Introduction
The first part of this article listed out the major new features of Java 6 (Mustang) related to areas like Common Annotations (JSR 250), Scripting Language for the Java Platform (JSR 223) and JDBC 4.0. This article assumed that Readers have got sufficiently fair bit of knowledge in the various concepts of Java 5.0. First-time Readers of Java 6 are strongly encouraged to read the first part of this article titled "Introduction to Java 6.0 New Features, Part–I". This article covers the left-over features of Part-I. More specifically, it will cover the Pluggabable Annotation Processing API (JSR 269), Java API for XML Binding (JSR 222) and Streaming API for XML (JSR 173).
2) Pluggable Annotation Processing API
2.1) Introduction to Annotation
Annotations have been there in the Java World from Java 5.0. Java Annotations are a result of the JSR 175 which aimed in providing a Meta-Data Facility to the Java Programming Language. It can be greatly used by the Build-time Tools and Run-time Environments to do a bunch of useful tasks like Code Generation, Validation and other valuable stuffs. Java 6 has introduced a new JSR called JSR 269, which is the Pluggable Annotation Processing API. With this API, now it is possible for the Application Developers to write a Customized Annotation Processor which can be plugged-in to the code to operate on the set of Annotations that appear in a Source File.
Let us see in the subsequent sections how to write a Java File which will make use of Custom Annotations along with a Custom Annotation Processor to process them.
2.2) Writing Custom Annotations
This section provides two Custom Annotations which will be used by a Sample Java File and a Custom Annotation Processor. One is the Class Level Annotation and the other is the Method Level Annotation. Following is the listing for both the Annotation Declarations. See how the Targets for the Annotations ClassLevelAnnotation.java and MethodLevelAnnotation.java are set to ElementType.TYPE and ElementType.METHOD respectively.
ClassLevelAnnotation.java
package net.javabeat.articles.java6.newfeatures.customannotations;
import java.lang.annotation.*;
@Target(value = {ElementType.TYPE})
public @interface ClassLevelAnnotation {
}

MethodLevelAnnotation.java
package net.javabeat.articles.java6.newfeatures.customannotations;
import java.lang.annotation.*;
@Target(value = {ElementType.METHOD})
public @interface MethodLevelAnnotation {
}

AnnotatedJavaFile.java
package net.javabeat.articles.java6.newfeatures.customannotations;
@ClassLevelAnnotation()
public class AnnotatedJavaFile {

@MethodLevelAnnotation
public void annotatedMethod(){
}
}

The above is a Sample Java File that makes use of the Class Level and the Method Level Annotations. Note that @ClassLevelAnnotation is applied at the Class Level and the @MethodLevelAnnotation is applied at the method Level. This is because both the Annotation Types have been defined to be tagged to these respective Elements only with the help of @Target Annotation.
2.3) Writing a Simple Custom Annotation Processor
TestAnnotationProcessor.java
package net.javabeat.articles.java6.newfeatures.customannotations;
import java.util.*;
import javax.annotation.processing.*;
import javax.lang.model.*;
import javax.lang.model.element.*;
@SupportedAnnotationTypes(value= {"*"})
@SupportedSourceVersion(SourceVersion.RELEASE_6)
public class TestAnnotationProcessor extends AbstractProcessor {

@Override
public boolean process(
Set extends TypeElement> annotations, RoundEnvironment roundEnv){

for (TypeElement element : annotations){
System.out.println(element.getQualifiedName());
}
return true;
}
}

Let us discuss the core points in writing a Custom Annotation Processor in Java 6. The first notable thing is that Test Annotation Processor class extends AbstractProcessor class which encapsulates an Abstract Annotation Processor. We have to inform what Annotation Types our Test Annotation Processor Supports. This is manifested through the Class-Level Annotation called @SupportedAnnotationTypes(). A value of "*" indicates that all types of Annotations will be processed by this Annotation Processor. Which version of Source Files this Annotation Processor supports is mentioned through @SupportedSourceVersion Annotation.
The javac compiler of Mustang has an option called '-processor' where we can specify the Name of the Annotation Processor along with a Set of Java Source Files containing the Annotations. For example, in our case, the command syntax would be something like the following,

javac -processor
net.javabeat.articles.java6.newfeatures.customannotations.TestAnnotationProcessor
AnnotatedJavaFile.java

The above command tells that the name of the Annotation Processor is net.javabeat.articles.java6.newfeatures.customannotations.TestAnnotationProcessor and it is going to process the AnnotatedJavaFile.java. As soon as this command is issued in the console, the TestAnnotationProcessor.process() method will be called by passing the Set of Annotations that are found in the Source Files along with the Annotation Processing Information as represented by RoundEnvironment. This TestAnnotationProcessor just list the various Annotations present in the Sample Java File (AnnotatedJavaFile.java) by iterating over it.
Following is the output of the above program

net.javabeat.articles.java6.newfeatures.customannotations.ClassLevelAnnotation
net.javabeat.articles.java6.newfeatures.customannotations.MethodLevelAnnotation

3) Streaming API for XML
3.1) Introduction
Streaming API for XML, simply called StaX, is an API for reading and writing XML Documents. Why need another XML Parsing API when we already have SAX (Simple API for XML Parsing) and DOM (Document Object Model)? Both SAX and DOM parsers have their own advantages and disadvantages and StaX provides a solution for the disadvantages that are found in both SAX and DOM. It is not that StaX replaces SAX and DOM.
SAX, which provides an Event-Driven XML Processing, follows the Push-Parsing Model. What this model means is that in SAX, Applications will register Listeners in the form of Handlers to the Parser and will get notified through Call-back methods. Here the SAX Parser takes the control over Application thread by Pushing Events to the Application. So SAX is a Push-Parsing model. Whereas StaX is a Pull-Parsing model meaning that Application can take the control over parsing the XML Documents by pulling (taking) the Events from the Parser.
The disadvantage of DOM Parser is, it will keep the whole XML Document Tree in memory and certainly this would be problematic if the size of the Document is large. StaX doesn’t follow this type of model and it also has options for Skipping a Portion of a large Document during Reading.
The core StaX API falls into two categories and they are listed below. They are
Cursor API
Event Iterator API
Applications can any of these two API for parsing XML Documents. Let us see what these APIs’ are in detail in the following sections.
3.2) Cursor API
The Cursor API is used to traverse over the XML Document. Think of a Cursor as some kind of Pointer pointing at the start of the XML Document and then Forwarding the Document upon properly instructed. The working model of this Cursor API is very simple. When given a XML Document and asked to parse, the Parser will start reading the XML Document, and if any of the Nodes (like Start Element, Attribute, Text, End Element) are found it will stop and will give information about the Nodes to the Processing Application if requested. This cursor is a Forward only Cursor, it can never go backwards. Both Reading and Writing operations is possible in this cursor API.
3.3) Sample Application
Let us consider a sample Application which will read data from and to the XML Document with the help of the Cursor API. Following is the sample XML Document. The below XML File contains a list of Events for a person in his/her Calendar.
myCalendar.xml


With my Manager
At the Conference Hall
June 09 2007




For my Girl Friend
01 December




ReadingUsingCursorApi.java
package net.javabeat.articles.java6.newfeatures.stax;
import java.io.*;
import javax.xml.stream.*;
import javax.xml.stream.events.*;
public class ReadingUsingCurorApi {

private XMLInputFactory inputFactory = null;
private XMLStreamReader xmlReader = null;

public ReadingUsingCurorApi() {
inputFactory = XMLInputFactory.newInstance();
}

public void read() throws Exception{

xmlReader = inputFactory.createXMLStreamReader(
new FileReader(".\\src\\myCalendar.xml"));

while (xmlReader.hasNext()){

Integer eventType = xmlReader.next();
if (eventType.equals(XMLEvent.START_ELEMENT)){
System.out.print(" " + xmlReader.getName() + " ");
}else if (eventType.equals(XMLEvent.CHARACTERS)){
System.out.print(" " + xmlReader.getText() + " ");
}else if (eventType.equals(XMLEvent.ATTRIBUTE)){
System.out.print(" " + xmlReader.getName() + " ");
}else if (eventType.equals(XMLEvent.END_ELEMENT)){
System.out.print(" " + xmlReader.getName() + " ");
}
}
xmlReader.close();
}

public static void main(String args[]){
try{
ReadingUsingCurorApi obj = new ReadingUsingCurorApi();
obj.read();
}catch(Exception exception){
exception.printStackTrace();
}
}
}

XMLInputFactory is the Factory Class for creating Input Stream objects which is represented by XMLStreamReader. An instance of type XMLStreamReader is created by calling XMLInputFactory.createXMLStreamReader() by passing the XML File to be parsed. At this stage, the Parser is ready to read the XML Contents if a combination call to XMLStreamReader.hasNext() and XMLStreamReader.next() is made. The entire Document is traversed in the while loop and the appropriate node's value is taken by checking the various Element Types.
3.4) Event Iterator API
The Working Model of this Event Iterator API is no more different from the Cursor API. As the Parser starts traversing over the XML Document and if any of the Nodes are found, it will provide this information to the Application that is processing in the form of XML Events. Applications can loop over the entire Document, by requesting for the Next Event. This Event Iterator API is implemented on top of Cursor API.
3.5) Sample Application
Now let us take over a Sample Application using the Event Iterator API which is parsing on the XML Document myCalendar.xml.
ReadingUsingEventIterator.java
package net.javabeat.articles.java6.newfeatures.stax;
import java.io.*;
import javax.xml.stream.*;
import javax.xml.stream.events.*;
public class ReadingUsingEventIteratorApi {

private XMLInputFactory inputFactory = null;
private XMLEventReader xmlEventReader = null;

public ReadingUsingEventIteratorApi() {
inputFactory = XMLInputFactory.newInstance();
}

public void read() throws Exception{

xmlEventReader = inputFactory.createXMLEventReader(
new FileReader(".\\src\\myCalendar.xml"));

while (xmlEventReader.hasNext()){

XMLEvent xmlEvent = xmlEventReader.nextEvent();
if (xmlEvent.isStartElement()){
System.out.print(" " + xmlEvent.asStartElement().getName() + " ");
}else if (xmlEvent.isCharacters()){
System.out.print(" " + xmlEvent.asCharacters().getData() + " ");
}else if (xmlEvent.isEndElement()){
System.out.print(" " + xmlEvent.asEndElement().getName() + " ");
}
}

xmlEventReader.close();
}
public static void main(String args[]){
try{
ReadingUsingEventIteratorApi obj = new ReadingUsingEventIteratorApi();
obj.read();
}catch(Exception exception){
exception.printStackTrace();
}
}
}

If XMLStreamReader class represents the Reader for stream reading the XML Contents, then XMLEventReader represents the class for reading the XML Document as XML Events (represented by javax.xml.stream.events.XMLEvent). The rest of the reading logic is the same as that of the ReadingUsingCurorApi.java.

4) Mapping Java Objects and XML Documents using JAXB
4.1) Introduction
JAXB (Java API for XML Binding) technology which was included as part of JWSDP (Java Web Services Developer Pack) before, is now included with the Mustang Distribution. Simply put, it is a Mapping Technology for Java and XML Documents. Using JAXB, one can Generate XML Documents from Java Objects and also they can Construct Java Objects from one or more XML Documents. In JAXB terms, Marshalling refers to the process of converting a Java Object to a XML Document and Un-Marshalling is the reverse of Marshalling which is simply getting a Java Object from one or more XML Documents.
Let us see along with Samples how to work with Marshalling and Un-Marshalling with JAXB.
4.2) Generating XML Documents from Java Objects
Assume that you want to have a XML Representation of a Java object. Using JAXB Marshalling you can do with much ease and the following Sample Application illustrates the same,
Person.java
package net.javabeat.articles.java6.newfeatures.jaxb;
import java.util.Date;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement()
public class Person {

private String name;
private int age;
private Date dateOfBirth;
private String type;

public Person(){
}

public Person(String name, int age, Date dateOfBirth, String type) {
this.name = name;
this.age = age;
this.dateOfBirth = dateOfBirth;
this.setType(type);
}
@XmlElement()
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@XmlElement()
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@XmlElement()
public Date getDateOfBirth() {
return dateOfBirth;
}
public void setDateOfBirth(Date dateOfBirth) {
this.dateOfBirth = dateOfBirth;
}
@XmlAttribute()
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
}

The above Person class has various properties namely 'name', 'age', 'dateOfBirth' and 'type' and objects of this Class are the targets we wish to Marshal. The Person class is annotated with @XmlRootElement since we want the name of the Class to be the Root Node. We want 'name', 'age', and 'dateOfBirth' as Child Elements so it has been tagged with @XmlElement. Since we want 'type' to appear as an Attribute we had tagged that as @XmlAttribute.
Java2XML.java
package net.javabeat.articles.java6.newfeatures.jaxb;
import java.io.FileWriter;
import java.util.*;
import javax.xml.bind.*;
public class Java2XML {

public Java2XML() {
}
public static void main(String args[]) throws Exception{
JAXBContext context = JAXBContext.newInstance(Person.class);
Marshaller marshaller = context.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);

Person person = new Person(
"Anonymous", 32, new Date(1970, 1, 10), "employee");
marshaller.marshal(person, new FileWriter(".\\src\\Person.xml"));
}
}

JAXBContext serves as the Entry Point for making use of the JAXB API. It is initiated by the list of Class objects whose objects want to be represented as XML Documents. Then an instance of Marshaller is created by calling JAXBContext.createMarshaller() method. The Java object of type Person is marshalled into the XML Document by calling the Marshaller.marshall() method. Since we want the XML Document to look Well-indented, we have set the property Marshaller.JAXB_FORMATTED_OUTPUT to true.
A file named Person.xml would have got generated and following is the listing of that file,
Person.xml


32
1970-01-10 T00:00:00+05:30
Anonymous


4.3) Representing Java Objects from XML Documents
In the previous section, we saw how to generate an XML Document from a Java Object. Now, let us see the Unmarshalling process here. As mentioned, Unmarshalling is the process of representing Java Objects from a XML Document. The process of Unmarshalling is a bit complicated as so many steps are involved. Let us break the steps one by one in greater detail.
4.3.1) Creating the XML Schema Definition File
If Java Classes represent the templates wherein objects can be created for a particular type, then in XML World, it is the XML Schema Definition File through which XML Document Instances can be instantiated. The first thing before creating a XML Document is to create a XML Schema and then to attach the Schema to a XML Document Instance. Let us look into a sample XML Schema File called Items, which will contain a list of 'Item' Elements along with its 'Name' and 'Price'. Following is the listing of that File.
Items.xsd






















The above is the XML Schema Definition File which represents a list of Items. Since 'Items' element contain a list of Item elements and 'Item' element in turn contains both 'Name' and 'Price' Element, both these elements are Composite Elements and the same is represented by complexType elements.
4.3.2) Generating Java Files from the Schema Definition Files
Now, its time to generate the Java Source Files from this XML Schema Definition File. Mustang comes with a Utility called xjc (which stands for XML to Java Compiler) which generates Java Source Files when given a XML Schema File. Xjc is nothing but a bat file location in the bin directory of the Java 6 Installation Path. Run the following command to generate the Java Source Files.

xjc –p net.javabeat.articles.java6.newfeatures.jaxb Items.xsd

The only argument to xjc is the name of the XML Schema File which is represented by Items.xsd and the ‘-p’ option specifies the package to which the generated Java Files have to be associated. This results is the generation of the following source files.
Item.java
package net.javabeat.articles.java6.newfeatures.jaxb;
import javax.xml.bind.annotation.*;
import javax.xml.bind.annotation.adapters.*;
import net.javabeat.articles.java6.newfeatures.jaxb.*;
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
"name",
"price"
})
@XmlRootElement(name = "Item")
public class Item {
@XmlElement(name = "Name")
protected String name;
@XmlElement(name = "Price")
protected String price;
@XmlAttribute(required = true)
@XmlJavaTypeAdapter(CollapsedStringAdapter.class)
protected String id;
public String getName() {
return name;
}
public void setName(String value) {
this.name = value;
}
public String getPrice() {
return price;
}
public void setPrice(String value) {
this.price = value;
}
public String getId() {
return id;
}
public void setId(String value) {
this.id = value;
}
}

This file is just a Data file for the corresponding 'Item' element which contains getter and setter methods with properly instructed Annotations. Note that the two sub-elements namely ‘name’ and ‘type’ has been tagged with @XmlElement Annotation and the attribute ‘id’ has been tagged with @XmlAttribute Annotation.
Items.java
package net.javabeat.articles.java6.newfeatures.jaxb;
import java.util.*;
import javax.xml.bind.annotation.*;
import net.javabeat.articles.java6.newfeatures.jaxb.*;
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
"item"
})
@XmlRootElement(name = "Items")
public class Items {
@XmlElement(name = "Item")
protected List item;
public List getItem() {
if (item == null) {
item = new ArrayList();
}
return this.item;
}
}

This is the Container Class for the Item element and it just contains a getter for the Item object. Note how the list of 'Item' elements in the Schema Document has been mapped to List of Item (List) elements. This is the Default Mapping given by the Sun's Reference Implementation for JAXB.
ObjectFactory.java
package net.javabeat.articles.java6.newfeatures.jaxb;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.annotation.XmlElementDecl;
import javax.xml.bind.annotation.XmlRegistry;
import javax.xml.namespace.QName;
import net.javabeat.articles.java6.newfeatures.jaxb.Item;
import net.javabeat.articles.java6.newfeatures.jaxb.Items;
import net.javabeat.articles.java6.newfeatures.jaxb.ObjectFactory;
@XmlRegistry
public class ObjectFactory {
private final static QName _Price_QNAME = new QName("", "Price");
private final static QName _Name_QNAME = new QName("", "Name");
public ObjectFactory() {
}
public Item createItem() {
return new Item();
}
public Items createItems() {
return new Items();
}
@XmlElementDecl(namespace = "", name = "Price")
public JAXBElement createPrice(String value) {
return new JAXBElement(_Price_QNAME, String.class, null, value);
}
@XmlElementDecl(namespace = "", name = "Name")
public JAXBElement createName(String value) {
return new JAXBElement(_Name_QNAME, String.class, null, value);
}
}

As guessed from its name, this is the Factory Class for creating various elements like 'Items', 'Item', 'Name' and Price'. Appropriate methods are available for creating 'Items', 'Item', 'Name' and 'Price' in the form of ObjectFactory.createItems(), ObjectFactory.createItem(), ObjectFactory.createName() and ObjectFactory.createPrice() respectively.
4.3.3) Creating a Sample XML Document
Now let us create a Sample XML Document against the Schema Definition File Items.xsd. Following is the sample XML file called Items.xml. Note how the XML Document Instance is related with the XML Schema Definition File with the help of ‘xsi:noNamespaceSchemaLocation’ attribute.
Items.xml
xsi:noNamespaceSchemaLocation='file:C:/Items.xsd'>

Laptop
4343$


Television
433$


DVD Player
763$



4.3.4) Unmarshalling the XML Document to construct the Java object
The code to Unmarshall the XML Document is given below. The code first represents a JAXBContext object by passing in a Context Path which is usually the package name where the compiled Java Class files are located. Then an Unmarshaller object is created by calling JAXBContext.createUnmarshaller() which does the unmarshalling operation by calling the Unmarshaller.unmarshall() method passing in the XML File. Then the object is iterated over the get the actual data contents from the XML File.
XML2Java.java
package net.javabeat.articles.java6.newfeatures.jaxb;
import java.io.*;
import javax.xml.bind.*;
public class XML2Java {

public static void main(String args[]) throws Exception{

JAXBContext context = JAXBContext.newInstance(
"net.javabeat.articles.java6.newfeatures.jaxb");
Unmarshaller unmarshaller = context.createUnmarshaller();
Items items = (Items)unmarshaller.unmarshal(
new FileReader(".\\src\\Items.xml"));
List listOfItems = items.getItem();
for(Item item : listOfItems){
System.out.println("Name = " + item.getName() +
", Price = " + item.getPrice() + ", Id = " + item.getId());
}
}
}

Following is the output of the above program

Name = Laptop, Price = 4343$, Id = LAP001
Name = Television, Price = 433$, Id = TV001
Name = DVD Player, Price = 763$, Id = DVD001

5) Conclusion
This article covered the leftover features of the Part I New features of Java 6. Starting with Pluggable Annotation Processing API, it covered what Annotations are, then guided us how to write Custom Annotations and Custom Annotation Processor. Then it traversed over the Cursor API and the Event Iterator API of StaX such as how to read XML Documents along with well-defined samples. Finally through Java API for XML Binding, it details how to map Java and XML Documents with some sample applications.
Struts 2.0 Introduction and Validations using Annotationsby
Rishi Kant Sharma 17/07/2007
1) Introduction
This article provides an introduction to Struts 2.0 and its new Validation Features. Since Struts 2.0 is new, the first few sections of the article discusses in brief about the basics of Struts 2.0, its architecture and its various New Features. The rest of the article is dedicated towards explaining about the new Validation Features available. Struts is an Open-Source Web Application Framework that simplifies the creation of a Java Web Application. It is based on the Model-View-Controller 2 (MVC 2) Architecture which was originally found in a language called SmallTalk. The recent version of Struts is Struts 2.0 and it has borrowed most of the concepts in terms of architecture and functionality from two frameworks namely WebWork and XWork.
2) Struts 2.0 - MVC Architecture
Struts 2.0 is based on MVC 2 Architecture. MVC is mainly concentrated in splitting the whole set of logic that happens in an Application into three different layers namely the Model, View and the Controller. In Struts 2.0, the Controller acts as a mediator between the View and the Model components. Whenever a request comes from a client, it is this Controller component who intercepts the request before being passed to Appropriate Handler.
Model represents the application data as well as the business logic that operates on the Data. Whenever the Framework routes the request to some Action class, the Action Class will do the Business Processing Logic which results in the State of the Application getting affected. After the application's state is affected, the control is returned back to the Controller which determines which View to be Rendered to the Client Application.
View is the Display Surface given as a response back to the Client populated with values. Struts 2.0 is not restricted in having JSP as its only View. Any View Technolgy can be chosen to render the Client Surface. It can be JSP, Velocity, Freemaker, or even XSLT. Even a brand new View technology can be plugged-in easily to the Struts Framework.
3) The Flow of a Struts 2.0 Application
The following are the sequence of steps that will happen when a Html Client makes a request to a Web Application built on top of Struts 2.0
The Client (which is usually a Html Browser) makes a Request to the Web Application.
The Web Server will search for the Configuration Information that is very specific to the Web Application (taken from the web.xml file), and will identity which Boot-strap Component has to be loaded to serve the Client's Request.
In Struts 2.0, this Component is going to be a Servlet Filter (whereas in Struts 1.0, the component is an Action Servlet).
The Filter Servlet then finds out the Action Class for this Request that is mapped in the Configuration File. File.
Before passing the Request to the Action class, the Controller passes the Request to a series of Interceptor Stack (explained later).
Then the Request Object is passed on to the corresponding Action Class.
The Action Class then executes the Appropriate Business Logic based on the Request and the Request Parameters.
After the execution of the Business Logic, a Result ("success" or "error") is returned either in the form of String or in the form of Result Object back to the Controller.
The Controller uses the Return Result to choose which View to be rendered back to the Client Application.
Let us look into the details of the major steps that was listed above.
3.1) Filter Servlet Loaded and Invoked by the Framework
A client makes a Web Request by typing the URL of the Web Application that is hosted in the Web Server something like the following, where localhost is the Machine Name where the Web Server is running, 8080 is the Port Number and hello is the Application Context for the Web Application.

http://localhost:8080/hello

Whenever a Request comes to a Web Application that is Struts 2.0 Enabled, the Web Server will search and load the Configuration Related Information that is very specific to the Application. In the case of a Struts 2.0 enabled Application, the Boot-Strap Component is going to a Filter Servlet. The Configuration Information about the Web Application will be maintained separately in web.xml file. Following is the Xml snippet taken from the web.xml file,
web.xml

Struts2FilterServlet

org.apache.struts.action2.dispatcher.FilterDispatcher




Struts2FilterServlet
/*


The above Xml Code tells that whatever be the Request URI Pattern (which is indicated by /*) that comes from the Client, identify the Component named by Struts2FilterServlet which happens to be the class org.apache.struts.action2.dispatcher.FilterDispatcher. The Identified Component is then instantiated and then passed with the Request Information.
3.2) Request Intercepted by Interceptors
Interceptors provide Pre-processing and Post-processing functionality for a Request or a Response object in a Web Application. For general information about Interceptors, readers can go through this section on JavaBeat. A Request Object usually passes through a Series of Interceptors before actually reaching the Framework. Assume that some kind of Authentication and Authorization related stuffs have to be done before a Request Object is being passed to a particular Module. In such a case, we can have the Core Business Logic that does the functionality of authorizing the Client Request in an Interceptor called AuthenticationInterceptor which does the Pre-processing works. Implementing a Custom Interceptor like this is very simple in Struts 2.0. The class structure may look like this,
AuthenticationInterceptor.java
package myinterceptors;
import com.opensymphony.xwork2.interceptor.*;
class AuthenticationInterceptor implements Interceptor{
public void init(){}
public void destroy(){}
public String intercept(ActionInvocation invocation) throws Exception{

// Get the value of user credentials from the Request and Validate it.

}
}

As we can see, writing a Custom Interceptor is as simple as writing a class that implements the Interceptor interface which is found in the com.opensymphony.xwork2.interceptor package. The method of interest is Interceptor.intercept() which has to be overriden along with the the appropriate business logic. Then the Custom Interceptor has to be made available to the framework by adding information in the Configuration File (struts.xml) as shown below,
struts.xml

...

class = "myinterceptors.AuthenticationInterceptor">


...



Interceptors are configured into the Web Application in the struts.xml file with the help of and entries. The name attribute is the alias name of the interceptor and it must be unique among the other set of Interceptor names. The class attribute identifies the actual implementation class for an Interceptor. The advantages of interceptors is not only limited to this. Interceptors can participate in so many different activities, to name a few - providing Logging Information to an Application, providing Encryption Facilities for the user input that used to get transmitted across layers, etc.. . Struts 2.0 already comes with a bunch of Built-in Useful Interceptors.
3.3) Performing some Action for a Request
After passing through a series of Interceptors, now it is time for the Framework to determine what Action has to be done for the Request. The Mapping between a Request and its Corresponding Action is configurable in the Xml Configuration File. Assume that in a Web Application, Regitration, Login and Logout represents the different set of actions. Let us have an assumptions that the operations are fairly complex, so that we tend to have individual classes for each of the operation. These things are configured in the struts.xml like the following,
struts.xml






The Action Class usually acts as a Model and executes a particular business logic depending on the Request object and the Input Parameters. In earlier versions of Struts (before Struts 2.0), an Action class is supposed to extend the org.apache.struts.Action class and has to override the Action.execute() method which takes four parameters. Following is the code snippet of an Action class before Struts 2.0,
MyAction.java
package myactions;
import java.servlet.http.*;
import org.apache.struts.*;
class MyAction extends Action{
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws java.lang.Exception {

// Do some business logic here.

}
}

In Struts 2.0, an Action class is made flexible as it can be a simple POJO Class. It means that the Action Class doesn't need to extend some class or implement an interface. It can be as simple as possible, and the following code snippet proves the same,
MyAction.java
package myactions;
import com.opensymphony.xwork2.*;
class MyAction extends Action{
public String execute(){
// Some logic here.
}

}

Here comes the big question!. Then how can an Action class is supposed to access the HttpServletRequest and the HttpServletResponse objects to get the needed information!!! At this stage it is worth to mention about the Aware-Related Interfaces here. Suppose that an Action class wants to access the HttpServletRequest object. For this, it has to implement a special Aware Interface called ServletRequestAware and has to override the method setServletRequest(HttpServletRequest request) thereby storing it in an instance variable. So, the new modified action class becomes like this,
MyAction.java
package myactions;
import javax.servlet.http.*;
import com.opensymphony.xwork2.*;
import org.apache.struts2.interceptor.*;
class MyAction extends Action implements ServletRequestAware{
private HttpServletRequest request;
public String execute(){
}
public void setServletRequest(HttpServletRequest request){
this.request = request;
}
}

This above technique is basically an Inversion of Control. Inversion of Control is generally a Push Model which means that the data needed by the Application will be pushed by the Container or the Framework. In our case, we are making the Struts 2.0 Framework to call the method ServletRequestAware.setServletRequest(HttpServletRequest request) thereby populating the Request Object. Similar to this, there are Aware-Related Interfaces for Application, Servlet Request, Servlet Response, Parameters etc namely ApplicationAware, HttpServletRequestAware, HttpServletResponseAware, ParameterAware respectively.
3.4) Rendering the Result back to the Client
As we can see from the method signature, the return type of the Action.excute() method is just a String. This return type defines the Logical Outcome of the Action or the Page. Actual Outcome or the Response of a Page is configurable in the Struts Configuration File. Say the Action class can return a logical 'success' which tells that the action has be successfully processed or 'failure' which sadly tells that some thing wrong has happened in the Application. Some Predefined Constants have been defined in the Action interface for the logical outcomes namely, Action.SUCCESS, Action.ERROR, Action.LOGIN, Action.INPUT and Action.NONE. Consider the following code snippet,
MyAction.java
package myactions;
public class MyAction{
public String execute(){
if (createOperation()){
return "create";
}else if (deleteOperation()){
return "delete";
}else if( readOperation()){
return "read";
}else if (writeOperation()){
return "write";
}
return "error";
}
}

The above method returns a bunch of Logical Outputs namely "create", "delete", "read" and "write". The logical outcomes should have their Corresponding Mappings defined in the struts.xml like the following,
struts.xml




/myApp/create.jsp
/myApp/delete.jsp
/myApp/read.jsp
/myApp/write.jsp




4) Struts.xml Configuration File
All the Configuration Related Information are externalized from a Web Application by maintaining them in a Xml File. The new Struts 2.0 Configuration Xml File is very Simple and Modular when compared with its older versions. Let us look into the structure of the Struts 2.0 Configuration File and the Core Elements within them in detail in the following sections.
4.1) Modularization of Configuration Files
The first nice feature is the File Inclusion Faciltity. Assume that in a very complex Web Application, there are multiple modules and each module is designated to be developed by a particular team. Similar to the Modularization of Work, the configuration file can also be made modular using the File Inclusion Facility. For the sake of simplicity, let the assume that there are three modules namely "admin", "customer", "employer" in a Web Application. We can define the three modules in three different Configuration Files, and using the File Inclusion Facility, the three files can be directly included in the Main Configuration File. A Main Configuration File is nothing but a File that includes other Configuration Files. Examine the following code snippet,
Admin-Config.xml




Customer-Config.xml




Employee-Config.xml




All the above separate Configuration Files can be directly referenced or included in the Root Configuration File with the help of tag like the following,
Struts.xml









4.2) Grouping of Similar Actions inside a Package
Packages in Java are logically used to group similar Classes or Interfaces. Similary, there is a tag in Struts 2.0, which is used to Group Similar Actions along with Interceptors, Results, Exceptions etc. Following is the structure of the package element,
Struts.xml



















/myApp/commons/commonError.jsp




/myApp/myResult1.jsp








Assuming that MyAction1 and MyAction2 are someway related, they are grouped under a package called MyPackage1. All the declaration of Interceptors, Results and Exceptions within the Package MyPackage1 will be availabe only within the actions MyAction1 and MyAction2. Similarly all the definition of the Interceptors, Results and Exceptions within the package MyPackage2 will be applicable only for MyAction3 and MyAction4 action elements. Packages can also be extended through the means of extends attribute like the following,
Struts.xml

...

...

...


Let us define what a Package Extension is and their advantages. Assume that there is a Package called P1 with interceptors I1 and I2, Results R1 and R2 and Exceptions E1 and E2. If we say some Package called P2 extends P1, then all the elements that are available in P1 becomes visible to Package P2. Package Extension is very similar to Class Inheritance which we normally see in any kind of Object Oriented Language.
4.3) Interceptors and Stack
As previously discussed, Custom Interceptors can be written and made immediately available in Application by configuring them in the Configuration File with the help of tag. An Interceptor defined can be applied to a particlur Action (or a set of Actions) through the help of tag. Following Xml snippet will show this,
Struts.xml




class="myinterceptors.LoggingInterceptor">




/myApp/Result1.jsp






The above code defines an Interceptor called logger-interceptor identified by the class myinterceptors.LoggingInterceptor and the same is included for an action called MyAction with the help of tag. It is very common that a Set of Interceptors (often called Interceptor Stack) to be applied as a whole for one or more actions. Such a piece of functionality can be easily achieved with the help of element.
struts.xml




































The above Xml snippet defines a series of interceptors with the help of tag. Related Set of Interceptors to be added to an action element is then categorized with the help of element. The categorized Interceptor Stack is then bound to an action element using the same sensible tag. The framework is sensible here, it will find out the value for the name attribute. If the value is an interceptor name, then the corresponding intercept() method will be invoked, else if the value is an Interceptor-Stack, then all the interceptors within the stack are iterated in the same order as their definition and their intercept() method will be invoked.
5) Validation using Configuration Files and Annotations
Struts 2.0 comes with new set of Robust Validation Features. Most of the common Validation Activities related to a Web Application are taken care by the Framework itself which means that only less burden lies on the shoulders of a Developer. Following lists the most commonly used Validations in Struts 2.0,
Integer Validation - Checks whether the value for a field is an integer and it falls within the integer range.
Double Validation - Checks whether the value for a field is a double and it falls within the double range.
Date Validation - Checks whether the value of the field is a Date value.
Email Validation - Validates whether the input string is in appropriate email format (Eg: userName@someDomain.com).
Url Validation - Ensures whether the value for a field is in appropriate URL Format.
Required Validation - Checks for the emptiness of a field value.
Required String Validation - Checks for the emptiness of a trimmed String value (not null)
String Length Validation - Checks whether the given field value is of the specified length.
Regex Validation - Ensures whether the field Value given matches the Regular Expression.
5.1) Validations Types based on Scope
Validation comes in two different flavors based on its Scope. A Scope defines whether a Validation is dedicated to a Single Field in a Page or it corresponds to a particular Action which may involve more than one fields along with some other constraints. Based on this, the following types are available.
Field Validation
Non-Field Validation
5.1.1) Field Validation
Validating a Field in a Page for correctness is a common situation for almost any Web Application. As mentioned this type of Validation is restricted to a particular field. Common cases may be validating the username and password field for emptiness. Both Xml-Based Validation or Annotation-Based Validation can be mentioned for the field elements. The following snippet code is an example of Field-Level Validation.
validation.xml


User name cannot be empty.





Email Address cannot be empty.



Enter the email id in proper format (eg: abc.def@xyz.com)




The above Xml snippet essentially applies one Validation Rule to the username field and two Validation Rules to the email-address field. The type of the validation rule is specified by the attribute called type. In our case, the types represent the Required Validation (required) and the EMail Validation (email). Any number of validation rules can be attached to a field element with the help of tag.
Annotation-Based Validation for a field is also possible. The only requirement for the class is that the class that contains the fields representing the page (it can be an Action class too) must be marked with the @Validation annotation. Assume the Validation has to take place when the user submits the form. It is known that the Action.execute() method will be invoked as a result of this. So we can perform the field validations by marking the necessary Annotations against the method.
MyAction.java
package myactions;
import com.opensymphony.xwork2.validator.annotations.*;

@Validation
public class MyAction{

@Validations(
emails = {
@EmailValidator(type = ValidatorType.SIMPLE,
fieldName = "email_address",
message = "Enter the email id in proper format (eg: abc.def@xyz.com)")
}

requiredFields = {
@RequiredFieldValidator(type = ValidatorType.SIMPLE,
fieldName = "email_address",
message = "Email Address cannot be empty.")},

@RequiredFieldValidator(type = ValidatorType.SIMPLE,
fieldName = "username",
message = "User name cannot be empty.")}
}
)
public String execute(){
// Other Logic goes here..
}

}

Instead of marking the whole Bunch of Validations on the Action.execute method(), there is another alternate way wherein which the Annotation-Based Validation can be applied on a Field-by-Field basis. Assume that username and password are the two properties inside the Action class, then the following type of Annotation is also possible.
MyAction.java
package myactions;
import com.opensymphony.xwork2.validator.annotations.*;
public class MyAction{
private String username;
private String emailAddress;

@RequiredFieldValidator(type = ValidatorType.SIMPLE,
fieldName = "username",
message = "User name cannot be empty.")
public String getUsername(){
return username;
}

...

@RequiredFieldValidator(type = ValidatorType.SIMPLE,
fieldName = "email_address",
message = "Email Address cannot be empty.")
@EmailValidator(type = ValidatorType.SIMPLE,
fieldName = "email_address",
message = "Enter the email id in app. format(eg: abc.def@xyz.com)")
public String getEmailAddress(){
return emailAddress;
}
}

5.1.2) Non-Field Validation
Non-Field Validations are generally Application specific and they will be given implementation by the Application Developers. Example may be performing validations based one or more fields in a form along with some Application specific Business Logic. The only availabe Validation that comes along with Struts 2.0 in this category is the Expression Validation. Assume that in some Application an Employee is asked to enter his Dirth of Birth and the Joining Date. For sure, the Birth Date will be logically lesser than the Joining Date. We can enforce this kind of Validation Rule using Expression Validation as follows.
validation.xml







date_of_birth lt joining_date


Warning: DOB(${date_of_birth}) is greater than Joining Date(${joining_date})



The first noticeable thing in the above Xml snippet is that the type of the Validation is identified as expression. The param tag is used to specify the constraint to be applied for the Validation. Here the constraint is very simple which tells that the Date of Birth for an Employee must be lesser that his Joining Date in the Organisation. Also notice, how actually the value of the field is taken to display error messages ($field_name). If the user enters 10/10/2000 for the DOB field and 10/10/1960 in the Joining Date Field, then the message "Warning: DOB(10/10/2000) is greater than the Joining Date(10/10/1960)" will be flashed in the User Browser.
5.2) Validation Types based on Implementation
If we look at another angle based on how Validations are Configured or Implemented, they can be classified into two categories namely,
Declarative Validation
Programmtic Validation.
5.2.1) Declarative Validation
If the Validation Logic for a particular Field or for an Entire Action is specified either in the Xml File or through Annotations, then it is called Declarative Validation. Whatever Validation we are seeing till now are Declarative Validations only. The idea behind Declarative Validation is that during the Deployment time of the Web Application itself, the Framework or the Container will be in a suitable position to map the set of fields participating in Validations against their Validation Rules.
5.2.2) Programmatic Validation
Not at all times, the Built-in Validations provided by the Framework will be sufficient. At times, there will be a situation to perform a Complex Validation Logic that is very specific to an application. For example situation may occur wherein, a single value of a field can be validated based on the content of some other text-fields along with some values fetched from the Database. In such a case, we can implement the Validation Logic directly into the Code. The following code snippet shows that,
MyAction.java
package myactions;
import com.opensymphony.xwork2.*;
public class MyAction extends ActionSupport{

public void validate(){
String stockSymbol = getStockFieldValue();

if ((stockSymbol == null) (stockSymbol.trim().length == 0) ){
addFieldError("stock_field", "Stock Symbol cannot be empty");
}

boolean result = validateStockSymbolFromDb(stockSymbol);
if (!result){
addActionError("Invalid Stock Symbol");
}
// Other Code goes here.
}
}

If an Application is going to provide Manual Validation, then it has to implement two interfaces namely Validateable and ValidationAware interfaces in the com.opensymphony.xwork2 package. The core logic for the Custom Validation must be done within the Validateable.validate() method. ValidationAware Interface is used to collect the Error Messages that are related to fields or to a general Action. Fortunately, as expected, Struts 2.0 provides Default Implementation for both these interfaces in the ActionSupport class. So it is wise to extend this class for performing any Validation Logic without redefining every methods available in the Validation Interfaces.
Our sample Action class extends ActionSupport class to get all the Basic functionality for Storing and Retrieving Error Messages. Two types of Error Messages are available in the ValidationAware interface. One is the Field-level Messages and the other thing is the Action-Level Messages. Convinient methods are available for populating and retreiving both these messages. Methods addActionError(String message) and addFieldMessage(String fieldName, String message) are used to populate the error messages to an internal Collection. To retrive the Error Messages getActionErrors() and getFieldErrors() are used. To check whether errors have occured in a page use hasActionErrors() and hasFieldErrors() methods.
The sample code essentially checks the value of the stock symbol obtained from the field and checks for its emptiness. If not, it is populating the field-level error message by calling the addFieldMessage("..."). It then make Database Calls to ensure whether the Stock Symbol is valid. If not, an Action Level Error message is populated in the code by calling addActionEror("...");
6) Conclusion
Though Struts 2.0 has more new features to its credit, this article just provides only the basic piece of information. It walked-through about how Struts 2.0 fits into the Bigger MVC2 Architecture. Then the Flow of the Client Request into the Struts Framework is explained in detail. Following that, some samples regarding the structure of a Struts Configuration File. Then the second section primarily focusses on the new Struts Validation Features with the various types of Validations that can be performed on field components.