来源:cubacn
浏览 753
扫码
分享
2019-03-24 09:51:26
3.2.13.2. 运行时验证
- 在 UI 中验证
连接到数据源的通用 UI 组件获取 BeanValidator
实例来检查字段的值。验证器是从可视化组件实现的 Component.Validatable.validate()
方法调用的。如果验证不通过,会抛出 CompositeValidationException
异常,这个异常实例中包含了一组违规信息的集合。
可以移除标准的验证器,也可以使用不同的约束组初始化标准验证器:
@UiController("sample_NewScreen")
@UiDescriptor("new-screen.xml")
public class NewScreen extends Screen {
@Inject
private TextField<String> field1;
@Inject
private TextField<String> field2;
@Subscribe
protected void onInit(InitEvent event) {
field1.getValidators().stream()
.filter(BeanPropertyValidator.class::isInstance)
.forEach(field1::removeValidator); (1)
field2.getValidators().stream()
.filter(BeanPropertyValidator.class::isInstance)
.forEach(validator -> {
((BeanPropertyValidator) validator).setValidationGroups(new Class[] {UiComponentChecks.class}); (2)
});
}
}
1 | 从 UI 组件中完全删除 bean 验证。 |
2 | 这里,验证器将仅检查显式设置了 UiComponentChecks 组的约束,因为没有传递默认组。 |
默认情况下,BeanValidator
具有 Default
和 UiComponentChecks
分组。
如果实体属性带有 @NotNull
注解且没有定义约束组,则在元数据中这个属性会被标记为强制的(mandatory),并且通过数据源使用此属性的 UI 组件将具有 required = true
属性。
DateField和DatePicker组件使用 @Past
和 @Future
注解自动设置其 rangeStart
和 rangeEnd
属性,不过这里忽略了时间部分。
如果约束包含 UiCrossFieldChecks
组并且所有属性级别的检查都通过了,编辑界面将在提交时做类级别约束的验证。可以在 XML 描述或界面控制器使用 crossFieldValidate
属性关闭此验证:
<window xmlns="http://schemas.haulmont.com/cuba/window.xsd"
caption="msg://editorCaption"
class="com.company.demo.web.task.TaskEdit"
datasource="taskDs"
crossFieldValidate="false">
</window>
public class TaskEdit extends StandardEditor<Task> {
@Subscribe
protected void onInit(InitEvent event) {
setCrossFieldValidate(false);
}
}
- 中间件服务验证
如果服务接口中的方法带有 @Validated
注解,则中间件服务会对方法的参数和返回结果执行验证。例如:
public interface TaskService {
String NAME = "demo_TaskService";
@Validated
@NotNull
String completeTask(@Size(min = 5) String comment, @NotNull Task task);
}
@Validated
注解可以指定约束组以使验证应用到某组约束上,如果没有指定任何组,默认使用以下约束组:
-
Default
和 ServiceParametersChecks
- 进行方法参数验证时
-
Default
和 ServiceResultChecks
- 进行方法返回值验证时
在验证错误时会抛出 MethodParametersValidationException
和 MethodResultValidationException
异常。
如果要在服务中以编程的方式执行某些自定义验证,请使用 CustomValidationException
来通知客户端有关验证的错误信息,这样可以与标准 bean 验证错误信息保持相同的格式。此异常也可以跟 REST API 客户端有特定的关联。
- 在 REST API 中验证
对于创建和更新操作, 通常 REST API 会自动执行 bean 验证。验证错误会以如下方式返回给客户端:
-
MethodResultValidationException
和 ValidationException
导致 500 Server error
HTTP 状态
-
MethodParametersValidationException
、 ConstraintViolationException
和 CustomValidationException
导致 400 Bad request
HTTP 状态
-
格式为 Content-Type: application/json
的响应体将包含一个对象列表,每个对象都包含属性 message
、 messageTemplate
、 path
和 invalidValue
属,例如:
[
{
"message": "Invalid email: aaa",
"messageTemplate": "{msg://com.company.demo.entity/Customer.email.validationMsg}",
"path": "email",
"invalidValue": "aaa"
}
]
-
path
- 表示被验证对象的无效属性在对象关系图中的路径。
-
messageTemplate
- 消息模板字符串,这个模板字符串是在 message
注解属性中定义。
-
message
- 包含验证消息的实际值 。
-
invalidValue
- 属性值类型是 String
、 Date
、 Number
、 Enum
、 UUID
中的其中之一时才返回。
- 以编程的方式进行验证
可以使用 BeanValidation
基础设施接口以编程的方式执行验证。该接口可在中间件和客户端层使用。它用于获取执行验证的 javax.validation.Validator
实现。验证的结果是一组 ConstraintViolation
对象。例如:
@Inject
private BeanValidation beanValidation;
public void save(Foo foo) {
Validator validator = beanValidation.getValidator();
Set<ConstraintViolation<Foo>> violations = validator.validate(foo);
}