Tuesday, April 10, 2012

Struts2


Introduction/ History of Struts
The first version of Struts was released in June 2001. It was born out of the idea that JSPs and servlets could be used together to provide a clean separation between the view and the business or application logic of a web application. Before Struts, the most common options were to add business and application logic to the JSP, or to render the view from servlets using println() statements. 

Since its release, Struts has become the de-facto standard for web application. With this popularity have come enhancements and changes - both to keep up with the ever-changing requirements for a web application framework, but also to match features with the ever-increasing number of competing frameworks available.

To that end, there have been several proposals for the next generation of Struts. The two alternatives that have become the most cohesive in the past year are Shale and Struts Ti. Shale is a component based framework, and just recently has become its own top-level Apache project, where Struts Ti continues the front controller or model-view-controller pattern that has made Struts so successful.

The WebWork project was started as a Struts revolution - as a fork of the Struts code to introduce new ideas, concepts and functionality that may not be compatible with the original Struts code - and it was first released in March 2002. WebWork is a mature framework, having undergone several minor and major releases.

In December 2005 it was announced that WebWork and the Struts Ti would join forces. Since that time, Struts Ti has become Struts Action Framework 2.0, and the successor to Struts.

Finally, it should be noted that neither the Struts nor WebWork projects are going away. While interest is high, and willing developers are available, both of these projects will continue - all the while having bugs fixed, and adding enhancements and new features.
What is Struts?
According to the Apache Struts project page  
"Apache Struts is a free open-source framework for creating Java web applications."
While that statement is certainly true, it belies the power and the complexity of Struts.  There are  a few adjectives I would add to this statement.
  • Powerful
  • Feature rich
  • Widely accepted
  • De-facto standard
  • Modern (in the case of Struts2)
The Apache Struts Project offers two major versions of the Struts framework. Struts 1 is recognized as the most popular web application framework for Java. The 1.x framework is mature, well-documented, and widely supported.
Struts 2 was originally known as WebWork 2 . After working independently for several years, the WebWork and Struts communities joined forces to create Struts 2. The 2.x framework is the best choice for teams who value elegant solutions to difficult problems.
What's so good about Struts2?
The bad old days
When the Servlet 1.0 API hit the scene in 1997 it was a major step forward in web application development.  Before this, most developers were doing CGI in languages like C and Perl.  Developers now had a clean API that closely followed the way HTTP works, but it still left the developer with a lot of work in terms of
You need a framework!
See Struts 1.x Vs Struts 2.x for a good rundown of Struts and a comparison between Struts 1 and Struts 2.
How do I get started?
What you need to know
The Struts2 Documentation  is referenced throughout this page.  See the key technologies primer to get up to speed.
The big picture is always a good place to start.
HTTP and the Servlet API
For the purposes of this article, I assume that you have a working knowledge of HTTP and the Servlet API but it's worth mentioning that to write good Web applications you must know HTTP and to write good Java Web applications you must know the Servlet API. A thourough understanding of HTTP helps you design web apps that take advantage of HTTP and since all Java web application frameworks are built on Servlets, it's good to understand what's going on under the hood.
In Struts2 they have implemented a ServletFilter to act as the entry point into the framework.  Struts2 applications typically configure the filter (
org.apache.struts2.dispatcher.FilterDispatcher) to wrap all requests.
OGNL
OGNL is Object Graph Navigation Language.  The STruts2 documentation describes it very well here .  OGNL is basically used within Struts to provide access to what's called the "value stack".  The value stack consists of several different objects including request parameters, attributes, session attributes, configuration etc.  OGNL allows you to access all of those objects as if they were one object.  Most of the interaction the code will have with OGNL is the use of OGNL expressions in JSP files.
Creating an Action
The requisite hello world example  shows how the Action and JSP interact in Struts2.  Action classes typically extend com.opensymphony.xwork2.ActionSupport however Actions are only required to implement the execute method. 
Key points:
  • Action classes use Java Beans style getters and setters to get data to and from the jsp/request.  Form element values are automatically set on the action.
  • Return "success" from the execute method to invoke the default result.
  • Return other values to control the flow of the application.  The framework will perform the next configured task.
  • Actions can be testable because they are POJOs.
Using Tags
Struts2 provides a comprehensive set of tags to handle form fields, links, messages, and more.  The tag developer's guide is where you can find documentation on these tags, also the tag reference  is helpful.  Here's the basics:


   
The using tags page also provides good information on tags.  One important feature of Struts2 is that all of the JSP tags delegate to Freemarker templates to render their output.  Freemarker is a templating engine from Apache.  The templates can be customized and overridden which allows you to easily change the way the tags render.
Configuring Struts2
Struts2 is generally configured via the struts.xml file on the classpath.  A basic configuration consists of action tags nested inside a package tag.  Packages can be used to logically partition an appliction into different functional areas that may or may not have unique configuration needs.   See configuration elements  in the documentation. 
   
       
            item.jsp
       
   
Constants can be set at the top of the configuration to control the overall behavior of the framework.  The most common is the "struts.devMode" constant.
   
    ...
Struts 2 Architecture
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 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:
The processing of a request can be broken into these 6 steps:
  • 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.
  • 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.
  • 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.
  • 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.
  • 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.
  • 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.
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:

        action
name>
        org.apache.struts.action.ActionServlet</servlet-class>
                      config
name>                    /WEB-INF/struts-config.xml

        
        2startup>  

        action
name>

        *.dopattern>  
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:

        webwork
name>
        org.apache.struts.action2.dispatcher.FilterDispatcherclass>   
        webwork
name>

        /* 
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.
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.
Deconstructing the Actions
Lets 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:
  • All actions have to extend the Action base class.
  • All actions have to be thread-safe, as only a single action instance is created.
  • 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.
  • 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).
  • 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. 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;    }}
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. 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.
Differences b/w Struts 1 and Struts 2
FeatureStruts 1Struts 2
Action classesStruts 1 requires Action classes to extend an abstract base class. A common problem in Struts 1 is programming to abstract classes instead of interfaces.An Struts 2 Action may implement an Action interface, along with other interfaces to enable optional and custom services. Struts 2 provides a base ActionSupport class to implement commonly used interfaces. Albeit, the Action interface is not required. Any POJO object with a execute signature can be used as an Struts 2 Action object.
Threading ModelStruts 1 Actions are singletons and must be thread-safe since there will only be one instance of a class to handle all requests for that Action. The singleton strategy places restrictions on what can be done with Struts 1 Actions and requires extra care to develop. Action resources must be thread-safe or synchronized.Struts 2 Action objects are instantiated for each request, so there are no thread-safety issues. (In practice, servlet containers generate many throw-away objects per request, and one more object does not impose a performance penalty or impact garbage collection.)
Servlet DependencyStruts 1 Actions have dependencies on the servlet API since the HttpServletRequest and HttpServletResponse is passed to the execute method when an Action is invoked.Struts 2 Actions are not coupled to a container. Most often the servlet contexts are represented as simple Maps, allowing Actions to be tested in isolation. Struts 2 Actions can still access the original request and response, if required. However, other architectural elements reduce or eliminate the need to access the HttpServetRequest or HttpServletResponse directly.
TestabilityA major hurdle to testing Struts 1 Actions is that the execute method exposes the Servlet API. A third-party extension, Struts TestCase, offers a set of mock object for Struts 1.Struts 2 Actions can be tested by instantiating the Action, setting properties, and invoking methods. Dependency Injection support also makes testing simpler.
Harvesting InputStruts 1 uses an ActionForm object to capture input. Like Actions, all ActionForms must extend a base class. Since other JavaBeans cannot be used as ActionForms, developers often create redundant classes to capture input. DynaBeans can used as an alternative to creating conventional ActionForm classes, but, here too, developers may be redescribing existing JavaBeans.Struts 2 uses Action properties as input properties, eliminating the need for a second input object. Input properties may be rich object types which may have their own properties. The Action properties can be accessed from the web page via the taglibs. Struts 2 also supports the ActionForm pattern, as well as POJO form objects and POJO Actions. Rich object types, including business or domain objects, can be used as input/output objects. The ModelDriven feature simplifies taglb references to POJO input objects.
Expression LanguageStruts 1 integrates with JSTL, so it uses the JSTL EL. The EL has basic object graph traversal, but relatively weak collection and indexed property support.Struts 2 can use JSTL, but the framework also supports a more powerful and flexible expression language called "Object Graph Notation Language" (OGNL).
Binding values into viewsStruts 1 uses the standard JSP mechanism for binding objects into the page context for access.Struts 2 uses a "ValueStack" technology so that the taglibs can access values without coupling your view to the object type it is rendering. The ValueStack strategy allows reuse of views across a range of types which may have the same property name but different property types.
Type ConversionStruts 1 ActionForm properties are usually all Strings. Struts 1 uses Commons-Beanutils for type conversion. Converters are per-class, and not configurable per instance.Struts 2 uses OGNL for type conversion. The framework includes converters for basic and common object types and primitives.
ValidationStruts 1 supports manual validation via a validate method on the ActionForm, or through an extension to the Commons Validator. Classes can have different validation contexts for the same class, but cannot chain to validations on sub-objects.Struts 2 supports manual validation via the validate method and the XWork Validation framework. The Xwork Validation Framework supports chaining validation into sub-properties using the validations defined for the properties class type and the validation context.
Control Of Action ExecutionStruts 1 supports separate Request Processors (lifecycles) for each module, but all the Actions in the module must share the same lifecycle.Struts 2 supports creating different lifecycles on a per Action basis via Interceptor Stacks. Custom stacks can be created and used with different Actions, as needed.

123passportphoto is a very easy to use passport photo website that provides six enhanced photos. I have never had an issue while using this ...