Reputation: 45583
In Struts 2 we can develop @CustomValidator
which can be used in application widely:
@CustomValidator(type = "CustomerNumberValidator", fieldName = "customerNo")
For validation more than one field we use @ExpressionValidator
:
@ExpressionValidator(expression =
"( (!''.equals(account.firstName) && (!''.equals(account.lastName) )
|| (presonalAccount == false)",
key = "validate.account.name")
If the expression is too complicated and needs to work on more than one field we use OGNL to call the static
method. The static
method will do the validation and return a boolean
for example
@ExpressionValidator(expression = "@foo.bar.CalendarUtil@compareDates(fromDate,toDate)", key = "validate.date.before")
Above is something how a Custom Expression Validator works!
And we use @foo.bar.CalendarUtil@compareDates
in application wide to make this validation for us.
Is there another approach which enables us to use a custom expression validator?!
Is there any custom expression validator which can be added to Struts and we can call it in Action
in the way we use @CustomValidator
?
Upvotes: 3
Views: 1576
Reputation: 1
You can use non-field custom validator if you need to validate several fields. Non-field custom validator should extend ValidatorSupport
and implement validate
method. Then apply a custom validator in your -validation.xml
or use @CustomValidator
annotation. There you can add custom expressions as @ValidationParameter
and parse them when you doing validation.
Note:
This technique I used firstly in this answer:
public class RetypeValidator extends ValidatorSupport { private String value = null; public String getValue() { return value; } public void setValue(String value) { this.value = value; } private String retypeValue = null; public String getRetypeValue() { return retypeValue; } public void setRetypeValue(String value) { retypeValue = value; } @Override public void validate(Object object) throws ValidationException { String value = (String) parse(this.value, String.class); String retypeValue = (String) parse(this.retypeValue, String.class); if (value != null && retypeValue != null && !value.equals(retypeValue)) addActionError(getDefaultMessage()); } }
Another option is to override validate
method of the ActionSupport
class. The call to this method is controlled via validation
interceptor. This method of validation is known as programmatic and is used by default regardless of validators applied during declarative validation.
Upvotes: 1
Reputation: 50281
Create a Custom Validator (not field related):
public final class CompareDatesValidator extends ValidatorSupport {
private String fromDate; // getter and setter
private String toDate; // getter and setter
@Override
public void validate(Object o) throws ValidationException {
Date d1 = (Date)parse(fromDate, Date.class);
Date d2 = (Date)parse(toDate, Date.class);
if (d1==null || d2==null || d2.before(d1)){
addActionError(getDefaultMessage());
}
}
}
Register the custom validator in validators.xml
file:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE validators PUBLIC
"-//OpenSymphony Group//XWork Validator Config 1.0//EN"
"http://www.opensymphony.com/xwork/xwork-validator-config-1.0.dtd">
<validators>
<validator name="compareDatesValidator"
class="org.foo.bar.CompareDatesValidator"/>
</validators>
Use the validator in an action:
private Date startDate; // getter and setter
private Date endDate; // getter and setter
@Validations(
customValidators={
@CustomValidator(type="compareDatesValidator",
message="Dates provided are not valid."
parameters={
@ValidationParameter(name="fromDate", value="${startDate}"),
@ValidationParameter(name="toDate", value="${endDate}")})})
public String execute(){
return SUCCESS;
}
Upvotes: 4