Skip to content

Custom validators in SEAM

January 28, 2011

I suppose all of you know that you can use static hibernate validators in SEAM, like this:

@NotNull(message = "Credit card name is required")
@Length(min = 3, max = 70, message = "Credit card name is required")
public String getCreditCardName() {
		return creditCardName;
}

But the question is how can I define my custom Validator?

There are two ways to do that: one to use like the annotation above and the second one to use directly from you JSF.

1. Custom validators to be used with annotations.

In order your annotation to be recognized, you have to define an interface for it.

@ValidatorClass(CNPValidatorImpl.class)
@Target( { ElementType.FIELD, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
public @interface CNPValidator {
String message() default "cnp incorrect";
}

Now you have to implement this interface:

package validators;

import org.hibernate.validator.Validator;
import org.jboss.seam.annotations.Name;

public class CNPValidatorImpl implements Validator<CNPValidator> {

 private boolean isValid = false;

 @Override
 public void initialize(CNPValidator arg0) {
 // TODO Auto-generated method stub

 }

 @Override
 public boolean isValid(Object arg0) {
 if (String.valueOf(arg0).length() == 13)
 return true;
 else
 return false;
 }

}

Now you can use it:

@CNPValidator()
public String getCNP(){
return cnp;
}

2. Custom validators to be used from jsf page.

Because I did not find a way to use the above validator directly from jsf (of course, it can be used if you declare it in a validator jsf tag but I prefer a simpler way – that’s Seam, isn’t it?) I have defined it like:

@Name("roCountyValidator")
@Validator
@BypassInterceptors
public class RoCountyValidator implements javax.faces.validator.Validator,
		Serializable {

	private static final long serialVersionUID = -3876319398131645955L;
	Log log = Logging.getLog(RoCountyValidator.class);

	public void validate(FacesContext context, UIComponent component,
			Object value) throws ValidatorException {
		log.info("validating....!");
		if (String.valueOf(value).equals("Arad")
                      //etc )
			((UIInput) component).setValid(true);
		else {
			((UIInput) component).setValid(false);
			FacesMessage message = new FacesMessage();
			message.setDetail("Invalid county");
			message.setSeverity(FacesMessage.SEVERITY_ERROR);
			throw new ValidatorException(message);
		}
	}
}

Now you can use it from xhtml page like:

<h:inputText id="someField" value="#{booking.creditCardName}"
                                   required="true" label="County" validator="roCountyValidator">
                    <h:message for="someField"/>
                </h:inputText>

Please note that I do not use EL to bind the validator because it’s not necessary. (Seam will transform that component in the background to a jsf validator so you do no longer need jsf validator tags or any other configuration in faces-config.xml).

Cool, isn’t it?

Advertisements

From → JAVA, Seam Framework

One Comment
  1. Carlos permalink

    This works fine!, but don’t forget add the ajax call in xhtml with <a4j:support tag, else the metod "validate" never will call.

    Thank you, Carlos.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: