Spring Webflow:能否为每个流手动设置验证器?

Spring Webflow: Can Validators Be Manually Set Per Flow?

我在我的应用程序中配置了多个流:

<flow:flow-registry id="flowRegistry" flow-builder-services="flowBuilderServices" >
    <flow:flow-location id="reservation1"   path="/WEB-INF/flows/flow1.xml" />
    <flow:flow-location id="reservation2"   path="/WEB-INF/flows/flow2.xml" />
</flow:flow-registry>

这两个流使用单独的 classes 作为它们的模型属性,将它们称为 Flow1DTO.java 和 Flow2DTO.java。但是,他们使用一组通用的 JSPs/Tiles 作为他们的实际界面。

<form:form modelAttribute="reservationForm">
   <!-- etc -->
</form:form>

是否可以为每个流定义一个单独的验证器class?

您可以为每个特定视图状态 ID 的同一模型 class 定义多种验证方法。每个自定义验证方法映射到特定的 webflow 视图状态 ID。

您的模型验证器 class 名称需要使用名称“${model}Validator”(并具有 @Component 注释)定义,并且每个验证方法名称都需要这样命名 "validate${state} ([ModelClassType] model, ValidationContext context)"

所以假设您有一个名为 "Reservation.java" 的模型 class 和 2 个使用该模型的不同流定义,并且每个流定义都具有

的视图状态定义
<!-- defined in your first flow file -->
<view-state id="ReservationSameDayViewState" view="sumting" model="reservationForm">
</view-state>
....
<!-- defined in your 2nd flow file -->
<view-state id="ReservationFutureViewState" view="sumting" model="reservationForm">
</view-state>

预订模型的验证器 class 想要这样:

@Component
public class ReservationValidator {
    public void validateReservationSameDayViewState(Reservation reservation, ValidationContext context) {
         // perform custom validation for first flow
    }

    public void validateReservationFutureViewState(Reservation reservation, ValidationContext context) {
         // perform custom validation for 2nd flow
    }
}

http://docs.spring.io/autorepo/docs/webflow/2.4.x/reference/html/views.html#view-validation-programmatic-validator

此外,用整数增量定义流是不好的做法。将您的流程注册表定义更改为如下所示。这样您就不必在每次创建新流时都手动向其中添加流。

<flow:flow-registry id="flowRegistry" flow-builder-services="flowBuilderServices" base-path="/WEB-INF/flows">
    <flow-location-pattern value="/**/*-flow.xml" />
</flow:flow-registry>

注意:流程名称以“-flow.xml”结尾。这是定义流注册表和流名称的非官方标准方法。

我找到了一个解决方案,它允许我使用表单验证器的单个实现来验证多个表单。

代码看起来像这样:

public void validateMethodName(Flow1DTO dto, ValidationContext context) {
    valMethodName(dto, context);
}

public void validateMethodName(Flow2DTO dto, ValidationContext context) {
    valMethodName(dto, context);
}

private void valMethodName(CommonFlowDTO dto, ValidationContext context) {
    // do stuff
}

将验证方法放入 DTO classes 本身不是一种选择。验证需要调用数据库,这会将 DTO 对象耦合到业务逻辑并使 DTO 的创建稍微复杂一些。

我发现验证方法无法指定接口,导致每个具体 DTO 的方法重复 class。