JBVE (Java Bean Validation Extension) is a small utils library that extends the Java Bean Validation Specification with additional @Annotations.
If you are not familiar with JSR-380 (or the Java Bean Validation Specification) please follow this nice tutorial first.
If you want to see JVBExt at work please:
- read this blog article;
- check out this repository.
For versions (>=0.0.12
):
<dependency>
<groupId>net.andreinc</groupId>
<artifactId>jbve</artifactId>
<version>0.0.12</version>
</dependency>
Important note(s):
In the runtime environment you will an existing JSR-380 implementation in the classpath. Spring Boot started web comes by default with Hibernate Validator.
If you are using the library in another environment that doesn't provide a JSR-380 implementation you will need to add the following as dependencies:
compile group: 'org.hibernate', name: 'hibernate-validator', version: '6.0.2.Final'
compile group: 'org.glassfish', name: 'javax.el', version: '3.0.1-b08'
Java Bean Validation Extension was downloaded +/-450 times since October, 2017.
If you are using jbvext in your cool projects please send me a note so I can include you in this list.
@Annotation | Supported Types | Description |
---|---|---|
@After |
Date |
Check if the Date is after the given date value, with date format as parameter. |
@Alpha |
String |
Checks if the String contains only unicode letters. |
@Alphanumeric |
String |
Checks if the String contains unly unicode letters or digits |
@AlphanumericSpace |
String |
Checks if the String contains only unicode letters, digits, empty strings or spaces. |
@AlphaSpace |
String |
Checks if the String contains only Unicode letters and space " " . |
@AsciiPrintable |
String |
Checks if the String contains only ASCII printable characters. |
@Blank |
String |
Checks if the String is empty "" , null or whitespace(s) " " only. |
@Before |
Date |
Check if the Date is before the given date value, with date format as parameter. |
@CC |
String |
Checks if the String is a valid credit card number. |
@EndsWith |
String |
Checks if the Strings ends with a specified suffix(es). |
@InstanceOf |
Object |
Check if the Object is an instanceof of (at least one of) the supplied value(s). |
@IPv4 |
String |
Checks if the String is a valid IPv4 address. |
@IPv6 |
String |
Checks if the String is a valid IPv6 address. |
@IsDate |
String |
Check if the String is in a date format. |
@LowerCase |
String |
Checks if the String contains only lowercase letters. |
@MinDigits |
Double |
Checks whether the annotated value is higher than or equal to the specified minimum. |
@MaxDigits |
Double |
Checks whether the annotated value is less than or equal to the specified maximum. |
@NotInstanceOf |
Object |
Check if the is not an instanceof of (all the) the supplied value(s). |
@Numeric |
String |
Checks if the String contains only unicode digits. Note: A decimal point is not considered a digit and the validation fails. Use @Parseable instead for more advanced validations. |
@OneOfChars |
Character |
Checks if the Character is contained in a given array (char[] ) of values. |
@OneOfDoubles |
Double |
Check if the Double is contained in a given array (double[] ) of values. |
@OneOfIntegers |
Integer |
Check if the Integer is contained in a given array (int[] ) of values. |
@OneOfLongs |
Long |
Check if the Long is contained in a given array (long[] ) of values. |
@OneOfStrings |
String |
Checks if the String is contained in a given array (String[] ) of values. |
@Parseable |
String |
Checks if the String can be parsed to a number (Short , Integer , Long , Double , etc.). |
@Password |
String |
Checks if the String is a valid password. |
@StartsWith |
String |
Checks if the String starts with the specified prefix(es). |
@UpperCase |
String |
Checks if the String contains only uppercase letters. |
Note:
All the examples are using project's lombok annotations like @Data
, @NoArgsConstructor
, @AllArgsConstructor
, etc.
Those annotations are used make the examples more compact, but their use is optional.
Check if the Date is after the given date value.
The annotation supports a second property format that by default is "yyyy-MM-dd'T'HH:mm:ss.SSSZ".
@Data
class AfterBean {
@After(value = "2018-01-01", format = "yyyy-MM-dd")
private Date isAfter = new Date(1522399999911L); // Passes // Date = 2018-03-30
}
Check if the String contains only unicode letters.
Behavior:
Value | Result |
---|---|
null |
❌ Fails |
"" |
❌ Fails |
" " |
❌ Fails |
"abc" |
✅ Passes |
"ab2c" |
❌ Fails |
"ab-c" |
❌ Fails |
@Data
class TestAlpha {
@Alpha
private String alpha = "abc";
@Alpha /** Will fail */
private String nonAlpha = "pr�s-*";
}
Checks if the String contains only unicode letters or digits.
Behavior:
Value | Result |
---|---|
null |
❌ Fails |
"" |
❌ Fails |
" " |
❌ Fails |
"abc" |
✅ Passes |
"ab c" |
❌ Fails |
"ab2c" |
✅ Passes |
"ab-c" |
❌ Fails |
Checks if the String contains only unicode letters, digits, empty strings or spaces.
Behavior:
Value | Result |
---|---|
null |
❌ Fails |
"" |
✅ Passes |
" " |
✅ Passes |
"abc" |
✅ Passes |
"ab c" |
✅ Passes |
"ab2c" |
✅ Passes |
"ab-c" |
❌ Fails |
Checks if the String contains only Unicode letters and space (" ").
Behavior:
Value | Result |
---|---|
null |
❌ Fails |
"" |
✅ Passes |
" " |
✅ Passes |
"abc" |
✅ Passes |
"ab c" |
✅ Passes |
"ab1c" |
❌ Fails |
"ab-c" |
❌ Fails |
Checks if the String is printable (ASCII printable characters).
Behavior:
Value | Result |
---|---|
null |
❌ Fails |
"" |
✅ Passes |
" " |
✅ Passes |
"\u0020" |
✅ Passes |
"\u007e" |
❌ Fails |
"G\u00fclc\u00fc" |
❌ Fails |
Check if the Date is before the given date value.
The annotation supports a second property format that by default is "yyyy-MM-dd'T'HH:mm:ss.SSSZ".
@Data
class BeforeBean {
@Before(value = "2018-12-01", format = "yyyy-MM-dd")
private Date isBefore = new Date(1522399999911L); // Passes // Date = 2018-03-30
}
Checks if the String is empty ""
, null or whitespace(s) " "
only.
Behavior:
Value | Result |
---|---|
null |
✅ Passes |
"" |
✅ Passes |
" " |
✅ Passes |
"abc" |
❌ Fails |
" abc " |
❌ Fails |
Checks if the String is a valid credit card number. Supported types are defined in the CreditCardType
enum:
- AMEX:
- DINERS;
- DISCOVER;
- MASTERCARD;
- VISA;
- VPAY;
- ALL.
Multiple credit card types can be supplied to the @CC
annotation.
@Data
class Account {
@CC({ AMEX, VISA }) // AMEX or VISA
private String ccNumber;
}
Multiple credit card types can be used.
Checks if the String endsWith
a list of given suffix(es). If multiple suffixes are supplied, the relationship between them is OR
(eg.: endsWith(prefix1) OR endsWith(prefix2) OR ...).
The annotation supports a second property ignoreCase
that by default is false
.
Behavior (ignoreCase==false
):
Value | Suffix | Result |
---|---|---|
null |
"abc" | ❌ Fails |
"abcdef" |
"def" |
✅ Passes |
"ABCDEF" |
"def" |
❌ Fails |
"ABCDEF" |
"" |
✅ Passes |
Behavior (ignoreCase==true
)
Value | Suffix | Result |
---|---|---|
null |
"abc" | ❌ Fails |
"abcdef" |
"def" |
✅ Passes |
"ABCDEF" |
"def" |
✅ Passes |
"ABCDEF" |
"" |
✅ Passes |
@Data
@AllArgsConstructor
@NoArgsConstructor
class SomeStrings {
private List<@EndsWith({"1", "2"}) String> someStrings;
}
In the above example we validate all the contents of someStrings
so that they end with either 1
or 2
.
Tests if an object is instance of the supplied classes.
@Data class Animal {}
@Data class Dog extends Animal {}
@Data class Cat extends Animal {}
@Data class Horse extends Animal {}
@Data
@AllArgsConstructor
class Pets {
/** This should contain only Cats and Dogs as pets, and doesn't contain null */
List<@NotNull @InstanceOf({Dog.class, Cat.class}) Animal> pets;
}
In order to test the above code we need something like this:
Animal aDog = new Dog();
Animal aCat = new Cat();
Pets pets = new Pets(asList(aDog, aCat));
ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
Validator validator = factory.getValidator();
Set<ConstraintViolation<Pets>> validations = validator.validate(pets);
// Should return 0 because the Pets class doesn't have any validation issues.
System.out.println(validations.size());
Checks if the given string is a valid IPv4 address.
This is implemented using InetAddressValidator.class
from Apache Common Validator.
Checks if the given string is a valid IPv6 address.
This is implemented using InetAddressValidator.class
from Apache Common Validator.
Checks if the given string is formatted as a date.
@Data
class IsDateBean {
@IsDate("yyyy-MM-dd")
private String isDate = "2018-12-01"; // Passes
}
Checks if the String contains only lowercase letters.
Behavior:
Value | Result |
---|---|
null |
❌ Fails |
"" |
❌ Fails |
" " |
❌ Fails |
"abc" |
✅ Passes |
"abC" |
❌ Fails |
"ab c" |
❌ Fails |
"ab1c" |
❌ Fails |
"ab-c" |
❌ Fails |
Checks whether the annotated value is higher than or equal to the specified minimum.
@Data
class MinDigitsDoubleBean {
@MinDigits(value = "10.5")
private Double isOk = new Double(11.0); // Passes
@MinDigits(value = "10.5")
private Double isKo = new Double(10.0); // Do not Pass
}
Double
TODO Add support for more types
Checks whether the annotated value is less than or equal to the specified maximum.
@Data
class MaxDigitsDoubleBean {
@MaxDigits(value = "10.5")
private Double isKo = new Double(11.0); // Do not Pass
@MaxDigits(value = "10.5")
private Double isOk = new Double(10.0); // Passes
}
Double
TODO Add support for more types
Test if an object is not an instance of any of the supplied classes.
@Data class Animal {}
@Data class Dog extends Animal {}
@Data class Cat extends Animal {}
@Data class Horse extends Animal {}
@Data
@AllArgsConstructor
class Horses {
/** This should contain only horses and doesn't contain NULL */
List<@NotNull @NotInstanceOf({Dog.class, Cat.class}) Animal> horses;
}
Checks if a String contains only Unicode digits. A decimal point is not an unicode digit and thus, the validation fails.
Behavior:
Value | Result |
---|---|
null |
❌ Fails |
"" |
❌ Fails |
" " |
❌ Fails |
"123" |
✅ Passes |
"\u0967\u0968\u0969" |
✅ Passes |
"12 3" |
❌ Fails |
"12a3" |
❌ Fails |
"12-3" |
❌ Fails |
Check if the String can be parsed to a number. The annotations accepts the type of parsing you want to perform as an input parameter.
For example if you want to parse it Integer
, @Parseable(TO_INT) should be used.
All the possible parsing strategies accepted are described in the enum ParseableType
. It currently supports:
TO_SHORT
TO_INT
TO_LONG
TO_FLOAT
TO_DOUBLE
Check if a String
is a valid password - matching a set of constraints.
containsUpperCase() default true
- Needs to contain at least an Uppercase letter;boolean containsLowerCase() default true
- Needs to contain at least a Lowercase letter;boolean containsSpecialChar() default true
- Needs to contain at least one special character;boolean containsDigits() default true
- Needs to contain at least one digit;boolean allowSpace() default false
- Password can contain spaces;int minSize() default 8
- The min size of the password;int maxSize() default 32
- The maximum size of the password;
Checks if the Character
is contained in a given array (char[]
) of values.
In the following example we test if the field aOrBOrC
is either 'a'
, 'b'
or 'c'
.
@Data
class {
@OneOfChars({'a', 'b', 'c'})
private Character aOrBOrC;
}
Check if the Double is contained in a given array (double[]
) of values.
In the following example we test if the field value
is either 1.0
or 2.0
.
@Data
class {
@OneOfDoubles({1.0, 2.0})
private Double value;
}
Check if the Integer is contained in a given array (int[]
) of values.
In the following example we test if the field value
is either 1
or 2
.
@Data
class {
@OneOfIntegers({1, 2})
private Integer value;
}
Check if the Long is contained in a given array (long[]
) of values.
Checks if the String is contained in a given array (String[]
) of values.
In the following example we check if the value returned by the getValue()
getter is either "A"
, "B"
or "C"
.
class Test {
@OneOfStrings({ "A" , "B", "C"})
private String getValue() { return /***/ }
}
Checks if a String starts with the specified prefix(es).
The annotation supports a second property ignoreCase
that by default is false
.
Behavior (ignoreCase==false
):
Value | Prefix | Result |
---|---|---|
null |
"abc" | ❌ Fails |
"abcdef" |
"abc" |
✅ Passes |
"ABCDEF" |
"abc" |
❌ Fails |
"ABCDEF" |
"" |
✅ Passes |
Behavior (ignoreCase==true
):
Value | Prefix | Result |
---|---|---|
null |
"abc" | ❌ Fails |
"abcdef" |
"abc" |
✅ Passes |
"ABCDEF" |
"abc" |
✅ Passes |
"ABCDEF" |
"" |
✅ Passes |
@Data
class Starters {
private List< @StartsWith("1", "2") String> starts;
}
Checks if the String contains only uppercase letters.
Behavior:
Value | Result |
---|---|
null |
❌ Fails |
"" |
❌ Fails |
" " |
❌ Fails |
"ABC" |
✅ Passes |
"aBC" |
❌ Fails |
"A C" |
❌ Fails |
"1AB" |
❌ Fails |
"A-C" |
❌ Fails |