Skip to main content

Overview

The Validator library makes it easy to validate multiple form fields with different validation rules. This guide demonstrates how to create a complete registration form with proper validation handling.

Complete Registration Form Example

Here’s a real-world example of validating a registration form with email, phone, and password fields.

Defining Reusable Validators

First, create a central place to define your validators:
Validators.java
import io.github.ApamateSoft.validator.Validator;
import static io.github.ApamateSoft.validator.utils.Alphabets.*;

public class Validators {

    public static final Validator email = new Validator.Builder()
        .required()
        .email()
        .build();

    public static final Validator phone = new Validator.Builder()
        .required()
        .numberPattern("(xxxx) xx-xx-xxx")
        .build();
    
    public static final Validator password = new Validator.Builder()
        .required()
        .minLength(12)
        .mustContainMin(3, ALPHA_LOWERCASE)
        .mustContainMin(3, ALPHA_UPPERCASE)
        .mustContainMin(3, NUMBER)
        .mustContainMin(3, "@~_/")
        .build();

}

Using Events for Validation

1

Create validator instances

Copy the predefined validators for each field:
private final Validator emailValidator = Validators.email.copy();
private final Validator pswValidator = Validators.password.copy();
private final Validator phoneValidator = Validators.phone.copy();
2

Set up error handlers

Configure the onInvalidEvaluation event for each validator:
public Register() {
    emailValidator.onInvalidEvaluation(message -> {
        // Display error message in email field UI
        System.err.println("Email error: " + message);
    });
    pswValidator.onInvalidEvaluation(message -> {
        // Display error message in password field UI
        System.err.println("Password error: " + message);
    });
    phoneValidator.onInvalidEvaluation(message -> {
        // Display error message in phone field UI
        System.err.println("Phone error: " + message);
    });
}
3

Validate on submit

Check all fields before submitting:
public void submit() {
    if (
        !emailValidator.isValid(email) ||
        !pswValidator.isMatch(psw, pswConfirmation) ||
        !phoneValidator.isValid(phone)
    ) return;
    
    // All validations passed - proceed with registration
    createAccount(email, phone, psw);
}

Complete Event-Based Example

Register.java
import io.github.ApamateSoft.validator.Validator;

public class Register {

    private final Validator emailValidator = Validators.email.copy();
    private final Validator pswValidator = Validators.password.copy();
    private final Validator phoneValidator = Validators.phone.copy();

    private String email = "";
    private String phone = "";
    private String psw = "";
    private String pswConfirmation = "";

    public Register() {
        emailValidator.onInvalidEvaluation(message -> {
            // TODO: handle error for email
        });
        pswValidator.onInvalidEvaluation(message -> {
            // TODO: handle error for password
        });
        phoneValidator.onInvalidEvaluation(message -> {
            // TODO: handle error for phone
        });
    }

    public void submit() {
        if (
            !emailValidator.isValid(email) ||
            !pswValidator.isMatch(psw, pswConfirmation) ||
            !phoneValidator.isValid(phone)
        ) return;
        // TODO proceed with submit
    }

}

Exception-Based Validation

If you prefer exception handling over events, use the validOrFail and compareOrFail methods:
Register.java
import io.github.ApamateSoft.validator.Validator;
import io.github.ApamateSoft.validator.exceptions.InvalidEvaluationException;

public class Register {

    private final Validator emailValidator = Validators.email.copy();
    private final Validator pswValidator = Validators.password.copy();
    private final Validator phoneValidator = Validators.phone.copy();

    private String email = "";
    private String phone = "";
    private String psw = "";
    private String pswConfirmation = "";

    public void submit() {
        try {
            emailValidator.validOrFail("email", email);
            pswValidator.compareOrFail("psw", psw, pswConfirmation);
            phoneValidator.validOrFail("phone", phone);
            // TODO proceed with submit
        } catch (InvalidEvaluationException e) {
            switch (e.getKey()) {
                case "email":
                    // TODO: handle error for email
                    break;
                case "psw":
                    // TODO: handle error for password
                    break;
                case "phone":
                    // TODO: handle error for phone
                    break;
            }
        }
    }

}
The key parameter in validOrFail() and compareOrFail() helps you identify which field failed validation in the catch block.

Annotation-Based Validation

For a more declarative approach, use annotations directly on your data model:

Create a POJO with Annotations

RegisterPojo.java
import io.github.ApamateSoft.validator.annotations.*;
import static io.github.ApamateSoft.validator.utils.Alphabets.*;

public class RegisterPojo {

    @Required
    @Email
    private String email = "";

    @Required
    @NumberPattern(patter = "(xxxx) xx-xx-xxx")
    private String phone = "";

    @Required
    @MinLength(min = 12)
    @MustContainMin(min = 3, alphabet = ALPHA_LOWERCASE)
    @MustContainMin(min = 3, alphabet = ALPHA_UPPERCASE)
    @MustContainMin(min = 3, alphabet = NUMBER)
    @MustContainMin(min = 3, alphabet = "@~_/")
    @Compare(compareWith = "pswConfirmation")
    private String psw = "";

    private String pswConfirmation = "";

    // Constructor, getters, and setters...
}

Validate the POJO

Register.java
import io.github.ApamateSoft.validator.Validator;
import io.github.ApamateSoft.validator.exceptions.InvalidEvaluationException;

public class Register {

    private RegisterPojo register = new RegisterPojo("", "", "", "");

    public void submit() {
        try {
            Validator.validOrFail(register);
            // TODO proceed with submit
        } catch (InvalidEvaluationException e) {
            switch (e.getKey()) {
                case "email":
                    // TODO: handle error for email
                    break;
                case "psw":
                    // TODO: handle error for password
                    break;
                case "phone":
                    // TODO: handle error for phone
                    break;
            }
        }
    }

}
Annotations only work with String fields. The Validator.validOrFail(Object) method inspects the object’s String fields and applies the validation rules defined by the annotations.

Validation Best Practices

Use .copy() for reusable validators

Always use .copy() when reusing validators to ensure each instance maintains its own state.

Define validators centrally

Create a Validators class to define all your validation rules in one place for consistency.

Validate early

Validate fields as the user types (on blur) to provide immediate feedback.

Provide clear error messages

Customize error messages to be user-friendly and actionable.

Next Steps

Password Validation

Learn advanced password validation techniques

Error Handling

Master both event-based and exception-based error handling

Build docs developers (and LLMs) love