Java: User Input Validation

tips_javaWhenever a user is asked to provide input, the program should expect errors. This is true for almost any language and almost any case; you should protect your MySQL code from sql-injections, your php input fields from scripts, your javascript from infinite loops, your java code from non-fitting variable type.

Purpose

The keyboard “Scanner” object accepts different types of variables using specific commands. The method nextInt expects an integer, nextDouble expects a double, nextFloat expects a float and nextLine expects a string. With the exception of strings, if a user inputs the wrong type, the code will produce an exception and (if not handled correctly) will stop.

The purpose of this code is to produce a consistent method to validate user input, and not let the program proceed until the user has inputted a correct type.

The Methods

The class methods accept user input as string, attempt to convert that input to the expected type. If the conversion was successful, the method returns the result in the correct type. If the conversion failed, the code outputs and error message and requests the user to re-enter a proper input.

The Try/Catch Test

First, we set up a method to test whether or not the accepted input can be converted to a specific type:

	public Boolean isType(String testStr, String type) {
		try {
			if (type.equalsIgnoreCase("float")) {
				Float.parseFloat(testStr);
			} else if (type.equalsIgnoreCase("int")) {
				Integer.parseInt(testStr);
			} else if (type.equalsIgnoreCase("double")) {
				Double.parseDouble(testStr);
			}
			return true;
		} catch(Exception e) {
			return false;
		}

	}

To test if a specific string input, we’d use:

Boolean answer;
answer = isType("10", "float"); //will return true;
answer = isType("1.0", "float"); //will return true;
answer = isType("blah", "int"); //will return false;

The next step is to make sure the code continues requesting for the proper input.

The Input Request Loop

There are methods for retrieving specific types of data. Let’s go over one of those, ‘askInputInt()’:

	public int askInputInt(String informationText) {
		Boolean error = false;
		String userInp = "";
		do {
			System.out.print(informationText);
			userInp = keyboard.nextLine();
			if (!this.isType(userInp, "int")) {
				error = true;
				System.err.println("Error: must be a whole number.");
			} else {
				error = false;
			}
		} while (error == true);
		return Integer.parseInt(userInp);
	}

The loop is called with a string parameter that decides which message the user will see. This message will repeat itself each time the loop requests for the input. In this case, we expect the input to be an integer. The keyboard Scanner accepts any string so it would not break on error, but then tries to convert it to the proper type using “isType” method.

The loop will continue requesting the user for another input as long as the conversion to the proper type failed.

Usage Example

An example of using this code in your program can be something like:

public class Test {

	public static void main(String[] args) {
		Scanner keyboard = new Scanner(System.in);
		moUserInput mValidator = new moUserInput();
		int ssn = mValidator.askInputInt("Please type your ID number: ");
		double age =  mValidator.askInputDouble("Please type your age: ");
		System.out.println("Accepted Results:");
		System.out.println("ID #: " + ssn);
		System.out.println("Age: " + age);
	}
}

In the case above, the system will repeatedly ask “Please type your ID number” until the user inserts a proper integer value. If the user types anything else, the loop will return an error message and repeat the request. Then, it will do the same for the age, expecting a double.

Potential result would be something like:

Please type your ID number: Don’t know

Error: must be a whole number.

Please type your ID number: 1.22w

Error: must be a whole number.

Please type your ID number: 111222333

Please type your age: twenty two

Error: must be a number.

Please type your age: 22

Accepted Results:

ID #: 111222333

Age: 22.0

As you can see, the code ignores inputted ‘errors’ and continues requesting for the proper input. This can save you a lot of time and effort. It sure did for me!

The Full Code

Please note: You are free to use this class in your code, as long as you keep the attribution and copyright notice. If you improve it, send it back to me and I’ll make sure to credit your improvements in the live version!
/**
 * @author Moriel Schottlender
 * @version 1.0
 *
 * A Java class meant to provide easy and consistent validation for user-generated input.
 *
 */

import java.util.Scanner;
public class moUserInput {
	private static Scanner keyboard = new Scanner(System.in);

	/**
	 * A method to repeatedly ask the user for input until 
	 * the input is valid. If condition is used, 
	 * input is measured against it.
	 * 
	 * @param informationText	The information text to prompt
	 * 							to the user.
	 * @return					Returns the final value of the accepted
	 * 							input, as an integer.
	 */
	public int askInputInt(String informationText) {
		Boolean error = false;
		String userInp = "";
		do {
			System.out.print(informationText);
			userInp = keyboard.nextLine();
			if (!this.isType(userInp, "int")) {
				error = true;
				System.err.println("Error: must be a whole number.");
			} else {
				error = false;
			}
		} while (error == true);
		return Integer.parseInt(userInp);
	}

	/**
	 * A method to repeatedly ask the user for input until 
	 * the input is valid. If condition is used, 
	 * input is measured against it.
	 * 
	 * @param informationText	The information text to prompt
	 * 							to the user.
	 * @return					Returns the final value of the accepted
	 * 							input, as a double.
	 */
	public double askInputDouble(String informationText) {
		Boolean error = false;
		String userInp = "";
		do {
			System.out.print(informationText);
			userInp = keyboard.nextLine();
			if (!this.isType(userInp, "double")) {
				System.err.println("Error: must be a number.");
				error = true;
			} else {
				error = false;
			}

		} while (error == true);
		return Double.parseDouble(userInp);
	}

	/**
	 * A method to repeatedly ask the user for input until 
	 * the input is valid. If condition is used, 
	 * input is measured against it.
	 * 
	 * @param informationText	The information text to prompt
	 * 							to the user.
	 * @return					Returns the final value of the accepted
	 * 							input, as a float.
	 */
	public float askInputFloat(String informationText) {
		Boolean error = false;
		String userInp = "";
		do {
			System.out.print(informationText);
			userInp = keyboard.nextLine();
			// validate:
			if (!this.isType(userInp, "float")) {
				System.err.println("Error: must be a number.");
				error = true;
			} else {
				error = false;
			}

		} while (error == true);
		return Float.parseFloat(userInp);
	}

	/**
	 * Tests if a specific input can be converted to a specific type.
	 * 
	 * @param input The input to test. Accepts String, int, double or float.
	 * @param type	Which type to test against. Accepts 'int','float' or 'double'.
	 * @return Boolean	True if can be transformed to requested type. False otherwise.
	 */
	public Boolean isType(String testStr, String type) {
		try {
			if (type.equalsIgnoreCase("float")) {
				Float.parseFloat(testStr);
			} else if (type.equalsIgnoreCase("int")) {
				Integer.parseInt(testStr);
			} else if (type.equalsIgnoreCase("double")) {
				Double.parseDouble(testStr);
			}
			return true;
		} catch(Exception e) {
			return false;
		}

	}

}

 

 

Tags: ,

Trackback from your site.