In this final step, we will build a complete form validation system that incorporates all the techniques we've learned. We'll create a more modular, reusable validation system that can be easily extended for different applications.
Creating a Validation Utility Class
Let's start by creating a utility class that encapsulates our validation methods:
-
Create a new file named InputValidator.java
in the WebIDE.
-
Add the following code to the file:
import java.util.regex.Pattern;
import java.util.regex.Matcher;
/**
* Utility class for validating user input
*/
public class InputValidator {
// Regular expression patterns
private static final String USERNAME_PATTERN = "^[a-zA-Z0-9_]{3,15}$";
private static final String EMAIL_PATTERN = "^[a-zA-Z0-9_+&*-]+(?:\\.[a-zA-Z0-9_+&*-]+)*@(?:[a-zA-Z0-9-]+\\.)+[a-zA-Z]{2,7}$";
private static final String PHONE_PATTERN = "^\\d{3}-\\d{3}-\\d{4}$";
private static final String PASSWORD_PATTERN = "^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%^&+=])(?=\\S+$).{8,}$";
/**
* Validates a username
* @param username The username to validate
* @return true if the username is valid, false otherwise
*/
public static boolean isValidUsername(String username) {
if (username == null) {
return false;
}
Pattern pattern = Pattern.compile(USERNAME_PATTERN);
Matcher matcher = pattern.matcher(username);
return matcher.matches();
}
/**
* Validates an email address
* @param email The email to validate
* @return true if the email is valid, false otherwise
*/
public static boolean isValidEmail(String email) {
if (email == null) {
return false;
}
Pattern pattern = Pattern.compile(EMAIL_PATTERN);
Matcher matcher = pattern.matcher(email);
return matcher.matches();
}
/**
* Validates a phone number
* @param phone The phone number to validate
* @return true if the phone number is valid, false otherwise
*/
public static boolean isValidPhone(String phone) {
if (phone == null) {
return false;
}
Pattern pattern = Pattern.compile(PHONE_PATTERN);
Matcher matcher = pattern.matcher(phone);
return matcher.matches();
}
/**
* Validates an age
* @param age The age to validate
* @return true if the age is valid, false otherwise
*/
public static boolean isValidAge(int age) {
return age >= 0 && age <= 120;
}
/**
* Validates a password
* @param password The password to validate
* @return true if the password is valid, false otherwise
*/
public static boolean isValidPassword(String password) {
if (password == null) {
return false;
}
Pattern pattern = Pattern.compile(PASSWORD_PATTERN);
Matcher matcher = pattern.matcher(password);
return matcher.matches();
}
/**
* Gets the error message for an invalid username
* @return The error message
*/
public static String getUsernameErrorMessage() {
return "Username must be 3-15 characters long and contain only letters, numbers, or underscores.";
}
/**
* Gets the error message for an invalid email
* @return The error message
*/
public static String getEmailErrorMessage() {
return "Please enter a valid email address.";
}
/**
* Gets the error message for an invalid phone number
* @return The error message
*/
public static String getPhoneErrorMessage() {
return "Please enter a valid phone number in the format 123-456-7890.";
}
/**
* Gets the error message for an invalid age
* @return The error message
*/
public static String getAgeErrorMessage() {
return "Age must be between 0 and 120.";
}
/**
* Gets the error message for an invalid password
* @return The error message
*/
public static String getPasswordErrorMessage() {
return "Password must be at least 8 characters long and contain at least one digit, one lowercase letter, one uppercase letter, one special character, and no whitespace.";
}
}
- Save the file by pressing
Ctrl+S
.
Now, let's create a new version of our registration form that uses the InputValidator
class:
-
Create a new file named CompleteRegistrationForm.java
in the WebIDE.
-
Add the following code to the file:
import java.util.Scanner;
public class CompleteRegistrationForm {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// Collect and validate user information
String username = getValidInput(scanner, "Username", InputValidator::isValidUsername, InputValidator.getUsernameErrorMessage());
int age = getValidAge(scanner);
String email = getValidInput(scanner, "Email", InputValidator::isValidEmail, InputValidator.getEmailErrorMessage());
String phone = getValidInput(scanner, "Phone number (format: 123-456-7890)", InputValidator::isValidPhone, InputValidator.getPhoneErrorMessage());
String password = getValidInput(scanner, "Password", InputValidator::isValidPassword, InputValidator.getPasswordErrorMessage());
// Display the registration information
System.out.println("\nRegistration Successful!");
System.out.println("Username: " + username);
System.out.println("Age: " + age);
System.out.println("Email: " + email);
System.out.println("Phone: " + phone);
System.out.println("Password: " + maskPassword(password));
scanner.close();
}
/**
* Generic method to get valid input from the user
* @param scanner The scanner to read input
* @param fieldName The name of the field being validated
* @param validator The validation function
* @param errorMessage The error message to display
* @return The validated input
*/
private static String getValidInput(Scanner scanner, String fieldName, java.util.function.Predicate<String> validator, String errorMessage) {
String input;
boolean validInput = false;
do {
System.out.print("Enter your " + fieldName + ": ");
input = scanner.nextLine().trim();
if (!validator.test(input)) {
System.out.println("Error: " + errorMessage);
} else {
validInput = true;
}
} while (!validInput);
return input;
}
/**
* Gets a valid age from the user
* @param scanner The scanner to read input
* @return The validated age
*/
private static int getValidAge(Scanner scanner) {
int age = 0;
boolean validAge = false;
while (!validAge) {
try {
System.out.print("Enter your age (0-120): ");
age = Integer.parseInt(scanner.nextLine());
if (!InputValidator.isValidAge(age)) {
System.out.println("Error: " + InputValidator.getAgeErrorMessage());
} else {
validAge = true;
}
} catch (NumberFormatException e) {
System.out.println("Error: Please enter a valid numeric age.");
}
}
return age;
}
/**
* Masks a password for display
* @param password The password to mask
* @return The masked password
*/
private static String maskPassword(String password) {
if (password == null || password.isEmpty()) {
return "";
}
return "*".repeat(password.length());
}
}
-
Save the file by pressing Ctrl+S
.
-
Compile both Java files:
javac InputValidator.java
javac CompleteRegistrationForm.java
- Run the registration form program:
java CompleteRegistrationForm
- Follow the prompts to enter valid information for each field. The program will validate each input according to the rules defined in the
InputValidator
class.
Sample interaction:
Enter your Username: john_doe
Enter your age (0-120): 35
Enter your Email: [email protected]
Enter your Phone number (format: 123-456-7890): 123-456-7890
Enter your Password: weakpw
Error: Password must be at least 8 characters long and contain at least one digit, one lowercase letter, one uppercase letter, one special character, and no whitespace.
Enter your Password: P@ssw0rd123
Registration Successful!
Username: john_doe
Age: 35
Email: [email protected]
Phone: 123-456-7890
Password: ***********
Benefits of This Approach
The approach we've taken in this final example offers several advantages:
- Modularity: The validation logic is separated into a reusable utility class.
- Extensibility: New validation rules can be easily added to the
InputValidator
class.
- Maintainability: Error messages are centralized and can be easily updated.
- Code Reuse: The
getValidInput
method is generic and can be used for different types of input.
- Security: The password is masked when displayed to the user.
This design follows good software engineering principles and makes it easy to adapt the validation system for different applications.