5

我的SpringMVC控制器中有下一个工作代码:

@RequestMapping(value = "/register", method = RequestMethod.GET)
public void registerForm(Model model) {
    model.addAttribute("registerInfo", new UserRegistrationForm());
}

@RequestMapping(value = "/reg", method = RequestMethod.POST)
public String create(
        @Valid @ModelAttribute("registerInfo") UserRegistrationForm userRegistrationForm,
        BindingResult result) {

    if (result.hasErrors()) {
        return "register";
    }
    userService.addUser(userRegistrationForm);
    return "redirect:/";
}

总之create方法尝试验证UserRegistrationForm。如果表单有错误,它会让用户在同一页面上填写表单字段,其中将显示错误消息。

现在我需要将相同的行为应用到另一个页面,但这里我有一个问题:

@RequestMapping(value = "/buy/{buyId}", method = RequestMethod.GET)
public String buyGet(HttpServletRequest request, Model model, @PathVariable long buyId) {
    model.addAttribute("buyForm", new BuyForm());
    return "/buy";
}

@RequestMapping(value = "/buy/{buyId}", method = RequestMethod.POST)
public String buyPost(@PathVariable long buyId,
                          @Valid @ModelAttribute("buyForm") BuyForm buyForm,
                          BindingResult result) {

    if (result.hasErrors()) {
        return "/buy/" + buyId;
    }

    buyForm.setId(buyId);
    buyService.buy(buyForm);
    return "redirect:/show/" + buyId;
}

我遇到了动态网址的问题。现在,如果表单有错误,我应该指定相同的页面模板留在当前页面上,但我也应该buyId作为路径变量传递。这两个要求哪里有冲突。如果我保留此代码,则会收到错误消息(我使用Thymeleaf作为模板处理器):

Error resolving template "/buy/3", template might not exist or might not be accessible by any of the configured Template Resolvers

我可以写类似的东西return "redirect:/buy/" + buyId,但在这种情况下,我会丢失表单对象的所有数据和错误。

我应该怎么做才能在方法中实现与buyPost方法中相同的行为create

4

3 回答 3

3

我在这个周末尝试了这篇文章中提到的解决方案,但它不适用于 BindingResult。

下面的代码有效,但并不完美。

@ModelAttribute("command")
public PlaceOrderCommand command() {
    return new PlaceOrderCommand();
}

@RequestMapping(value = "/placeOrder", method = RequestMethod.GET)
public String placeOrder(
        @ModelAttribute("command") PlaceOrderCommand command,
        ModelMap modelMap) {
    modelMap.put(BindingResult.MODEL_KEY_PREFIX + "command",
            modelMap.get("errors"));
    return "placeOrder";
}

@RequestMapping(value = "/placeOrder", method = RequestMethod.POST)
public String placeOrder(
        @Valid @ModelAttribute("command") PlaceOrderCommand command,
        final BindingResult bindingResult, Model model,
        final RedirectAttributes redirectAttributes) {
    if (bindingResult.hasErrors()) {
        redirectAttributes.addFlashAttribute("errors", bindingResult);

        //it doesn't work when passing this          
        //redirectAttributes.addFlashAttribute(BindingResult.MODEL_KEY_PREFIX + "command", bindingResult);

        redirectAttributes.addFlashAttribute("command", command);
        return "redirect:/booking/placeOrder";
    }
    ......
}
于 2013-08-11T16:10:00.963 回答
2

*我正在使用Hibernate Validator API来验证我的 bean。要保留表单数据并显示错误消息,您需要执行以下 3 件事:

  1. 注释您的 bean(例如,@NotEmpty、@Pattern、@Length、@Email 等)

在此处输入图像描述

  1. 内部控制器:

    @Controller 公共类注册控制器 {

    @Autowired
    private RegistrationService registrationService;
    
    @RequestMapping(value="register.htm", method=RequestMethod.GET, params="new")
    public String showRegistrationForm(Model model) {
        if (!model.containsAttribute("employee")) {
            model.addAttribute("employee", new Employee());
        }
        return "form/registration";
    }
    
    @RequestMapping(value="register.htm", method=RequestMethod.POST)
    public String register(@Valid @ModelAttribute("employee") Employee employee, BindingResult bindingResult, RedirectAttributes redirectAttributes) {
        if (bindingResult.hasErrors()) {
            redirectAttributes.addFlashAttribute("org.springframework.validation.BindingResult.employee", bindingResult);
            redirectAttributes.addFlashAttribute("employee", employee);
            return "redirect:register.htm?new";
        }
        registrationService.save(employee);
        return "workspace";
    }
    // ....
    

    }

  2. 更新您的视图/jsp 以保存错误消息:

在此处输入图像描述

这篇文章肯定会有所帮助。

于 2013-11-09T09:44:12.233 回答
0

您可以将 POST 实现更改为:

@RequestMapping(value = "/buy/{buyId}", method = RequestMethod.POST)
public String buyPost(@PathVariable long buyId,
                          @Valid @ModelAttribute("buyForm") BuyForm buyForm,
                          BindingResult result) {

    buyForm.setId(buyId); // important to do this also in the error case, otherwise, 
                          // if the validation fails multiple times it will not work.

    if (result.hasErrors()) {
        byForm.setId(buyId);
        return "/buy/{buyId}";
    }

    buyService.buy(buyForm);
    return "redirect:/show/{buyId}";
}

或者,@PostMapping("/buy/{buyId}")如果您使用 Spring 4.3 或更高版本,您还可以注释该方法。

于 2016-11-25T09:44:35.507 回答