Monday, January 29, 2007

Data Access with Spring 2

In "Struts 2 and Spring Communication" described how to make a struts application ready to use spring and how does Struts Action works in Spring. In this post, we will see how to implement spring data access.
Add: applicationContext.xml, Database-context.xml, TestDAODB2-config.xml, Manager-context.xml
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">

<beans default-autowire="autodetect">
<import resource="Database-context.xml"/>
<import resource= "TestDAODB2-context.xml"/>
<import resource= "Manager-context.xml"/>
</beans>



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

<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">

<beans default-autowire="autodetect">
<bean id="dataSource"
class= "org.springframework.jdbc.datasource.DriverManagerDataSource">

<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/>
<property name="url" value="jdbc:oracle:thin:@localhost:1521:XE" />
<property name="username" value="hr"/>
<property name="password" value="hr"/>
</beans>
TestDAODB2-context.xml
<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">

<beans default-autowire="autodetect">
<bean id="testDAODB2" class="example.dao.TestDAODB2">
<property name="dataSource">
<ref bean="dataSource"/>
</property>
<property name="baseFindSQL" value="SELECT EMAIL, LAST_NAME FROM EMPLOYEES" />
<property name="findByUserAndPasswordWhere"value=" WHERE ID = ? AND PASSWORD= ? "/>
</beans>

Note: In above configration, I am injecting SQL query in the DAO class because quries will also be managed from XML file.
TestManager-context.xml
<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">

<beans default-autowire="autodetect">
<bean id="testManagerBean" class="example.manager.TestManager">
<property name="testDAO"/>
<ref bean="testDAODB2"/>
</property>
</beans>

Create Data Access Object: The database access object uses Spring's MappingSQLQuery class to query the database. This class is a reusable query in which concrete subclass must implement the abstract mapRow(..) method to convert each row of supplied Result set into an object.
Alternatively, JdbcTemplate class can be use to query the database.
Common tasks:
* Retrieves connections from the datasource.
* Prepares statement object.
* Executes SQL CRUD operations.
* Iterates over result sets and populates the results in standard collection objects.
* Handles SQLException and translates it into a more explicit exception in the spring exception hierarchy.

TestDAODB2.java

package example.dao;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.Collection;
import java.util.ArrayList;

import org.springframework.jdbc.core.SqlParameter;
import org.springframework.jdbc.object.MappingSqlQuery;

public class TestDAODB2{

private DataSource ds;
private String baseFindSql;
private String findByUserAndPasswordWhere;
private FindByUserIDQuery findByUserIDQuery;

public Collection find(String empID, String password){

if (findByUserIDQuery == null)
findByUserIDQuery = new FindByUserIDQuery(baseFindSql +
findByUserAndPasswordWhere);
Object[] params=new Object[2];
params[0] = empID;
params[1] = password;
Collection coll = findByUserIDQuery.execute(params);
return coll;
}

protected class FindByUserIDQuery extends MappingSqlQuery{
public FindByUserIDQuery(){
super();
setDataSource(ds);
}
public FindByUserIDQuery(String sql) {
super(ds, sql);
declareParameter(new SqlParameter(Types.CHAR));
declareParameter(new SqlParameter(Types.CHAR));
compile();
}
protected Object mapRow(ResultSet rs, int rownum) throws SQLException {

ArrayList list=new ArrayList();
list.add(rs.getString("LAST_NAME"));
list.add(rs.getString("EMAIL"));
return list;
}
}

public void setFindByUserAndPasswordWhere(String findByUserAndPasswordWhere) {
this.findByUserAndPasswordWhere = findByUserAndPasswordWhere;
}

public void setBaseFindSql(String s){
baseFindSql = s;
}
public void setDataSource(DataSource datasource){
ds = datasource;
}
}

TestManager.java

package example.manager;

import example.dao.TestDAO;

import java.util.Collection;
import java.util.Iterator;

public class TestManager {

protected TestDAO testDAO;

public String userAuthentication(String empID, String empName)
{
Collection coll= testDAO.find(empID, empName);
Iterator iterator = coll.iterator();
if(iterator!=null){
return "Succesfull";
}else{
return "Failure";
}
}
public void setTestDAO(TestDAO testDAODB2) {
this.testDAO = testDAODB2;
}
}


This example is executed on Tomcat Server and used follwoing jar files.
JAR Files: In order for you to run this example, you must have the following jar files in your class path: commons-collections.jar || commons-lang.jar || commons-logging.jar || ojdbc14.jar || oro-2.0.8.jar || spring.jar || struts-core-1.3.5.jar || struts-taglib-1.3.5.jar
Learn more about how Spring interacts with database

Struts 2 and Spring Communication

The Spring plugin allows Actions, Interceptors, and Results to be created and/or autowired by Spring.

It works by overriding the Struts ObjectFactory to enhance the creation of core framework objects. When an object is to be created, it uses the class attribute in the Struts configuration to correspond to the id attribute in the Spring configuration.

Features
* Allow Actions, Interceptors, and Results to be created by Spring
* Struts-created objects can be autowired by Spring after creation
* Provides two interceptors that autowire actions, if not using the Spring ObjectFactory

USAGE
To enable Spring integration, simply include struts2-spring-plugin-x-x-x.jar in your application.


struts.properties
struts.objectFactory = springAutowiring

The framework enables "autowiring" by default. (Autowiring means to look for objects defined in Spring with the same name as your object property). To change the wiring mode, modify the spring.autowire property.
Wiring Mode
struts.objectFactory.spring.autoWire = type
Enabling Spring integration for other application objects is a two-step process.
  • Configure the Spring listener
web.xml

<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

  • Register your objects via the Spring configuration
applicationContext.xml

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

<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd" >

<beans default-autowire="autodetect">
<bean id="personManagerBean" class="com.acme.PersonManager"/>
<bean id="LoginAction" class="example.Login" singleton="false">
<property name="testManager" ref="personManagerBean"></property>
</bean>
</beans>

Initializing Actions from Spring
Normally, in struts.xml you specify the class for each Action. When using the default SpringObjectFactory, the framework will ask Spring to create the Action and wire up dependencies as specified by the default auto-wire behavior. To do this, all you have to do is configure the bean in your Spring applicationContext.xml and then change the class attribute from your Action in the struts.xml to use the bean name defined in Spring instead of the class name.
struts.xml

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

<include file="struts-default.xml"/>

<package name="default" extends="struts-default">
<action name="foo" class="com.acme.Foo">

<result>foo.ftl</result>
</action>
</package>

<package name="secure" namespace="/secure" extends="default">

<action name="Login" class="LoginAction">
<result>/jsp/HelloWorld.jsp</result>
</action>
</package>

</struts>
Where you have a Spring bean defined in your applicationContext.xml named "LoginAction". Note that the example.Login Action did not need to be changed, because it can be autowired.

References:
* Spring Plugin
* Struts 2 + Spring 2 + JPA + AJAX

Thursday, January 11, 2007

WebWork - Comparison to Struts

As of December, 2005 the Struts and WebWork teams have agreed to combine their efforts to create Struts Action 2.0. Struts Action 2.0 will be based on WebWork 2.2. Therefore this comparison is less relevant as the two communities cooperate more. But it can give you an idea what they have intorduce in Struts 2

Reference: Struts vs Webwork

Wednesday, January 10, 2007

Struts 2 Validation

Struts 2.0 relies on a validation framework provided by XWork input validation. Along with basic validation and client-side Javascript validation offered in Struts 1.x, Struts 2 offers Ajax based validation. The following example demonstrates how to use Struts 2 validation, both basic and ajax validations. For this, the sample page used is shown below.

<s:form action="RegisterUser">
<s:textfield name="userName" size="20" label="User Name" />
<s:textfield name="emailAddress" size="20" label="Email Address" />
<s:textfield name="dateOfBirth" size="20" label="Date Of Birth" />
<s:submit name="submit" value="submit" />
</s:form>

Action defination is shown below:

<action name="RegisterUser" method="registerUser" class="example.RegisterUser">
<result name="input">/example/Register.jsp</result>

Apache Struts 2 Architecture

Architecture in a Nutshell
1. The web browser requests a resource (/mypage.action, /reports/myreport.pdf, et cetera)
2. The Filter Dispatcher looks at the request and determines the appropriate Action
3. The Interceptors automatically apply common functionality to the request, like workflow, validation, and file upload handling
4. The Action method executes, usually storing and/or retrieving information from a database
5. The Result renders the output to the browser, be it HTML, images, PDF, or something else

Source of this article: http://struts.apache.org/2.x/docs/home.html

Aside from actions and results, we can specify exception handlers and interceptors.

Exception handlers declare how to handle an exception on a global or local basis. Instead of sprinking source code with try .. catch blocks, we can let the framework catch the exception and display the page of our choice. The page can display an appropriate message and details from the exception.

*
Interceptors specify the "request-processing lifecycle" for an action. (What happens to the request before and after the Action class fires.) We can specify both global and local lifecycles. If some actions respond to AJAX, SOAP, or JSF requests, we can simplify the lifecycle, and even just "pass through" the request, if needed. However, these are special cases, and most applications can use the default interceptor stack, "out of the box".
In the diagram, an initial request goes to the Servlet container (such as Jetty or Resin) which is passed through a standard filter chain. The chain includes the (optional)
ActionContextCleanUp filter, which is useful when integrating technologies such as SiteMesh Plugin. Next, the required FilterDispatcher is called, which in turn consults the ActionMapper to determine if the request should invoke an action.
If the ActionMapper determines that an Action should be invoked, the
FilterDispatcher delegates control to the ActionProxy. The ActionProxy consults the framework Configuration Files manager (initialized from the struts.xml file). Next, the ActionProxy creates an ActionInvocation, which is responsible for the command pattern implementation. This includes invoking any Interceptors (the before clause) in advance of invoking the Action itself.
Once the Action returns, the
ActionInvocation is responsible for looking up the proper result associated with the Action result code mapped in struts.xml. The result is then executed, which often (but not always, as is the case for Action Chaining) involves a template written in JSP or FreeMarker to be rendered. While rendering, the templates can use the Struts Tags provided by the framework. Some of those components will work with the ActionMapper to render proper URLs for additional requests.

All objects in this architecture (Actions, Results, Interceptors, and so forth) are created by an ObjectFactory. This ObjectFactory is pluggable. We can provide our own ObjectFactory for any reason that requires knowing when objects in the framework are created. A popular ObjectFactory implementation uses Spring as provided by the Spring Plugin

Migrating to Struts 2

A Request Walk-through

Before we start looking at the low level details of how to convert an application from Struts to Struts2, let's take a look at what the new architecture looks like by walking through the request processing.
As we walk through the request lifecycle you should notice one important fact - Struts2 is still a front controller framework. All of the concepts that you are familiar with will still apply.
This means:
· Actions will still be invoked via URL's and data is still sent to the server via the URL request parameters and form parameters
· All those Servlet objects (request, response, session, etc.) are all still available to the Action


From a high-level overview, this is how the request is processed:
1. A request is made and processed by the framework - the framework matches the request to a configuration so that the interceptors, action class and results to use are known.
2. The request passes through a series of interceptors - interceptors, and interceptor stacks, can be configured at a number of different levels for the request. They provide pre-processing for the request as well as cross-cutting application features. This is similar to the Struts RequestProcessor class which uses the Jakarta Commons Chain component.
3. The Action is invoked - a new instance of the action class is created and the method that is providing the logic for this request is invoked. We will discuss this in more detail in the second part of this series; however, in Struts2 the configuration of the action can specify the method of the action class to be invoked for this request.
4. The Result is invoked - the result class that matches the return from processing the actions' method is obtained, a new instance created and invoked. One possible outcome of the result being processed is rendering of a UI template (but not the only one) to produce HTML. If this is the case, then Struts2 tags in the template can reach back into the action to obtain values to be rendered.
5. The request returns through the Interceptors - the request passes back through the interceptors in reverse order, allowing any clean-up or additional processing to be performed.
6. The response is returned to the user - the last step is to return control back to the servlet engine. The most common outcome is that HTML is rendered to the user, but it may also be that specific HTTP headers are returned or a HTTP redirect is invoked.

As you may have noticed, there are some differences. The most obvious one is that Struts2 is a pull-MVC architecture. What does this mean? From a developers perspective it means that data that needs to be displayed to the user can be pulled from the Action. This differs from Struts, where data is expected to be present in beans in either the HTTP page, request or session scopes. There are other places that data can be pulled from, and we'll talk about those as the scenarios come up.

Configuring the framework

The first, and most important configuration, is the one that enables the web application framework within the servlet containers web.xml file.

The configuration that everyone should be familiar with for Struts is:
<servlet>
<servlet-name>action</servlet-name>
<servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
<init-param>
<param-name>config</param-name>
<param-value>/WEB-INF/struts-config.xml</param-value>
</init-param>
<load-on-startup>2</load-on-startup>
</servlet>

<servlet-mapping>
<servlet-name>action</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>

For Struts2 there are very few changes. The most significant is that the dispatcher has been changed from a servlet to a servlet filter. The configuration is just as easy as for a servlet, and shown here:
<filter>
<filter-name>webwork</filter-name>
<filter-class>
org.apache.struts.action2.dispatcher.FilterDispatcher
</filter-class>
</filter>

<filter-mapping>
<filter-name>webwork</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Similar to the servlet configuration, the filter configuration defines a name (for reference) and the class of the filter. A filter mapping links the name with the URI pattern that will invoke the filter. By default, the extension is ".action". This is defined in the default.properties file (within the Struts2 JAR file) as the "struts.action.extension" property.

SIDEBAR: The "default.properties" file is the place that many configuration options are defined. By including a file with the name "struts.properties" in the classpath of your web application, with different values for the properties, you can override the default configuration.
For Struts, the servlet configuration provides an init-param tag that defines the names of the files used to configure Struts. Struts2 does not have such a configuration parameter. Instead, the default configuration file for Struts2 has the name "struts.xml" and needs to be on the classpath of the web application.
SIDEBAR/TIP: Since there is a namespace separation between the Struts actions (with a ".do" extension) and the Struts2 actions (with a ".action") extension, there is no reason why they cannot co-exist within the same web application. This is a great way to start the migration process - add the necessary configuration, and start developing all new functionality in Struts2. As time and resources permit, the remaining actions can be converted. Or, the two frameworks can co-exist peacefully forever, since there is no reason that the existing action ever needs to be migrated. Another migration strategy is to update only the actions by changing the Struts2 extension to ".do". This allows the existing JSP's to remain the same and be re-used.

Deconstructing the Actions
In the request walk-through we spoke about some of the differences between Struts and Struts2 from a high level. Let's take it a step deeper now, and look at the differences between the structures of the actions in each framework.

Let's first review the general structure of the Struts action. The general form of the Struts action looks like this:

public class MyAction extends Action {
public ActionForward execute(ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response)
throws Exception {
// do the work
return (mapping.findForward("success"));
}
}

When implementing a Struts action, you need to be aware of the following items:
1. All actions have to extend the Action base class.
2. All actions have to be thread-safe, as only a single action instance is created.
3. Because the actions have to be thread-safe, all the objects that may be needed in the processing of the action are passed in the method signature.
4. The name of the method that is invoked for the processing of the action is "execute" (there is a DispatchAction class available in Struts which can re-route the method to be executed to another method in the same action, however the initial entry point from the framework into the action is still the "execute" method).
5. An ActionForward result is returned using a method from the ActionMapping class, most commonly via the "findForward" method call.
In contrast, the Struts2 action provides a much simpler implementation. Here's what it looks like:

public class MyAction {
public String execute() throws Exception {
// do the work
return "success";
}
}

The first thing you may have noticed is that the action doesn't extend any classes or interfaces. In fact, it goes further than this. By convention, the method invoked in the processing of an action is the "execute" method - but it doesn't have to be. Any method that follows the method signature public String methodName() can be invoked through configuration.
Next, the return object is a String. If you don't like the idea of string literals in your code, there is a helper interface Action available that provides the common results of "success", "none", "error", "input" and "login" as constants.

Finally, and perhaps the most revolutionary difference from the original Struts implementation, is that the method invoked in the processing of an action (the "execute" method) has no parameter. So how do you get access to the objects that you need to work with? The answer lies in the "inversion of control" or "dependency injection" pattern (for more information Martin Fowler has an informative article at http://www.martinfowler.com/articles/injection.html). The Spring Framework has popularized this pattern, however, the predecessor to Struts2 (WebWork) started using the pattern around the same time.

To understand the inversion of control better, let's look at an example where the processing of the action requires access to the current requests HttpServerRequest object.
The dependency injection mechanism used in this example is interface injection. As the name implies, with interface injection there is an interface that needs to be implemented. This interface contains setters, which in turn are used to provide data to the action. In our example we are using the ServletRequestAware interface, here it is:

public interface ServletRequestAware {
public void setServletRequest(HttpServletRequest request);
}
When we implement this interface, our simple action from above becomes a little more complex - but now we have a HttpServerRequest object to use.
public class MyAction implements ServletRequestAware {
private HttpServletRequest request;
public void setServletRequest(HttpServletRequest request) {
this.request = request;
}
public String execute() throws Exception {
// do the work using the request
return Action.SUCCESS;
}
}
At this point, some alarm bells are probably going off. There are now class level attributes in the action - which, although not thread-safe, is actually okay. In Struts2, an action instance is created for each request. It's not shared and it's discarded after the request has been completed.
There is one last step left, and that is to associate the ServletConfigInterceptor interceptor with this action. This interceptor provides the functionality to obtain the HttpServletRequest and inject it into actions that implement the ServletRequestAware interface. For the moment, don't worry about the details of the configuration - we'll go into much more detail in the next article. The important thing at the moment is to understand that the interceptor and the interface work hand-in-hand to provide the dependency injection to the action.

The benefit to this design is that the action is completely de-coupled from the framework. The action becomes a simple POJO that can also be used outside of the framework. And for those that encourage unit testing, testing a Struts2 action is going to be significantly easier than wrestling to get a Struts action into a StrutsTestCase or a MockStrutsTestCase unit test.
Source of this article:
http://www.infoq.com/articles/converting-struts-2-part1
http://www.infoq.com/articles/migrating-struts-2-part2

Monday, January 08, 2007

Hello Struts 2

Struts has been the most popular web application framework for the past few years. With this popularity have come enhancements and changes due not only to the changing requirements, but also to provide features available in newer frameworks. The new version Struts 2.0 is a combination of the Sturts action framework and Webwork. According to the Struts 2.0.1 release announcement, some key changes are:

  • Improved Design - All Struts 2 classes are based on interfaces. Core interfaces are HTTP independent.
  • Intelligent Defaults - Most configuration elements have a default value that we can set and forget.
  • Enhanced Results - Unlike ActionForwards, Struts 2 Results can actually help prepare the response.
  • Enhanced Tags - Struts 2 tags don't just output data, but provide stylesheet-driven markup, so that we can create consistent pages with less code.
  • First-class AJAX support - The AJAX theme gives interactive applications a significant boost.
  • Stateful Checkboxes - Struts 2 checkboxes do not require special handling for false values.
  • QuickStart - Many changes can be made on the fly without restarting a web container.
  • Easy-to-test Actions - Struts 2 Actions are HTTP independent and can be tested without resorting to mock objects.
  • Easy-to-customize controller - Struts 1 lets us customize the request processor per module, Struts 2 lets us customize the request handling per action, if desired.
  • Easy-to-tweak tags - Struts 2 tag markup can be altered by changing an underlying stylesheet. Individual tag markup can be changed by editing a FreeMarker template. No need to grok the taglib API! Both JSP and FreeMarker tags are fully supported.
  • Easy cancel handling - The Struts 2 Cancel button can go directly to a different action.
  • Easy Spring integration - Struts 2 Actions are Spring-aware. Just add Spring beans!
  • Easy plugins - Struts 2 extensions can be added by dropping in a JAR. No manual configuration required!
  • POJO forms - No more ActionForms! We can use any JavaBean we like or put properties directly on our Action classes. No need to use all String properties!
  • POJO Actions - Any class can be used as an Action class. We don't even have to implement an interface!
The following are a few resources to get started with writing Struts 2.0 applications