应用@valid之前的spring mvc进程对象

时间:2013-02-06 15:26:31

标签: spring bean-validation hibernate-validator

我有一个像以下

的弹簧mvc控制器
@RequestMapping(value="/new", method=RequestMethod.POST)
public String createBooking(@Valid Booking booking, BindingResult bindingResult, Model model, Principal principal)
{
    if(bindingResult.hasErrors()) {
        return "booking/edit";
    }
    //Store Booking in db...
    ...

问题是我从POST获得的Booking对象是由Spring构造的,但是无法填充验证器所需的其中一个属性,因为该属性不在表单中。所以我的问题是,在@Valid标签处理程序处理之前,我是否有办法拦截预订以添加此必需属性?

干杯! NFV

2 个答案:

答案 0 :(得分:0)

我不确定我是否理解这个问题,但听起来您希望在命令由表单提交绑定之前将命令对象中的字段设置为值。如果是这样,您可以在控制器中添加一个方法,如下所示......

@ModelAttribute
public Booking getBooking() {
    Booking booking = new Booking();
    booking.setMyRequiredProperty("some value");
    return booking;
}

希望有所帮助

答案 1 :(得分:0)

有两种方法可以在@Valid触发之前修改模型属性对象:

  1. 删除@Valid并自动连接验证器并手动触发验证器:
class MyController {

  private final Validator validator;

  class MyController(Validator validator) {
    this.validator = validator;
  }

  @PostMapping("/new")
  public String createBooking(Booking booking, BindingResult bindingResult, Model model, Principal principal) {
    // edit booking here

    validator.validate(booking, result)

    // original method body here
  }
}

  1. 装饰默认的验证器并预处理装饰的验证器中的booking对象。
class MyController {

  @InitBinder
  public void initBinder(WebDataBinder binder) {
      binder.setValidator(new PreProcessBookingValidator(binder.getValidator()));
  }

  @PostMapping("/new")
  public String createBooking(@Valid Booking booking, BindingResult bindingResult, Model model, Principal principal) {
    ...
  }

  private static class PreProcessBookingValidator implements Validator {
        private final Validator validator;

        public PreProcessBookingValidator(Validator validator) {
            this.validator = validator;
        }

        @Override
        public boolean supports(@Nonnull Class<?> clazz) {
            return validator.supports(clazz);
        }

        @Override
        public void validate(@Nonnull Object target, @Nonnull Errors errors) {
            if (target instanceof Booking) {
                Booking booking = (Booking) target;
                // manipulate booking here

            }

            validator.validate(target, errors);
        }
    }

}

(第二个技巧是我从https://github.com/spring-projects/spring-framework/issues/11103中学到的)