Pages

Monday, August 3, 2009

Struts 2 Validation Annotation

This post will show how to use Annotation based validation in Struts 2. For this example I used the add transaction part of google's portfolio manager (noticed that they do not have validations over there). Struts 2 provides a number of validators for XML based validation rules. All of them have respective annotations defined and can be used in place of XML validation rules. In the example, we will use the @RequiredStringValidator, @RegexFieldValidator and also see how to parameterize messages when using annotations.

Follow these steps to implement the example ... There's more

1. Create a dynamic web project in Eclipse.
2. Copy the following jar files into the WEB-INF/lib directory, all these files are available with sturts download.
* struts2-core-2.0.11.1.jar
* xwork-2.0.4.jar
* freemarker-2.3.8.jar
* commons-logging-1.1.1.jar
* ognl-2.6.11.jar
3. Update your web deployment desciptor to include the sturts filter dispatcher.

WEB-INF/web.xml





4. Create the input JSP : transactions.jsp





Note: The method="noValidation" indicates to struts that on submission, the noValidation() method will be invoked on the AddTransactionAction class.

5. Create the output JSP : done.jsp





6. Create the Action class :AddTransactionAction.java

package actions;

import org.apache.struts2.interceptor.validation.SkipValidation;

import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.validator.annotations.RegexFieldValidator;
import com.opensymphony.xwork2.validator.annotations.RequiredStringValidator;
import com.opensymphony.xwork2.validator.annotations.ValidatorType;
import com.opensymphony.xwork2.validator.annotations.Validation;

@Validation
public class AddTransactionAction extends ActionSupport {

private String symbol;
private String type;
private String date;
private String numberOfShares;
private String price;
private String comission;
private String notes;


public String execute() throws Exception {
System.out.println("In Execute");

return SUCCESS;
}

@SkipValidation
public String noValidation() throws Exception {
System.out.println("In Novalidation");
return SUCCESS;
}


public String getSymbol() {
return symbol;
}

@RequiredStringValidator(type = ValidatorType.FIELD, message = "Symbol Required")
public void setSymbol(String symbol) {
this.symbol = symbol;
}


public String getType() {
return type;
}

@RequiredStringValidator(type = ValidatorType.FIELD, message = "Type Required")
public void setType(String type) {
this.type = type;
}


public String getDate() {
return date;
}

@RequiredStringValidator(type = ValidatorType.FIELD, message = "Date Required")
@RegexFieldValidator(type=ValidatorType.FIELD, message="",key="date.error.message", expression = "[0-9][0-9]/[0-9][0-9]/[1-9][0-9][0-9][0-9]")
public void setDate(String date) {
this.date = date;
}


public String getNumberOfShares() {
return numberOfShares;
}


@RequiredStringValidator(type = ValidatorType.FIELD, message = " Number of Shares Required")
public void setNumberOfShares(String numberOfShares) {
this.numberOfShares = numberOfShares;
}


public String getPrice() {
return price;
}

@RequiredStringValidator(type = ValidatorType.FIELD, message = "Price Required")
public void setPrice(String price) {
this.price = price;
}


public String getComission() {
return comission;
}

@RequiredStringValidator(type = ValidatorType.FIELD, message = "Comission Required")
public void setComission(String comission) {
this.comission = comission;
}


public String getNotes() {
return notes;
}


public void setNotes(String notes) {
this.notes = notes;
}
}



Note:
* The annotation @Validation is used to indicate that the current action might need validation. The validations on a method level can be skipped using the @SkipValidation annotation on the method.
* The method noValidations() uses the @SkipValidation annotation, you can see this when you click on "Submit without validation" in the JSP
* The @RequiredStringValidator annotation is used to indicate a Required Strint similar to the following xml rule

* On the date field, I used a @RegexFieldValidator annotation, so that the date field will be mandated to have a given format.
* Parameterized messages: You will notice that the message attribute of the @RegexFieldValidator is set to an empty string, while the key is set to a value. This is due to the fact that the message attribute is mandatory, and the key attribute is used to denote the message key from the properties files. The parameters can be retrieved in the properties files using the ${date} notation where the "date" variable is expected to available in the value stack.

7. Create a definition for the action in struts.xml





Note: The result with name "input" is because the validator returns the result to input when validation fails.
8. Create the properties file for messages

date.error.message=Date ${date} is not properly formatted.

package.properties

Note: In the properties file, ${date} is used to retrieve the "date" value from the value stack, this is the way Struts 2 supports parameterization.

9. Create the struts.properties file to set the theme to simple theme, so that you have more control how the UI components are laid out.

struts.ui.theme=simple

struts.properties
Google
 

Java-Struts