Struts2 is not an escalation of struts1, but a lineage of inherited webwork, which absorbs the advantages of struts1 and webwork.
first look at struts ' action official note (struts1.3.8 source code)
/**
* <p>an <strong>Action</strong> is an adapter between the contents of
* Incoming HTTP request and the corresponding business logic that should to be
* Executed to process this request. The controller (requestprocessor) would
* Select an appropriate Action for each request, create a instance (if
* necessary), and call the <code>execute</code> method.</p>
*
* <p>actions must is programmed in a thread-safe manner, because the
* Controller'll share the same instance for multiple simultaneous requests.
* This means your should design with the following items in mind: </p>
*
* <ul>
*
* <li>instance and static variables must is used to store information
* Related to the state of a particular request. They May is used to share
* Global resources across requests for the same action.</li>
*
* <li>access to other resources (JavaBeans, session variables, etc.) Must be
* Synchronized if those resources require protection. (Generally, however,
* Resource classes should is designed to provide their the own where
* necessary.</li>
*
* </ul>
*
* <p>when A <code>Action</code> instance is the created, the controller
* 'll call <code>setServlet</code> with a non-null argument to identify the
* Servlet instance to which this Action is attached. When the ' servlet is ' to
* is shut down (or restarted), the <code>setServlet</code> method would be
* Called with a <code>null</code> argument, which can is used to the
* Allocated-action.</p>
*
* @version $Rev: 471754 $ $Date: 2005-08-26 21:58:39-0400 (Fri, Aug 2005)
* $
*/
public class Action {
Code omitted ....
}
and look at the Struts2 Action Note (struts2.3.1.2)
Package COM.OPENSYMPHONY.XWORK2;
/**
* All actions <b>may</b> implement this interface, which exposes <code>execute () </code> Metho D.
* <p/>
* However, as of Xwork 1.1, this is <b>not</b> required and are only in to assist users. are free to create POJOs
* That honor the same contract defined by this interface without actually implementing the interface.
*/
Public interface Action {
/**
* The action execution was successful. Show result
* View to the end user.
*/
public static final String SUCCESS = "SUCCESS";
/**
* The action execution was successful but does not
* Show a view. This is useful the for actions that are
* Handling the view in another fashion like redirect.
*/
The public static final String none = "None";
/**
* The action execution was a failure.
* Show an error view, possibly asking the
* User to retry entering data.
*/
public static final String error = "Error";
/**
* The action execution require more input
& nbsp * In order to succeed.
* This is typically used if a form
* Handling action has been executed so as
* to provide defaults for a form. The
* form associated with the handler should is
* shown to the End user.
* <p/>
* This is also used if the given input
* Params are invalid, meaning the user
* should try providing input Again.
*/
public static final String input = "input";
/**
* The action could not execute, since the
* User most wasn't logged in. The login view
* should be shown.
*/
public static final String login = "Login";
/**
* Where The logic of the action is executed.
*
* @return A String representing the logical result of the execution.
* Constants in this interface for a list of standard result values.
* @throws Exception thrown if a system level Exception occurs.
* <b>Note:</b> Application level Exceptions should is handled by returning
* An error value, such as <code>action.error</code>.
*/
Public String Execute () throws Exception;
}
the difference and contrast between Struts1 and Struts2:
Action class:
STRUTS1 requires the action class to inherit an abstract base class. A common problem with Struts1 is programming with abstract classes rather than interfaces, while STRUTS2 action is an interface.
The Struts 2 action class can implement an action interface or implement other interfaces to make optional and custom services possible. STRUTS2 provides a actionsupport base class to implement commonly used interfaces. The action interface is not required, and any Pojo object that has an execute identity can be used as a Struts2 action object.
Threading Mode:
The struts1 action is a singleton pattern and must be thread-safe because only one instance of the action handles all requests. A single example strategy limits what Struts1 action can do, and is particularly cautious when developing. The action resource must be thread safe or synchronized.
The struts2 Action object produces an instance of each request, so there is no thread-safe issue. (In fact, the servlet container produces many disposable objects for each request, and does not cause performance and garbage collection issues)
Servlet dependencies:
The struts1 action relies on the servlet API because when an Action is invoked HttpServletRequest and HttpServletResponse are passed to the Execute method.
The Struts 2 action does not depend on the container, allowing the action detach container to be tested individually. If necessary, the STRUTS2 action can still access the initial request and response. However, other elements reduce or eliminate the need for direct access to Httpservetrequest and HttpServletResponse.
Testability:
• A major problem with testing the STRUTS1 action is that the Execute method exposes the servlet API (which makes testing dependent on the container). A third-party extension--struts testcase--provides a set of Struts1 mock objects (for testing).
Struts 2 action can be tested by initializing, setting properties, calling methods, and "Dependency injection" support also makes testing easier.
Capture Input:
Struts1 uses the Actionform object to capture the input. All Actionform must inherit a base class. Because other JavaBean cannot be used as actionform, developers often create redundant class capture inputs. Dynamic Beans (Dynabeans) can be used as a choice to create a traditional actionform, but a developer may be recreating (creating) an already existing javabean (still causing a redundant javabean).
Struts 2 eliminates the need for a second input object by using the action attribute directly as an input property. The input property may be a rich object type with its own (child) attribute. The action attribute can be accessed through taglibs on a Web page. STRUTS2 also supports Actionform mode. Rich object types, including business objects, that can be used as input/output objects. This modeldriven feature simplifies taglib references to pojo input objects.
Expression language:
Struts1 integrates Jstl, so use Jstl EL. This El has a basic object graph traversal, but the support for collections and indexed properties is weak.
Struts2 can use Jstl, but it also supports a more powerful and flexible expression language-"Object Graph notation Language" (OGNL).
Bound value to page (view):
Struts 1 uses the standard JSP mechanism to bind objects to the page to access them.
Struts 2 uses the "Valuestack" technique to enable taglib to access values without having to bind your page (view) to the object. The Valuestack policy allows pages (view) to be reused through a series of properties with the same name but different types.
Type conversions:
Struts 1 Actionform properties are usually string types. Struts1 uses commons-beanutils for type conversions. Each class has a converter that is not configurable for each instance.
Struts2 uses OGNL for type conversions. A converter that provides basic and commonly used objects.
Check:
struts 1 supports manual checksums in the Actionform validate method, or is validated by Commons validator extension. The same class can have different checksum content, but cannot validate child objects.
STRUTS2 supports validation through the Validate method and the Xwork checksum framework. The Xwork validation Framework supports chain checksum properties using the checksum content checksum defined for the attribute class type
Control performed by Action:
Struts1 supports each module with a separate request processors (lifecycle), but all the action in the module must share the same life cycle.
Struts2 supports creating different lifecycles for each action through the Interceptor Stack (Interceptor Stacks). The stack can be used in conjunction with different action as needed.
The first version of the introduction struts was released in May 2001. It was originally conceived to be a clear separation of the view and business/application logic of Web applications by combining JSP and servlet. Before struts, the most common practice is to include business and application logic in the JSP, or to generate views in a servlet through println ().
Since the release of the first edition, Struts has actually become an industry-recognized Web application standard. Its popularity has also brought improvements and changes to its own, so it will not only keep up with the changing needs of the Web application framework, but also with the characteristics of a growing number of competing frameworks. In the end, several next-generation struts solutions are produced. Among the two most watched programs are shale and struts Ti.
Shale is a component-based framework and has recently become a top-level project for Apache. And Struts Ti is based on the successful experience of struts continue to adhere to the front-end controller (Front Controller) and MVC (Model-view-controller) mode to improve. The WebWork project, released in March 2002, revolutionized the struts framework by introducing new ideas, concepts, and features, but not compatible with the original struts code. WebWork is a mature framework that has undergone several major improvements and releases. In December 2005, WebWork and Struts TI announced the merger. At the same time, struts TI was renamed the Struts Action Framework 2.0 to become the true successor of struts. Finally, it's not that struts or webwork projects have stopped developing. Since interest in these two projects is still high, and many developers are still willing to use them, the two projects continue to be developed, continue to fix bugs, improve functionality, and continue to add new features.
Second, the difference of action for friends with rich struts1.x development experience, it is clear that action is the core of the entire struts framework, of course, STRUTS2 is no exception. However, struts1.x differs greatly from the STRUTS2 action model. The difference between Struts2 and struts1.x, the most obvious is that STRUTS2 is a PULL-MVC structure.
What do you mean by that? From a developer's point of view, the data that needs to be displayed to the user can be obtained directly from the action, unlike struts1.x, which has to be stored in page, request, or session to get the appropriate bean. struts1.x must inherit org.apache.struts.action.Action or its subclasses, and the form data is encapsulated in Formbean.
Struts 2 does not need to inherit any type or implement any interface, the form data is contained in the action, obtained by Getter and setter (as in the following ACTIONFORSTRUTS2 code example). Although theoretically Struts2 action does not need to implement any interfaces or inherit any of the classes, in the actual programming process, in order to more easily implement the action, In most cases, the Com.opensymphony.xwork2.ActionSupport class is inherited and the string execute () method in this class is overloaded (Override).
First, as you can see from the ActionForStruts2, the object returned is not Actionforward, but string. If you don't like to appear in your code as a string, there's a helper interface action that provides a constant way to provide common results, such as "success", "None", "Error," "Input," and "Login."
In addition, by convention, only the "execute" method can invoke the action in struts1.x, but it is not necessary in Struts2, and any declared as a public String methodname () method can be configured to invoke the action.
Finally, the most revolutionary difference with struts1.x is that the method invoked during the STRUTS2 process (the "execute" method) is not parametric.
So how do you get the objects you need? The answer is to use the IOC (reverse control, inversion of controls), also known as the "Dependency injection (Dependency injection)" model (for more information, see Martin Fowler's article http:// www.martinfowler.com/articles/injection.html). The spring framework has made this pattern popular, but Struts2 's predecessor (WebWork) has also applied this pattern.
Third, IOCIOC (inversion of Control, translated below), is becoming more and more familiar with the popularization of lightweight containers (lightweight Contianer) in the Java community. It is no longer necessary to explain "what is control reversal" and "why control reversal". Because there are so many articles on the Internet that have a wonderful and accurate answer to such questions.
Readers can read "Development of" by Rod Johnson and Juergen Hoeller, Expert one-on-one Java EE without Fowler EJB or Martin inversion. Control containers and the "Dependency injection pattern". As we all know, STRUTS2 is developed on the basis of WebWork 2. The webwork version of WebWork 2.2, which has its own set of control reversal implementations, WebWork 2.2, in the context of the spring framework's booming development, decided to abandon the development of the control reversal function and turn it into a spring implementation.
It is worth mentioning that spring is indeed a learning framework, as more and more open source components, such as Ibatis, are abandoning the development of overlapping features with spring. Therefore, STRUTS2 recommends that you implement control inversion through spring.
To better understand inversion control, let's look at an example of how IOC can access the current request Httpserverrequest object during the action process. In the example, the dependency injection mechanism used is interface injection. Like its name, interface injection requires an interface that has already been implemented.
This interface contains the setter of the corresponding property, providing a value for the action.
The Servletrequestaware interface is used in the example, as follows:
Public interface Servletrequestaware {public void setservletrequest (HttpServletRequest request);}
Once the interface is inherited, the simple action may seem a bit complicated, but then you can get the Httpserverrequest object to use.
public class IoCForStruts2 implements Servletrequestaware {
private HttpServletRequest request;
public void Setservletrequest (HttpServletRequest request) {
This.request = Request; }
Public String Execute () throws Exception {
You can start working with the Request object
return action.success; }
}
It looks like these properties are class-level, not thread-safe, and there are problems.
In fact, there is no problem with Struts2, because each request comes with a new instance of the action object, it does not share an object with other requests, so there is no need to consider thread safety issues.
Interceptor Interceptor (The Interceptor) is used in AOP (aspect-oriented programming) to intercept a method or field before it is accessed, and then to add some action before or after.
Interception is an implementation strategy for AOP. The Chinese document in WebWork is interpreted as-the interceptor is the object that dynamically intercepts the action call. It provides a mechanism for developers to define code that executes before and after an action is executed, or to block execution of an action before it is executed. It also provides a way to extract the reusable parts of the action. Struts1.x's standard framework does not provide any form of interceptor, although an add-on project called Saif implements such a function, but its scope is limited.
Interceptors are a powerful tool for Struts2, and many functions (feature) are built on top of it, such as internationalization, converters, checksums, and so on. When it comes to interceptors, there is also a popular word-the Interceptor chain (Interceptor Chain, called the Interceptor Stack interceptor stack in Struts2).
The Interceptor chain is a chain that connects the interceptor in a certain order. When you access an intercepted method or field, the interceptor in the interceptor chain is invoked in the order in which it was previously defined.
The interceptors for Struts 2 are relatively simple to implement. When the request arrives at Struts2 's servletdispatcher, struts 2 looks for the configuration file and instantiates the relative interceptor object based on its configuration, then strings it into a list (list), and finally invokes the interceptor in the list, struts 2 has provided a variety of full-featured interceptor implementations.
Readers can view the configuration of the default interceptor and interceptor chains to the struts-default.xml of the Struts2-all-2.0.6.jar or Struts2-core-2.0.6.jar package. As a "framework", scalability is indispensable because there is no universal thing in the world.
Although Struts 2 provides us with such a rich interceptor implementation, it does not mean that we lose the ability to create custom interceptors, but on the contrary, it is quite easy to customize interceptors in Struts 2.
The origins of Struts2 are briefly described, and the differences between STRUTS2 and struts1.x are detailed, and readers should have a better understanding of the basics of Struts2-including the high-level framework concept and the underlying request process, and understand the difference in action between struts1.x and Struts2, STRUTS2 has strengthened support for interceptors and IOC, and in struts1.x these features are hard to imagine.
At the same time, readers should understand that STRUTS2 is a webwork upgrade, not a struts 1.x upgrade. Although Struts 2 provides compatibility with struts1.x, it is no longer a struts1.x upgrade. For developers who already have struts1.x development experience, the development experience of struts1.x is not very helpful to Struts2, on the contrary, for developers who already have webwork development experience, webwork development experience will be very Good reference meaning.