Just when you think your Java application’s data validation is becoming complex, Apache Commons Validator steps in to simplify your life.
As you go through this comprehensive guide, you’ll discover how this powerful library can streamline your validation requirements with its rich set of built-in validators.
Whether you’re building a web application or processing data in a standalone Java program, you’ll find Apache Commons Validator offers an elegant solution to validate emails, URLs, credit cards, and more.
Your journey to robust data validation starts here, with a library trusted by developers worldwide.
Getting Started
Apache Commons Validator is a versatile library that helps you implement data validation with minimal effort in your Java applications.
This powerful tool provides a collection of validators for common data types and allows you to create custom validation rules tailored to your needs.
Environment Setup
Commons Validator can be easily added to your project using Maven.
Add the following dependency to your pom.xml:
<dependency> <groupId>commons-validator</groupId> <artifactId>commons-validator</artifactId> <version>1.9.0</version> </dependency>
If you are using Gradle, then add below dependency
implementation 'commons-validator:commons-validator:1.9.0'
Basic Validation Architecture
Started with version 1.9.0, Apache Commons Validator follows a component-based architecture where each validator is responsible for a specific type of validation.
The library provides both simple validators for basic data types and complex validators for more sophisticated validation scenarios.
Steps in the validation process involve
- creating appropriate validator instances,
- configuring validation rules, and
- executing validation checks.
Here’s an example demonstrating the basic validation flow:
public class ValidationExample { public static void main(String[] args) { // Create validator instance EmailValidator validator = EmailValidator.getInstance(); // Perform validation String email = "user@example.com"; if (validator.isValid(email)) { System.out.println("Email is valid!"); } else { System.out.println("Invalid email format"); } } }
Standard Validators Implementation
All standard validators in Apache Commons Validator provide you with ready-to-use validation functionality for common data types.
These validators are thread-safe and highly optimized, saving you time and effort in implementing validation logic from scratch.
Let’s explore the main categories of validators available in version 1.9.0.
1. String and Text Validators
With String validators, you can perform various text-based validations efficiently.
The library offers EmailValidator
, UrlValidator
and RegexValidator
for common text validation scenarios.
Email Validation
Here’s a quick example of email validation:
EmailValidator emailValidator = EmailValidator.getInstance(); boolean isValid = emailValidator.isValid("user@example.com");
URL Validation
You can easily check if a URL is in standard format or not with its URLValidator
class as shown below
UrlValidator validator = UrlValidator.getInstance(); boolean isURLValid = validator.isValid("www.example.com"); // false boolean isURLValid = validator.isValid("http://example.com"); // true
Regex Validation
Assuming you need to validate complex string patterns, you can use the RegexValidator
class.
This powerful feature allows you to define multiple patterns and customize matching behavior:
RegexValidator v = new RegexValidator("^[a-z0–9._%+-]+@[a-z0–9.-]+\\.[a-z]{2,6}$"}); boolean isValid = v.isValid("your.email@domain.com");
Development of regex-based validation can be enhanced by combining multiple patterns and using case-sensitive matching.
Domain Validation
You can check if a given string represents a valid domain name format using its DomainValidator
class:
DomainValidator dv = DomainValidator.getInstance(); boolean valid = dv.isValid("google.com"); // true valid = dv.isValid("google"); // false
2. Numeric Validators
Validators for numeric values help you validate integers, decimals, and currency amounts.
These include IntegerValidator
, DoubleValidator
and CurrencyValidator
, ensuring your numeric inputs meet specific format and range requirements.
You can use these validators to check
- If a number is in specific format.
- If a number falls within an acceptable range.
Here’s how you can validate an integer range:
int value = 10; IntegerValidator intValidator = IntegerValidator.getInstance(); boolean isValid = intValidator.isInRange(value, 1, 100); // true // For currency validation BigDecimalValidator currencyValidator = CurrencyValidator.getInstance(); boolean isValidAmount = currencyValidator.isValid("$1234.56", Locale.US);
3. Date and Time Validators
On the date and time front, Apache Commons Validator provides you with robust validation for various date formats, time zones, and calendar systems.
The DateValidator
helps ensure your date inputs conform to specified patterns and ranges.
Validators in this category allow you to check date formats across different locales and validate against custom patterns.
Here’s an example:
DateValidator dateValidator = DateValidator.getInstance(); String pattern = "yyyy-MM-dd"; boolean isValid = dateValidator.isValid("2023–12–31", pattern); // With specific locale boolean isValidLocale = dateValidator.isValid("31/12/2023", "dd/MM/yyyy", Locale.UK);
You can also use DateValidator
to convert a string to a java.util.Date
object with its validate()
method
DateValidator instance = DateValidator.getInstance(); Date date = instance.validate("25-12-2024", "dd/MM/yyyy"); System.out.println(date); // Wed Dec 25 00:00:00 IST 2024
If the specified date is not in the format provided, then validate()
will return null
.
Testing Strategies
If you want to ensure your validation logic works correctly, you’ll need to implement comprehensive unit tests.
JUnit 5 works perfectly with Apache Commons Validator, allowing you to test individual validators in isolation.
Here’s a simple example of testing an EmailValidator
:
@Test void testEmailValidation() { EmailValidator validator = EmailValidator.getInstance(); assertTrue(validator.isValid("user@domain.com")); assertFalse(validator.isValid("invalid.email@")); assertFalse(validator.isValid("@domain.com")); }
Validation Scenarios
You should create a comprehensive set of test scenarios covering both valid and invalid inputs.
This includes edge cases, boundary values, and common user input patterns that your application might encounter.
It’s beneficial to organize your test scenarios into categories based on validation types.
Consider this example of testing different credit card formats:
@Test void testCreditCardScenarios() { CreditCardValidator validator = new CreditCardValidator(); assertTrue(validator.isValid("4111111111111111")); // Visa assertTrue(validator.isValid("5500000000000004")); // MasterCard assertFalse(validator.isValid("1111111111111111")); // Invalid assertFalse(validator.isValid("")); }
Security Considerations
Input Sanitization
Your validation strategy should always include proper input sanitization.
On top of using Apache Commons Validator’s built-in validators, you should implement additional security measures to prevent injection attacks.
Here’s an example of combining validation with sanitization:
public boolean validateAndSanitizeEmail(String email) { // First, sanitize the input String sanitizedEmail = email. trim(). replaceAll("[\\n\\r]", ""). toLowerCase(); // Then validate using EmailValidator EmailValidator validator = EmailValidator.getInstance(); return validator.isValid(sanitizedEmail); }
Validation Boundaries
There’s a need to set appropriate boundaries for your validation rules. String lengths, numeric ranges, and other constraints should be carefully defined to prevent buffer overflow attacks and resource exhaustion.
The implementation of boundary validation can be achieved using custom validators or by combining multiple validators.
Here’s an example:
public class BoundedStringValidator { private static final int MAX_LENGTH = 255; public boolean isValid(String input) { return input != null && input.length() <= MAX_LENGTH && input.matches("^[a-zA-Z0–9\\s.-]*$"); } }
Code Organization
Organization of your validation code should follow a clear, modular structure.
You can create separate validator classes for different domains of your application, making your code more maintainable and testable.
Implementation of your validation logic should be centralized in dedicated classes or services.
Consider this example of a well-organized validation service:
public class UserValidationService { private final EmailValidator emailValidator; private final RegexValidator passwordValidator; public UserValidationService() { this.emailValidator = EmailValidator.getInstance(); this.passwordValidator = new RegexValidator("^(?=.*[A-Za-z])(?=.*\\d)[A-Za-z\\d]{8,}$"); } public ValidationResult validateUser(User user) { ValidationResult result = new ValidationResult(); if (!emailValidator.isValid(user.getEmail())) { result.addError("email", "Invalid email format"); } // Add more validation logic return result; } }
Conclusion
We explored the comprehensive capabilities of Apache Commons Validator, equipping you with powerful tools for robust data validation in your Java applications.
You can implement validations using simple code like EmailValidator.getInstance().isValid(“user@domain.com”)
.
Using Apache Commons library, you’re well-prepared to implement reliable validation logic that ensures data integrity across your applications.