1. Overview
1.概述
One of the features of Java JSR 380 is allowing expressions while interpolating the validation messages with parameters.
Java JSR 380的特点之一是允许表达式,同时用参数来插值验证信息。
When we use Hibernate Validator, there is a requirement that we need to add one of the uniform implementations of Java JSR 341 as a dependency to our project. JSR 341 is also called the Expression Language API.
当我们使用Hibernate验证器时,有一个要求,我们需要将Java JSR 341的统一实现之一作为依赖项添加到我们的项目中。 JSR 341也被称为表达式语言API。
However, adding an extra library can be cumbersome if we don’t need to support parsing expressions according to our use-case.
然而,如果我们不需要根据我们的使用情况来支持解析表达式,那么增加一个额外的库就会很麻烦。
In this short tutorial, we’ll have a look at how to configure ParameterMessageInterpolator in Hibernate Validator.
在这个简短的教程中,我们将看看如何在Hibernate Validator中配置ParameterMessageInterpolator。
2. Message Interpolators
2.信息插值器
Beyond the basics of validating a Java bean, the Bean Validation API’s MessageInterpolator is an abstraction that gives us a way of performing simple interpolations without the hassle of parsing expressions.
除了验证Java Bean的基础知识之外,Bean Validation API的MessageInterpolator是一个抽象,它为我们提供了一种执行简单插值的方法,而无需解析表达式的麻烦。
Besides, Hibernate Validator offers a non-expression based ParameterMessageInterpolator, and therefore, we don’t need any extra libraries to configure it.
此外,Hibernate Validator提供了一个非表达式的ParameterMessageInterpolator,因此,我们不需要任何额外的库来配置它。
3. Setting up Custom Message Interpolators
3.设置自定义信息插值器
To remove the expression language dependency, we can use custom message interpolators and configure Hibernate Validator without expression support.
为了消除对表达式语言的依赖,我们可以使用自定义的消息插值器,并配置不支持表达式的Hibernate验证器。
Let’s show some of the convenient ways of setting up custom message interpolators. We’ll use the built-in ParameterMessageInterpolator in our case.
让我们展示一些设置自定义消息插值器的方便方法。在我们的案例中,我们将使用内置的ParameterMessageInterpolator。
3.1. Configuring ValidatorFactory
3.1.配置ValidatorFactory
One way of setting up a custom message interpolator is to configure ValidatorFactory when bootstrapping.
设置自定义消息插值器的一种方法是在启动时配置ValidatorFactory。
Thus, we can build a ValidatorFactory instance with ParameterMessageInterpolator:
因此,我们可以用ParameterMessageInterpolator构建一个ValidatorFactory实例。
ValidatorFactory validatorFactory = Validation.byDefaultProvider()
.configure()
.messageInterpolator(new ParameterMessageInterpolator())
.buildValidatorFactory();
3.2. Configuring Validator
3.2.配置Validator
Similarly, we can set ParameterMessageInterpolator when we initialize the Validator instance:
同样地,我们可以在初始化Validator实例时设置ParameterMessageInterpolator。
Validator validator = validatorFactory.usingContext()
.messageInterpolator(new ParameterMessageInterpolator())
.getValidator();
4. Performing Validations
4.执行验证
To see how ParameterMessageInterpolator works, we need a sample Java bean with some JSR 380 annotations on it.
为了了解ParameterMessageInterpolator如何工作,我们需要一个带有一些JSR 380注解的Java Bean样本。
4.1. Sample Java Bean
4.1.示例Java Bean
Let’s define our sample Java bean Person:
让我们来定义我们的示例Java Bean Person。
public class Person {
@Size(min = 10, max = 100, message = "Name should be between {min} and {max} characters")
private String name;
@Min(value = 18, message = "Age should not be less than {value}")
private int age;
@Email(message = "Email address should be in a correct format: ${validatedValue}")
private String email;
// standard getters and setters
}
4.2. Testing Message Parameters
4.2.测试消息参数
Certainly, to perform our validations, we should use a Validator instance accessed from ValidatorFactory, which we already configured before.
当然,为了执行我们的验证,我们应该使用一个从ValidatorFactory访问的Validator实例,我们之前已经配置了.。
So, we need to access our Validator:
因此,我们需要访问我们的Validator。
Validator validator = validatorFactory.getValidator();
After that, we can write our test method for the name field:
之后,我们可以为name字段编写我们的测试方法。
@Test
public void givenNameLengthLessThanMin_whenValidate_thenValidationFails() {
Person person = new Person();
person.setName("John Doe");
person.setAge(18);
Set<ConstraintViolation<Person>> violations = validator.validate(person);
assertEquals(1, violations.size());
ConstraintViolation<Person> violation = violations.iterator().next();
assertEquals("Name should be between 10 and 100 characters", violation.getMessage());
}
The validation message is interpolated with variables of {min} and {max} correctly:
验证信息是用{min}和{max}的变量正确插值。
Name should be between 10 and 100 characters
Next, let’s write a similar test for the age field:
接下来,让我们为年龄字段写一个类似的测试。
@Test
public void givenAgeIsLessThanMin_whenValidate_thenValidationFails() {
Person person = new Person();
person.setName("John Stephaner Doe");
person.setAge(16);
Set<ConstraintViolation<Person>> violations = validator.validate(person);
assertEquals(1, violations.size());
ConstraintViolation<Person> violation = violations.iterator().next();
assertEquals("Age should not be less than 18", violation.getMessage());
}
Similarly, the validation message is interpolated correctly with the variable {value} as we expected:
同样,验证信息也如我们所期望的那样,用变量{value}正确插值。
Age should not be less than 18
4.3. Testing Expressions
4.3.测试表达式
To see how ParameterMessageInterpolator behaves with expressions, let’s write another test for the email field that involves a simple ${validatedValue} expression:
为了了解ParameterMessageInterpolator在表达式中的表现,让我们为email字段编写另一个测试,它涉及一个简单的${validatedValue}表达式。
@Test
public void givenEmailIsMalformed_whenValidate_thenValidationFails() {
Person person = new Person();
person.setName("John Stephaner Doe");
person.setAge(18);
person.setEmail("johndoe.dev");
Set<ConstraintViolation<Person>> violations = validator.validate(person);
assertEquals(1, violations.size());
ConstraintViolation<Person> violation = violations.iterator().next();
assertEquals("Email address should be in a correct format: ${validatedValue}", violation.getMessage());
}
This time, the expression ${validatedValue} is not interpolated.
这一次,表达式${validatedValue}没有被插值。
ParameterMessageInterpolator only supports the interpolation of parameters, not parsing expressions that use the $ notation. Instead, it simply returns them un-interpolated.
ParameterMessageInterpolator只支持参数的插值,不支持使用$符号的表达式的解析。相反,它只是返回未插值的参数。
5. Conclusion
5.总结
In this article, we learned what ParameterMessageInterpolator is for and how to configure it in Hibernate Validator.
在这篇文章中,我们了解了ParameterMessageInterpolator的作用以及如何在Hibernate Validator中配置它。
As always, all the examples involved in this tutorial are available over on GitHub.
一如既往,本教程中涉及的所有例子都可以在GitHub上找到。