Skip to main content

Overview

Password validation is critical for application security. The Validator library provides powerful tools to enforce password strength requirements through character composition rules.

Basic Password Validation

Start with a simple password validator that checks minimum length:
import io.github.ApamateSoft.validator.Validator;

Validator passwordValidator = new Validator.Builder()
    .required()
    .minLength(8)
    .build();

Password Strength Requirements

Using Character Alphabets

The library provides predefined character sets in the Alphabets class:
import static io.github.ApamateSoft.validator.utils.Alphabets.*;

// Available alphabets:
// ALPHA_LOWERCASE = "abcdefghijklmnopqrstuvwxyz"
// ALPHA_UPPERCASE = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
// NUMBER = "0123456789"
// ALPHA_NUMERIC = lowercase + uppercase + numbers

Strong Password Validator

Create a validator that enforces multiple character type requirements:
import io.github.ApamateSoft.validator.Validator;
import static io.github.ApamateSoft.validator.utils.Alphabets.*;

Validator strongPassword = new Validator.Builder()
    .required("Password is required")
    .minLength(12, "Password must be at least 12 characters")
    .mustContainMin(3, ALPHA_LOWERCASE, "At least 3 lowercase letters required")
    .mustContainMin(3, ALPHA_UPPERCASE, "At least 3 uppercase letters required")
    .mustContainMin(3, NUMBER, "At least 3 numbers required")
    .mustContainMin(3, "@~_/", "At least 3 special characters (@~_/) required")
    .build();
The mustContainMin(min, alphabet, message) rule validates that the string contains at least min characters from the specified alphabet.

Password Confirmation

Always verify that users correctly re-entered their password:

Using isMatch() with Events

import io.github.ApamateSoft.validator.Validator;

public class PasswordForm {
    
    private Validator passwordValidator = new Validator.Builder()
        .required()
        .minLength(12)
        .mustContainMin(3, ALPHA_LOWERCASE)
        .mustContainMin(3, ALPHA_UPPERCASE)
        .mustContainMin(3, NUMBER)
        .mustContainOne("@#$%^&*")
        .setNotMatchMessage("Passwords do not match")
        .build();
    
    private String password = "";
    private String confirmPassword = "";
    
    public PasswordForm() {
        passwordValidator.onInvalidEvaluation(message -> {
            System.err.println("Error: " + message);
        });
    }
    
    public boolean validatePassword() {
        // This validates the password AND checks if both match
        return passwordValidator.isMatch(password, confirmPassword);
    }
}

Using compareOrFail() with Exceptions

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

public class PasswordForm {
    
    private Validator passwordValidator = new Validator.Builder()
        .required()
        .minLength(12)
        .mustContainMin(3, ALPHA_LOWERCASE)
        .mustContainMin(3, ALPHA_UPPERCASE)
        .mustContainMin(3, NUMBER)
        .mustContainOne("@#$%^&*")
        .build();
    
    public void changePassword(String newPassword, String confirmPassword) {
        try {
            passwordValidator.compareOrFail("password", newPassword, confirmPassword);
            // Password is valid and matches - proceed with update
            updatePassword(newPassword);
        } catch (InvalidEvaluationException e) {
            System.err.println("Password validation failed: " + e.getMessage());
        }
    }
}
Use .setNotMatchMessage() to customize the error message shown when passwords don’t match.

Password Validation with Annotations

For a declarative approach, use annotations on your data model:
import io.github.ApamateSoft.validator.annotations.*;
import static io.github.ApamateSoft.validator.utils.Alphabets.*;

public class UserRegistration {

    @Required(message = "Password is required")
    @MinLength(min = 8, message = "Password must be at least 8 characters")
    @MustContainMin(min = 3, alphabet = ALPHA_LOWERCASE, message = "At least 3 lowercase letters required")
    @MustContainMin(min = 3, alphabet = NUMBER, message = "At least 3 numbers required")
    @MustContainOne(alphabet = ALPHA_UPPERCASE, message = "At least one uppercase letter required")
    @MustContainOne(alphabet = "@#*-", message = "At least one special character required")
    @Compare(compareWith = "passwordConfirm", message = "Passwords do not match")
    private String password;
    
    private String passwordConfirm;

    // Constructor, getters, setters...
}
Validate the annotated object:
import io.github.ApamateSoft.validator.Validator;
import io.github.ApamateSoft.validator.exceptions.InvalidEvaluationException;

public void register(UserRegistration user) {
    try {
        Validator.validOrFail(user);
        // All validations passed
        createUserAccount(user);
    } catch (InvalidEvaluationException e) {
        if ("password".equals(e.getKey())) {
            System.err.println("Password error: " + e.getMessage());
        }
    }
}

Common Password Patterns

Moderate Security (8+ characters)

Validator moderatePassword = new Validator.Builder()
    .required()
    .minLength(8)
    .mustContainOne(ALPHA_LOWERCASE)
    .mustContainOne(ALPHA_UPPERCASE)
    .mustContainOne(NUMBER)
    .build();

High Security (12+ characters)

Validator highSecurityPassword = new Validator.Builder()
    .required()
    .minLength(12)
    .mustContainMin(3, ALPHA_LOWERCASE)
    .mustContainMin(3, ALPHA_UPPERCASE)
    .mustContainMin(3, NUMBER)
    .mustContainMin(3, "@~_/")
    .build();

Enterprise Security (16+ characters)

Validator enterprisePassword = new Validator.Builder()
    .required()
    .minLength(16)
    .mustContainMin(4, ALPHA_LOWERCASE)
    .mustContainMin(4, ALPHA_UPPERCASE)
    .mustContainMin(4, NUMBER)
    .mustContainMin(4, "!@#$%^&*()-_=+")
    .notContain(" ", "Spaces are not allowed")
    .build();

Character Requirements Reference

Validates that the string contains at least one character from the specified alphabet.
.mustContainOne(ALPHA_UPPERCASE, "At least one uppercase letter required")
.mustContainOne("!@#$", "At least one special character required")
Validates that the string contains at least a minimum number of characters from the specified alphabet.
.mustContainMin(3, ALPHA_LOWERCASE, "At least 3 lowercase letters required")
.mustContainMin(2, NUMBER, "At least 2 numbers required")
Validates that the string does not contain any characters from the specified alphabet.
.notContain(" ", "Spaces are not allowed")
.notContain("<>\"'", "HTML characters are not allowed")

Real-World Example

Here’s a complete password change form implementation:
import io.github.ApamateSoft.validator.Validator;
import static io.github.ApamateSoft.validator.utils.Alphabets.*;

public class PasswordChangeForm {
    
    private final Validator currentPasswordValidator = new Validator.Builder()
        .required("Current password is required")
        .build();
    
    private final Validator newPasswordValidator = new Validator.Builder()
        .required("New password is required")
        .minLength(12, "Must be at least 12 characters")
        .mustContainMin(3, ALPHA_LOWERCASE)
        .mustContainMin(3, ALPHA_UPPERCASE)
        .mustContainMin(3, NUMBER)
        .mustContainOne("@#$%^&*")
        .setNotMatchMessage("Passwords do not match")
        .build();
    
    private String currentPassword = "";
    private String newPassword = "";
    private String confirmNewPassword = "";
    
    public PasswordChangeForm() {
        currentPasswordValidator.onInvalidEvaluation(msg -> 
            displayError("current", msg));
        newPasswordValidator.onInvalidEvaluation(msg -> 
            displayError("new", msg));
    }
    
    public void submit() {
        if (!currentPasswordValidator.isValid(currentPassword)) return;
        if (!newPasswordValidator.isMatch(newPassword, confirmNewPassword)) return;
        
        // All validations passed
        updatePassword(currentPassword, newPassword);
    }
    
    private void displayError(String field, String message) {
        System.err.println(field + " error: " + message);
    }
}
Never log or display actual password values in error messages. The InvalidEvaluationException contains the password value in getValue(), but you should only use the getMessage() and getKey() for error handling.

Next Steps

Form Validation

Learn how to validate complete forms with multiple fields

Error Handling

Explore different error handling strategies

Build docs developers (and LLMs) love