Groups allow you to restrict the set of constraints applied during validation.
In the following example, the AClass
class has the bool
attribute that belongs to the AGroup
group. But when the group of an attribute is not specified, which is the case of the other attributes of AClass
, then it belongs to the default group javax.validation.groups.Default
.
import javax.validation.constraints.AssertTrue;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotBlank;
public class AClass {
@NotBlank
private String string;
@Min(2)
private int integer;
@AssertTrue(groups = AGroup.class)
private boolean bool;
public AClass(String string, int integer, boolean bool) {
this.string = string;
this.integer = integer;
this.bool = bool;
}
}
A group declaration can be a simple empty interface.
public interface AGroup { }
In the following program, the validate
method validates all attributes that belong to the default group. But to validate attributes of other groups, you must specify in the validate
method which group of attributes will be validated.
import java.util.Set;
import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import org.junit.Assert;
public class Program {
public static void main(String[] args) {
Validator validator = Validation.buildDefaultValidatorFactory().getValidator();
// create a AClass and check that everything is ok with it.
AClass a = new AClass("Foo", 2, false);
Set<ConstraintViolation<AClass>> constraintViolations = validator.validate(a);
Assert.assertEquals(0, constraintViolations.size());
// but has it passed the bool field?
constraintViolations = validator.validate(a, AGroup.class);
Assert.assertEquals(1, constraintViolations.size());
Assert.assertEquals("must be true", constraintViolations.iterator().next().getMessage()
);
}
}
Source: https://docs.jboss.org/hibernate/validator/5.2/reference/en-US/html/ch05.html#example-driver
Payloads can be used by clients of the Bean Validation API to assign custom payload objects to a constraint. This attribute is not used by the API itself.
In the following example, the TestBean
class has an attribute with Payload
.
import javax.validation.constraints.NotNull;
public class TestBean {
@NotNull(payload = {ErrorEmailSender.class})
private String str;
public String getStr() {
return str;
}
public void setStr(String str) {
this.str = str;
}
}
Implementation of ErrorEmailSender
Payload:
import javax.validation.ConstraintViolation;
import javax.validation.Payload;
public class ErrorEmailSender implements Payload {
public void onError(ConstraintViolation violation) {
System.out.println("Sending email to support team: "
+ violation.getPropertyPath() + " "
+ violation.getMessage());
}
}
The Client
program checks whether a TestBean
instance is valid, and if not, it calls the Payload
of invalid attributes.
import java.util.Set;
import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
public class Client {
public static void main(String[] args) {
Validator validator = Validation.buildDefaultValidatorFactory().getValidator();
TestBean bean = new TestBean();
Set<ConstraintViolation<TestBean>> constraintViolations = validator.validate(bean);
if (constraintViolations.size() > 0) {
constraintViolations.stream().forEach(Client::processError);
} else {
//proceed using user object
System.out.println(bean);
}
}
private static void processError(ConstraintViolation<TestBean> violation) {
violation.getConstraintDescriptor().getPayload().forEach(p -> {
if (ErrorEmailSender.class.isAssignableFrom(p)) {
try {
((ErrorEmailSender) p.getDeclaredConstructor().newInstance()).onError(violation);
} catch (Exception ex) {
System.out.println(ex);
}
}
});
}
}
You should see in the output:
Sending email to support team: str must not be null
Sources: