为什么控制器需要在绑定错误上添加模型

时间:2018-12-06 07:26:48

标签: java spring spring-boot thymeleaf

在用户注册期间的Spring-Boot控制器中,如果出现绑定错误,我的控制器会将用户返回到注册页面,但是在我的实现中,该模型似乎丢失了。

例如,我通常在tutorials上看到

    @PostMapping
public String registerUserAccount(@ModelAttribute("user") @Valid UserRegistrationDto userDto, 
                                  BindingResult result){

    User existing = userService.findByEmail(userDto.getEmail());
    if (existing != null){
        result.rejectValue("email", null, "There is already an account registered with that email");
    }

    if (result.hasErrors()){
        return "registration";
    }

    userService.save(userDto);
    return "redirect:/registration?success";
}

如果存在绑定错误,则返回“注册”

我的控制器非常相似:

    @PostMapping("/user/register")
public String registerNewUser(@ModelAttribute("user") @Valid RegisterUserDTO registerUserDTO,
                              BindingResult bindingResult,
                              Model model,
                              HttpServletRequest request,
                              Errors errors) {
    User existing = userService.findUserByEmail(registerUserDTO.getEmail());
    if (existing != null) {
        bindingResult.rejectValue("email", null, "There is already an account with that Email");
    }
    if (bindingResult.hasErrors()) {
        return "register";
    }
    userService.createUser(registerUserDTO);
    return "redirect:/registration?success";
 }
}

但是,当我返回“ register”时,堆栈上的绑定错误出现在与我有关该对象的第一个百里香标签相对应的位置。

如果我更改POST控制器以显式添加模型:

        if (bindingResult.hasErrors()) {
        model.addAttribute(registerUserDTO);
        return "register";
    }

然后工作,返回包含模型和先前输入的数据的页面。

  

为什么必须将模型显式添加到退货中?

更新

这也不起作用:

    @PostMapping("/user/register")
public String registerNewUser(@ModelAttribute("user") @Valid RegisterUserDTO registerUserDTO,
                              BindingResult bindingResult) {
    User existing = userService.findUserByEmail(registerUserDTO.getEmail());
    if (existing != null) {
        bindingResult.rejectValue("email", null, "There is already an account with that Email");
    }
    if (bindingResult.hasErrors()) {
        return "register";

1 个答案:

答案 0 :(得分:0)

这有效:

    @PostMapping("/user/register")
    public String registerNewUser(@ModelAttribute("registerUserDTO") @Valid RegisterUserDTO registerUserDTO,
                              BindingResult bindingResult) {
    User existing = userService.findUserByEmail(registerUserDTO.getEmail());
    if (existing != null) {
           bindingResult.rejectValue("email", null, "There is already an account with that Email");
    }
    if (bindingResult.hasErrors()) {
        return "register";
    }
    userService.createUser(registerUserDTO);
    return "redirect:/registration?success";
}

正如M.Denium指出的,@ ModelAttribute名称必须与GET控制器中使用的支持对象的实例名称相同。在我的GET控制器中,我有:

    @GetMapping("/user/register")
String registerForm(Model model) {
    RegisterUserDTO registerUserDTO = new RegisterUserDTO();
    model.addAttribute(registerUserDTO);
    return "register";
}

因此@ModelAttribute需要匹配,即@ModelAttribute(“ registerUserDTO ”)