Skip to main content

Overview

Numeric rules validate that String values represent valid numbers and fall within specified ranges. These rules are essential for validating numeric inputs like prices, ages, quantities, and other numerical data.

Format Validation

number

Validates that the String is in a valid numeric format.
public void number(String message)
public void number()
message
String
Custom error message (optional - uses default if not provided)
Accepts:
  • Integers: "123"
  • Decimal numbers: "123.45"
  • Negative values: "-123", "-123.45"
Example:
Validator validator = new Validator.Builder()
    .build();
validator.number()
    .build();
validator.number("Please enter a valid number");

validator.isValid("123");      // true
validator.isValid("123.45");   // true
validator.isValid("-123");     // true
validator.isValid("-123.45");  // true
validator.isValid("abc");      // false
validator.isValid("12.34.56"); // false
Builder Usage:
Validator validator = new Validator.Builder()
    .number("Invalid number format")
    .build();
Annotation Usage:
public class Product {
    @Number
    private String price;
    
    @Number(message = "Quantity must be a number")
    private String quantity;
}

numberPattern

Validates that the String matches a specific pattern, where ‘x’ characters can be replaced with numbers.
public void numberPattern(String pattern, String message)
public void numberPattern(String pattern)
pattern
String
required
Pattern string where ‘x’ represents positions that can contain numbers or ‘x’ itself
message
String
Error message (can use %s placeholder for pattern)
How It Works:
  • Each ‘x’ in the pattern can be matched by a digit (0-9) OR the letter ‘x’
  • All other characters must match exactly
  • Useful for phone numbers, credit cards, formatted IDs, etc.
Example:
// Phone number pattern
validator.numberPattern("+xx (xxx) xxx-xx-xx");
validator.numberPattern("+1 (xxx) xxx-xxxx", "Invalid US phone number format");

// Valid matches for pattern "+xx (xxx) xxx-xx-xx"
validator.isValid("+12 (345) 678-90-12");  // true (all digits)
validator.isValid("+xx (345) 678-90-12");  // true (x's in first two)
validator.isValid("+xx (xxx) xxx-xx-xx");  // true (all x's)
validator.isValid("+12 (3x5) 678-90-12");  // true (mixed)

// Invalid
validator.isValid("+12 (345) 678-9012");   // false (wrong format)
validator.isValid("+12 345 678-90-12");    // false (missing parens)
Common Patterns:
// US Phone: +1 (xxx) xxx-xxxx
validator.numberPattern("+1 (xxx) xxx-xxxx");

// Credit Card: xxxx-xxxx-xxxx-xxxx
validator.numberPattern("xxxx-xxxx-xxxx-xxxx");

// SSN: xxx-xx-xxxx
validator.numberPattern("xxx-xx-xxxx");

// Date: xx/xx/xxxx
validator.numberPattern("xx/xx/xxxx");
Annotation Usage:
public class Contact {
    @NumberPattern(patter = "+1 (xxx) xxx-xxxx")
    private String phoneNumber;
    
    @NumberPattern(
        patter = "xxx-xx-xxxx",
        message = "SSN must be in format xxx-xx-xxxx"
    )
    private String ssn;
}
Note: The annotation parameter is spelled patter (not pattern) in the source code.

Value Range Validation

minValue

Validates that the numeric value of the String is not less than the minimum.
public void minValue(double min, String message)
public void minValue(double min)
min
double
required
Minimum allowed value (inclusive)
message
String
Error message (can use %s placeholder for min value)
Note: It is recommended to use the number() rule first to ensure the String is a valid number. Example:
Validator validator = new Validator.Builder()
    .build();
validator.number()
    .build();
validator.minValue(0);
validator.minValue(18, "Must be at least %s years old");

validator.isValid("17");    // false
validator.isValid("18");    // true
validator.isValid("25");    // true
validator.isValid("18.5");  // true
Annotation Usage:
public class Order {
    @Number
    @MinValue(min = 0.01, message = "Price must be at least $0.01")
    private String price;
    
    @Number
    @MinValue(min = 1)
    private String quantity;
}

maxValue

Validates that the numeric value of the String is not greater than the maximum.
public void maxValue(double max, String message)
public void maxValue(double max)
max
double
required
Maximum allowed value (inclusive)
message
String
Error message (can use %s placeholder for max value)
Note: It is recommended to use the number() rule first. Example:
Validator validator = new Validator.Builder()
    .build();
validator.number()
    .build();
validator.maxValue(100);
validator.maxValue(150.5, "Cannot exceed %s");

validator.isValid("99");     // true
validator.isValid("100");    // true
validator.isValid("100.5");  // false
validator.isValid("150.5");  // true if max is 150.5
Annotation Usage:
public class Survey {
    @Number
    @MaxValue(max = 10, message = "Rating must be 10 or less")
    private String rating;
    
    @Number
    @MaxValue(max = 120)
    private String age;
}

rangeValue

Validates that the numeric value of the String is within the specified range (inclusive).
public void rangeValue(double min, double max, String message)
public void rangeValue(double min, double max)
min
double
required
Minimum allowed value (inclusive)
max
double
required
Maximum allowed value (inclusive)
message
String
Error message (can use %s placeholders for min and max values)
Note: It is recommended to use the number() rule first. Example:
Validator validator = new Validator.Builder()
    .build();
validator.number()
    .build();
validator.rangeValue(1, 10);
validator.rangeValue(18, 65, "Age must be between %s and %s");

validator.isValid("0");     // false (below min)
validator.isValid("1");     // true
validator.isValid("5.5");   // true
validator.isValid("10");    // true
validator.isValid("11");    // false (above max)
Builder Usage:
Validator percentageValidator = new Validator.Builder()
    .number("Must be a number")
    .rangeValue(0, 100, "Percentage must be between %s and %s")
    .build();
Annotation Usage:
public class Assessment {
    @Number
    @RangeValue(min = 0, max = 100, message = "Score must be 0-100")
    private String score;
    
    @Number
    @RangeValue(min = 1.0, max = 5.0)
    private String rating;
}

Complete Examples

Price Validation

Validator priceValidator = new Validator.Builder()
    .required("Price is required")
    .number("Price must be a valid number")
    .minValue(0.01, "Price must be at least $%s")
    .maxValue(999999.99, "Price cannot exceed $%s")
    .build();

try {
    priceValidator.validOrFail("price", "49.99");
    System.out.println("Valid price");
} catch (InvalidEvaluationException e) {
    System.err.println(e.getMessage());
}

Age Validation

Validator ageValidator = new Validator();
ageValidator.required("Age is required");
ageValidator.number("Age must be a number");
ageValidator.rangeValue(0, 150, "Age must be between %s and %s");
ageValidator.onlyNumbers(); // Ensure no decimal points

ageValidator.onInvalidEvaluation(error -> {
    System.err.println("Validation error: " + error);
});

boolean isValid = ageValidator.isValid("25"); // true

Quantity Validation

Validator quantityValidator = new Validator.Builder()
    .required()
    .onlyNumbers() // Integer only
    .minValue(1, "Quantity must be at least %s")
    .maxValue(1000, "Cannot order more than %s items")
    .build();

Phone Number Validation

Validator phoneValidator = new Validator.Builder()
    .required("Phone number is required")
    .numberPattern(
        "+1 (xxx) xxx-xxxx",
        "Phone must be in format +1 (xxx) xxx-xxxx"
    )
    .build();

boolean valid = phoneValidator.isValid("+1 (555) 123-4567"); // true

Credit Card Validation

Validator cardValidator = new Validator();
cardValidator.required("Card number is required");
cardValidator.numberPattern(
    "xxxx-xxxx-xxxx-xxxx",
    "Card must be in format xxxx-xxxx-xxxx-xxxx"
);

cardValidator.onInvalidEvaluation(error -> {
    showErrorDialog(error);
});

Rating Validation (1-5 Stars)

Validator ratingValidator = new Validator.Builder()
    .required("Rating is required")
    .number("Rating must be a number")
    .rangeValue(1, 5, "Rating must be between %s and %s stars")
    .build();

Percentage Validation

Validator percentValidator = new Validator();
percentValidator.required();
percentValidator.number("Must be a valid number");
percentValidator.rangeValue(0, 100, "Percentage must be between %s%% and %s%%");

if (percentValidator.isValid("85.5")) {
    System.out.println("Valid percentage");
}

Discount Code Validation

Validator discountCodeValidator = new Validator.Builder()
    .required()
    .numberPattern("SAVE-xx", "Discount code must be in format SAVE-xx")
    .build();

// Valid codes: "SAVE-10", "SAVE-25", "SAVE-xx"

Using with Annotations

public class ProductForm {
    @Required(message = "Product name is required")
    private String name;
    
    @Number
    @MinValue(min = 0.01)
    @MaxValue(max = 99999.99)
    private String price;
    
    @Number
    @MinValue(min = 0)
    @MaxValue(max = 10000)
    private String stockQuantity;
    
    @Number
    @RangeValue(min = 0, max = 100)
    private String discountPercent;
    
    @NumberPattern(patter = "xxx-xxx-xxxx")
    private String sku;
}

// Validate the entire form
ProductForm form = new ProductForm();
try {
    Validator.validOrFail(form);
    System.out.println("Form is valid");
} catch (InvalidEvaluationException e) {
    System.err.println("Field " + e.getKey() + ": " + e.getMessage());
}

Best Practices

1. Always Validate Format First

// Good
validator.number();
validator.minValue(0);
validator.maxValue(100);

// Less ideal - may fail if not a number
validator.minValue(0);

2. Use Appropriate Data Types

// For integers
validator.onlyNumbers();
validator.rangeValue(1, 100);

// For decimals
validator.number();
validator.rangeValue(0.01, 999.99);

3. Provide Clear Error Messages

// Good
validator.rangeValue(18, 65, "Age must be between %s and %s years");

// Less helpful
validator.rangeValue(18, 65);

4. Combine with Other Rules

Validator priceValidator = new Validator.Builder()
    .required("Price is required")
    .number("Must be a valid number")
    .minValue(0.01, "Price must be positive")
    .maxLength(10) // Limit total string length
    .build();

See Also

Build docs developers (and LLMs) love