This annotation can be used for custom validators. Use the ValidationParameter annotation to supply additional params.
@CustomValidator(type ="customValidatorName", fieldName = "myField")
This annotation sets the KeyProperty for type conversion. The KeyProperty annotation must be applied at field or method level.
@KeyProperty( value = "userName" )
protected List<User> users = null;
When you reference a message element by its key, Struts framework searches for a corresponding message bundle in the following order −
This annotation sets the Key for type conversion. The Key annotation must be applied at field or method level.
@Key( value = java.lang.Long.class )
private Map<Long, User> userMap;
StrutsTypeConverter class tells Struts how to convert Environment to a String and vice versa by overriding two methods convertFromString() and convertToString().
Following is the life cycle of a request in Struct2 application −
This is where you map your ActionForm subclass to a name. You use this name as an alias for your ActionForm throughout the rest of the struts-config.xml file, and even on your JSP pages.
At Struts's core, we have the validation framework that assists the application to run the rules to perform validation before the action method is executed. Action class should extend the ActionSupport class, in order to get the validate method executed.
The dispatcher result type is the default type, and is used if no other result type is specified. It's used to forward to a servlet, JSP, HTML page, and so on, on the server. It uses the RequestDispatcher.forward() method.
Struts2 provides a lot of custom tags that we can use in result pages to create views for client request. These tags are broadly divided into three categories- Data tags, Control tags and UI tags.
We can use these tags by adding these in JSP pages using taglib directive.
< %@ taglib uri="/struts-tags" prefix="s" % >>
This validation annotation checks that a String field is not empty (i.e. non-null with a length > 0).
public class Employee extends ActionSupport{
@RequiredStringValidator(message = "Default message",
key = "i18n.key", shortCircuit = true, trim = true)
public String getName() {
return name;
}
}
Struts2 action classes doesn’t provide direct access to Servlet API components such as Request, Response and Session. However sometimes we need these access in action classes such as checking HTTP method or setting cookies in response.
That's why Struts2 API provides a bunch of *Aware interfaces that we can implement to access these objects. Struts2 API uses dependency injection to inject Servlet API components in action classes. Some of the important Aware interfaces are SessionAware, ApplicationAware, ServletRequestAware and ServletResponseAware.
A @Results annotation is a collection of results. Under the @Results annotation, we can have multiple @Result annotations.
@Results({
@Result(name="success", value="/success.jsp"),
@Result(name="error", value="/error.jsp")
})
public class Employee extends ActionSupport{
...
}
The fileUplaod interceptor uses several default error message keys −
struts.messages.error.uploading − A general error that occurs when the file could not be uploaded.
struts.messages.error.file.too.large − Occurs when the uploaded file is too large as specified by maximumSize.
struts.messages.error.content.type.not.allowed − Occurs when the uploaded file does not match the expected content types specified.
The @result annotations have the name that correspond to the outcome of the execute method. They also contain a location as to which view should be served corresponding to return value from execute().
@Result(name="success", value="/success.jsp")
public class Employee extends ActionSupport{
...
}
Default result type is dispatcher, which is used to dispatch to JSP pages.
his validation annotation checks that a double field has a value within a specified range. If neither min nor max is set, nothing will be done.
public class Employee extends ActionSupport{
@DoubleRangeFieldValidator(message = "Default message",
key = "i18n.key", shortCircuit = true,
minInclusive = "0.123", maxInclusive = "99.987")
public String getIncome() {
return income;
}
}
Some of the best practices while developing Struts2 application are:
Struts 2 comes with three built-in themes −
simple theme − A minimal theme with no "bells and whistles". For example, the textfield tag renders the HTML <input/> tag without a label, validation, error reporting, or any other formatting or functionality.
xhtml theme − This is the default theme used by Struts 2 and provides all the basics that the simple theme provides and adds several features like standard two-column table layout for the HTML, Labels for each of the HTML, Validation and error reporting etc.
css_xhtml theme − This theme provides all the basics that the simple theme provides and adds several features like standard two-column CSS-based layout, using <div> for the HTML Struts Tags, Labels for each of the HTML Struts Tags, placed according to the CSS stylesheet.
Struts2 is popular and mature web application framework based on the MVC design pattern. Struts2 is not just the next version of Struts 1, but it is a complete rewrite of the Struts architecture.
com.opensymphony.xwork2.interceptor.I18nInterceptor interceptor is responsible for i18n support in Struts2 applications. This interceptor is configured in struts-default package with name “i18n” and it’s part of i18nStack and defaultStack.
We can implement Action interface to create our action classes. This interface has a single method execute() that we need to implement. The only benefit of using this interface is that it contains some constants that we can use for result pages, these constants are SUCCESS, ERROR, NONE, INPUT and LOGIN.
ActionSupport class is the default implementation of Action interface and it also implements interfaces related to Validation and i18n support. ActionSupport class implements Action, Validateable, ValidationAware, TextProvider and LocaleProvider interfaces. We can override validate() method of ActionSupport class to include field level validation login in our action classes.
Depending on the requirements, we can use any of the approaches to create struts 2 action classes, my favorite is ActionSupport class because it helps in writing validation and i18n logic easily in action classes.
The @Before annotation marks a action method that needs to be called before the main action method and the result was executed. Return value is ignored.
public class Employee extends ActionSupport{
@Before
public void isAuthorized() throws AuthenticationException {
// authorize request, throw exception if failed
}
public String execute() {
// perform secure action
return SUCCESS;
}
}
The value stack is a set of several objects which keeps the following objects in the provided order −
Temporary Objects − There are various temporary objects which are created during execution of a page. For example the current iteration value for a collection being looped over in a JSP tag.
The Model Object − If you are using model objects in your struts application, the current model object is placed before the action on the value stack.
The Action Object − This will be the current action object which is being executed.
Named Objects − These objects include #application, #session, #request, #attr and #parameters and refer to the corresponding servlet scopes.
We define action tags corresponds to every URL we want to access and we define a class with execute() method which will be accessed whenever we will access corresponding URL.
Results determine what gets returned to the browser after an action is executed. The string returned from the action should be the name of a result. Results are configured per-action as above, or as a "global" result, available to every action in a package. Results have optional name and type attributes. The default name value is "success".
This configuration file provides a mechanism to change the default behavior of the framework. Actually all of the properties contained within the struts.properties configuration file can also be configured in the web.xml using the init-param, as well using the constant tag in the struts.xml configuration file. But if you like to keep the things separate and more struts specific then you can create this file under the folder WEB-INF/classes. The values configured in this file will override the default values configured in default.properties which is contained in the struts2-core-x.y.z.jar distribution.
The default URI suffix for Struts2 action is .action, in Struts1 default suffix was .do. We can change this suffix by defining struts.action.extension constant value in our Struts2 configuration file as:
< constant name="struts.action.extension" value="action,do" > < /constant >
The @BeforeResult annotation marks a action method that needs to be executed before the result. Return value is ignored.
public class Employee extends ActionSupport{
@BeforeResult
public void isValid() throws ValidationException {
// validate model object, throw exception if failed
}
public String execute() {
// perform action
return SUCCESS;
}
}
Interceptor interface defines three methods – init(), destroy() and intercept(). init and destroy are the life cycle methods of an interceptor. Interceptors are Singleton classes and Struts2 initialize a new thread to handle each request. init() method is called when interceptor instance is created and we can initialize any resources in this method. destroy() method is called when application is shutting down and we can release any resources in this method.
An interceptor stack helps us to group together multiple interceptors in a package for further use. struts-default package creates some of the mostly used interceptor stack – basicStack and defaultStack. We can create our own interceptor stack at the start of the package and then configure our action classes to use it.
Struts2 provides localization ie. internationalization (i18n) support through resource bundles, interceptors and tag libraries in the following places −
The struts.xml file contains the configuration information that you will be modifying as actions are developed. This file can be used to override default settings for an application, for example struts.devMode = false and other settings which are defined in property file. This file can be created under the folder WEB-INF/classes.
Struts2 support OGNL expression language and it performs two important tasks in Struts 2 – data trfer and type conversion.
OGNL is flexible and we can easily extend it to create our own custom converter class. Creating and configuring custom type converter class is very easy, first step is to fix the input format for the custom class. Second step is to implement the converter class. Type converter classes should implement com.opensymphony.xwork2.conversion.TypeConverter interface. Since in web application, we always get the request in form of String and send response in the form of String, Struts 2 API provides a default implementation of TypeConverter interface, StrutsTypeConverter. StrutsTypeConverter contains two abstract methods – convertFromString to convert String to Object and convertToString to convert Object to String.
This annotation sets the Element for type conversion. The Element annotation must be applied at field or method level.
@Element( value = com.acme.User )
private List<User> userList;
Here are some of the great features that may force you to consider Struts2 −
POJO forms and POJO actions − Struts2 has done away with the Action Forms that were an integral part of the Struts framework. With Struts2, you can use any POJO to receive the form input. Similarly, you can now see any POJO as an Action class.
Tag support − Struts2 has improved the form tags and the new tags allow the developers to write less code.
AJAX support − Struts2 has recognised the take over by Web2.0 technologies, and has integrated AJAX support into the product by creating AJAX tags, that function very similar to the standard Struts2 tags.
Easy Integration − Integration with other frameworks like Spring, Tiles and SiteMesh is now easier with a variety of integration available with Struts2.
Template Support − Support for generating views using templates.
Plugin Support − The core Struts2 behaviour can be enhanced and augmented by the use of plugins. A number of plugins are available for Struts2.
The @After annotation marks a action method that needs to be called after the main action method and the result was executed. Return value is ignored.
public class Employee extends ActionSupport{
@After
public void isValid() throws ValidationException {
// validate model object, throw exception if failed
}
public String execute() {
// perform secure action
return SUCCESS;
}
}
The Action class manages the application's state, and the Result Type manages the view.
You can override the text of these messages in WebContent/WEB-INF/classes/messages.properties resource files.
The constant tag along with name and value attributes will be used to override any of the following properties defined in default.properties, like we just set struts.devMode property. Setting struts.devMode property allows us to see more debug messages in the log file.
The struts-config.xml configuration file is a link between the View and Model components in the Web Client.
This is a marker annotation for type conversions at Type level. The Conversion annotation must be applied at Type level.
@Conversion()
public class ConversionAction implements Action {
}
com.opensymphony.xwork2.interceptor.ParametersInterceptor interceptor is responsible for mapping request parameters to the Action class java bean properties. This interceptor is configured in struts-default package with name “params”. This interceptor is part of basicStack and defaultStack interceptors stack.
This validation annotation checks that a field is a valid e-mail address if it contains a non-empty String.
public class Employee extends ActionSupport{
@EmailValidator(message = "Default message",
key = "i18n.key", shortCircuit = true)
public String getEmail() {
return email;
}
}
Internationalization (i18n) is the process of planning and implementing products and services so that they can easily be adapted to specific local languages and cultures, a process called localization. The internationalization process is sometimes called trlation or localization enablement.
ValueStack is the storage area where the application data is stored by Struts2 for processing the client requests. The data is stored in ActionContext objects that use ThreadLocal to have values specific to the particular request thread.
Object-Graph Navigation Language (OGNL) is a powerful Expression Language that is used to manipulate data stored on the ValueStack. As you can see in architecture diagram, both interceptors and result pages can access data stored on ValueStack using OGNL.
Some of the benefits of interceptors are:
This is used to decorate the execute() method. The Action method also takes in a value which is the URL on which the action is invoked.
public class Employee extends ActionSupport{
private String name;
private int age;
@Action(value="/empinfo")
public String execute()
{
return SUCCESS;
}
}
This section maps a page on your webapp to a name. You can use this name to refer to the actual page. This avoids hardcoding URLs on your web pages.