Home > Net >  Is there a Java bean validation to accept only numbers?
Is there a Java bean validation to accept only numbers?

Time:12-24

This is my Java class for accepting the request body.

public class ItemForReorderRequest {
    private String itemNo;
    @DecimalMax(value = "100", message = "Reorder quantity must be less than or equal to 100")
    private Double quantity;
}

This is the request body.

{
        "itemNo": "000006510",
        "quantity": 100.0
}

I need to validate the quantity to accept only numeric inputs. Whenever I enter a string to quantity, it gives me "An unexpected application error has occurred" with multiple errors including "className": "com.fasterxml.jackson.core.JsonParser".

CodePudding user response:

You can use @Digits - here is a tutorial

@Digits(integer = 3, fraction = 2, message = "Quantity must be a valid number with a maximum of 3 integral digits and 2 fractional digits")
private Double quantity;

But @Digits only works for numeric values!

Another point to concider is that if you want to treat 1.0 as a Double an 1 as an Integer, you need to work with the input variable, which is of type String.

Java will always treat Double x = 1 in the same way as Double y = 1.0 (meaning 1 is a valid Double), so you will not be able to distinguish them with code.

Alternatively, you can use the good old regular expressions!

@Pattern(regexp = "^[0-9] (\\.[0-9] )?$", message = "Quantity must be a numeric value")

This regEx will match any string that consists of one or more digits, optionally followed by a decimal point and one or more digits. It will reject any non-numeric characters.

CodePudding user response:

You could validate the input by using Apache Commons' NumberUtils (https://commons.apache.org/proper/commons-lang/apidocs/org/apache/commons/lang3/math/NumberUtils.html)

NumberUtils provides a bunch of useful methods to check if a String is a valid Java number, a parsable value, unicode digit and so on.


This approach provides a static method called NumberUtils.isCreatable(String), which checks whether a String is a valid Java number or not.

The aforementioned method accepts:

  • Hexadecimal numbers starting with 0x or 0X
  • Octal numbers starting with a leading 0
  • Scientific notation (for example 1.05e-10)
  • Numbers marked with a type qualifier (for example 1L or 2.2d)

Null and empty/blank inputs are not considered numbers and therefore the method will return false.


The NumberUtils.isParsable(String) method checks whether the given String is parsable or not.

Parsable numbers are those that are successfully parsed by any parse method such as Integer.parseInt(String), Long.parseLong(String), Float.parseFloat(String) or Double.parseDouble(String).

Unlike NumberUtils.isCreatable(), this method will not accept hexadecimal numbers, scientific notations, or strings ending with any type of qualifier like 'f', 'F', ‘d' ,'D' ,'l' or 'L'.


The method StringUtils.isNumeric(CharSequence) checks for Unicode digits, meaning:

Any digits from any language that is a Unicode digit is acceptable. Since a decimal point is not considered as a Unicode digit, it's not valid Leading signs (either positive or negative) are also not acceptable.


StringUtils.isNumericSpace(CharSequence) checks strictly for Unicode digits and/or space. This is the same as StringUtils.isNumeric(), except that it also accepts spaces, and not only leading and/or trailing spaces, but also if they're in between numbers.


You can also use Regular Expressions (although most people would not recommend it unless it's really needed). Here's a simple example:

Use the Regular Expression -?\d (.\d )? to match numeric Strings consisting of the positive or negative integer and floats.

RegEx breakdown:

  • -? – identifies if the given number is negative, the dash "-" literally searches for dash and the question mark "?" makes it optional.
  • \d – this searches for one or more digits.
  • (.\d )? – identifies float numbers. It looks for one or more digits followed by a period. The question mark, in the end, means that this group is optional.

A method example:

private Pattern pattern = Pattern.compile("-?\\d (\\.\\d )?");

public boolean isNumeric(String input) {
    if (input == null) {
        return false; 
    }
    return pattern.matcher(input).matches();
}

CodePudding user response:

In general, unless I am performing math on the value, I store all values (including numbers) as Strings in my JSON objects.

I would define your class as follows (getter and setter are lombok annotations):

@Getter
@Setter
public class ItemForReorderRequest {
    private String itemNumber;
    private String quantity;
}


ItemForReorderRequest blam; // used below.

Note: "No" is a terrible abbreviation for number. If you must abbreviate, consider "Num".

I would perform validation after I received the JSON.

I like Apache utility classes, so I would likely use NumberUtils.isParsable(blam.getQuantity())

  • Related