As your question was a little modified, I added a strikeout to the content related to your original question:
First, The application level validation include points 3 and 4 (Custom validation using Validator interface and Validation methods in backing beans) in addition to using Custom Component.
It seems that you are mixing up Validation using bean methods and implementing custom validator classes (the two last ones), a quick refresh about this two approaches taking your code as an example :
Validation with bean methods:
This is the most simple one, as hou will just need to add validation method to your class and invoke it through a method expression using the validator
attribute, like your example :
<h:inputText id="username" value="#{user.username}" required="true" validator="#{usernameValidator}" />
// I changed to usernameValidator to respect naming conventions
But, in that case, usernameValidator
is a method in the user
@ManagedBean
, something like this:
@ManagedBean("user")
@SessionScoped
public class User implements Serializable{
// Please notice that this method should have the same signature as the validate method of the interface Validator
public void usernameValidator(FacesContext fc, UIComponent uic, Object value) throws ValidatorException {
JOptionPane.showMessageDialog(null, "in validator class");
if (String.valueOf(value).length() == 0 || String.valueOf(value).length() < 3) {
FacesMessage message = new FacesMessage("Username Validation Failed", "Invalid Username");
message.setSeverity(FacesMessage.SEVERITY_ERROR);
throw new ValidatorException(message);
}
}
}
Custom Validator Classes:
The implementation for the Class is the same as what you did, which is implementing the Validator
Interface, and registring the Validator by giving it and ID
, I will copy your exact code to make the answer clean:
// I just changed the ID from UsernameValidator to usernameValidator
@FacesValidator("usernameValidator")
public class UsernameValidator implements Validator {
@Override
public void validate(FacesContext fc, UIComponent uic, Object value) throws ValidatorException {
JOptionPane.showMessageDialog(null, "in validator class");
if (String.valueOf(value).length() == 0 || String.valueOf(value).length() < 3) {
FacesMessage message = new FacesMessage("Username Validation Failed", "Invalid Username");
message.setSeverity(FacesMessage.SEVERITY_ERROR);
throw new ValidatorException(message);
}
}
}
You can give and ID
to your Validator by using annotation @FacesValidator("usernameValidator")
(which you already did), Or in the faces-config.xml
by adding the following:
<validator>
<validator-id>usernameValidator</validator-id>
<validator-class>yourpackage.UsernameValidator</validator-class>
</validator>
Then, you will use the same ID
in the f:validator
Tag, like this:
<h:inputText id="username" value="#{user.username}" required="true">
<f:validator validatorId="usernameValidator" />
</h:inputText>
NB: This is not all validation appraoches in JSF, but I think that these two are the simplest ones for Custom validation which you can use in your example (It's the 4 and 3 respectively in the list of JSF validation ways you provided).
As additional information, I will also give a brief review about the Built-in validation components which doesn't fit to your Code example:
Built-in validation components:
JSF (I am talking about 2.0 as I am not sure if there is some new ones in JSF 2.2) has standard validators that you can use to validate:
- The length of
String
using f:validateLength
- A
double
/ long
value within an optional range using f:validateDoubleRange
/ f:validateLongRange
respectivly.
- A
String
against a regular expression using f:validateRegex
- Required values using
f:validateRequired
or the attribute required
There is another alternative for using those Tags by using the f:validator
, you can find a good example here.
See also: