可以在运行@Validated之前修改@ModelAttribute。

问题描述 投票:1回答:2

是否可以在通过@Validated验证之前修改@ModelAttribute。

@RequestMapping(value = "/doSomething", method = RequestMethod.POST)
public final ModelAndView save(
        @Validated(value = {myGroup.class}) @ModelAttribute("myObject") MyObject myObject)

我需要在执行@Validated之前改变myObject的状态。

spring-mvc hibernate-validator
2个回答
1
投票

增加一个ModelAttribute populate方法呢?

@ModelAttribute("myObject")
public MyObject modifyBeforeValidate(
        @ModelAttribute("myObject") MyObject myObject) {
    //modify it here
    return myObject;
}

副作用是如果我没记错的话,这个方法会在每个@RequestMapping方法之前被调用。

更新1:示例

@ModelAttribute("command")
public ChangeOrderCommand fillinUser(
        @ModelAttribute("command") ChangeOrderCommand command,
        HttpServletRequest request) {
    command.setUser(securityGateway.getUserFrom(request));
    return command;
}

@RequestMapping(value = "/foo/bar", method = RequestMethod.POST)
public String change(@ModelAttribute("command") ChangeOrderCommand command,
        BindingResult bindingResult, Model model, Locale locale) {
}

0
投票

有2种方法可以在模型属性对象之前修改。@Validated 将触发。

  1. 移除 @Validated 和自动装配验证器,并手动触发验证器。
class MyController {

  private final Validator validator;

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

  @PostMapping("/doSomething")
  public final ModelAndView save(
        @ModelAttribute("myObject") MyObject myObject, BindingResult result) {
    // edit MyObject here

    validator.validate(myObject, result)

    // original method body here
}

  1. 装饰默认的验证器和预处理。myObject 对象内的装饰验证器。
class MyController {

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

@PostMapping("/doSomething")
  public final ModelAndView save(
        @Validated(value = {myGroup.class}) @ModelAttribute("myObject") MyObject myObject, BindingResult result) {
    ...
  } 

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

        public PreProcessMyObjectValidator(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 MyObject) {
                MyObject myObject = (MyObject) target;
                // manipulate myObject here

            }

            validator.validate(target, errors);
        }
    }

}

(这第二个小技巧是我从 https:/github.comspring-projectsspring-frameworkissues11103。)

© www.soinside.com 2019 - 2024. All rights reserved.