以上第一种方式,将校验方法定义在实体内是最简单的方式;随着webflow会话的执行, view-state节点提交的动作将会自动触发实体定义的校验逻辑(即对对应页面表单项的该实体中的属性值进行统一验证)。至于具体实现方式如下: 在实体bean内创建名为 validate${state}的方法,state即等待表单校验的 view-state节点的ID,比如 在flow配置文件中有如下节点配置
flow执行到此页面节点时,会将模型 booking 与该页面表单绑定,booking的属性和表单项name必然对应,当触发 _eventId=proceed时,如果在booking中存在符合上面第一种校验的方法,flow则自动调用该方法进行表单验证,方法定义如下:
public class Booking { private Date checkinDate; private Date checkoutDate; ... public void validateEnterBookingDetails(ValidationContext context) { MessageContext messages = context.getMessageContext(); if (checkinDate.before(today())) { messages.addMessage(new MessageBuilder().error().source("checkinDate"). defaultText("Check in date must be a future date").build()); } else if (!checkinDate.before(checkoutDate)) { messages.addMessage(new MessageBuilder().error().source("checkoutDate"). defaultText("Check out date must be later than check in date").build()); } } }
类推,那么有多个视图节点需要做校验的时候就在该booking 添加多个校验方法。
校验的第二种途径,是有别于实体单独创建一个校验器,具体做法为创建一个名为 ${model}Validator的class,比如bookingValidator,然后定义一个名为 validate${state}的公共方法,比如validateEnterBookingDetails(EnterBookingDetails即上面的view-state ID)
@Component public class BookingValidator { public void validateEnterBookingDetails(Booking booking, ValidationContext context) { MessageContext messages = context.getMessageContext(); if (booking.getCheckinDate().before(today())) { messages.addMessage(new MessageBuilder().error().source("checkinDate"). defaultText("Check in date must be a future date").build()); } else if (!booking.getCheckinDate().before(booking.getCheckoutDate())) { messages.addMessage(new MessageBuilder().error().source("checkoutDate"). defaultText("Check out date must be later than check in date").build()); } } }
创建完这样的class,记得交给spring管理,实例beanId按标准命名就好了。