【问题标题】:How to re-render previous page when validating form验证表单时如何重新呈现上一页
【发布时间】:2020-07-30 00:02:44
【问题描述】:

我有一个控制器,它呈现一个包含各种杂务的 chores.html 页面。

@GetMapping("/chores")
public String getDueChores(Model model)
{
    var tomorrow = LocalDate.now().plusDays(1);
    var chores = choreRepository.findByDueBefore(tomorrow);
    model.addAttribute("choresDue", chores);
    model.addAttribute("allChores", choreRepository.findAll());
    model.addAttribute("chore", new Chore());
    model.addAttribute("chores", new ArrayList<Chore>());
    return "chores";
}

同一页面还有一个用于添加新杂务的表单。这是控制器方法:

@PostMapping("/chores")
public String addNewChore(@ModelAttribute @Valid Chore chore)                  
{       
    chore.setDue(LocalDate.now().plusDays(chore.getDaysBetween()));
    choreRepository.save(chore);
    return "redirect:/chores";
}

现在我想在新的杂务无效时显示错误。

尝试 1:

@PostMapping("/chores")
public String addNewChore(@ModelAttribute @Valid Chore chore,
                                             Errors errors)
{
    if (errors.hasErrors())
    {
        return "chores";
    }

    chore.setDue(LocalDate.now().plusDays(chore.getDaysBetween()));
    choreRepository.save(chore);
    return "redirect:/chores";
}

这显示了错误消息,但感觉它没有通过 GET 控制器方法中的逻辑,页面上的所有其他杂务都不会被填充。

尝试 2:

@PostMapping("/chores")
public String addNewChore(@ModelAttribute @Valid Chore chore,
                          Errors errors)
{
    if (errors.hasErrors())
    {
        return "redirect:/chores";
    }

    chore.setDue(LocalDate.now().plusDays(chore.getDaysBetween()));
    choreRepository.save(chore);
    return "redirect:/chores";
}

这不起作用,因为重定向时错误信息丢失,并且错误不显示。

谁能指点我正确的方向,好吗?

这里是chores.html,如果相关的话:

<body>
<h1>Due today...</h1>
<form method="post" th:action="@{/chore}" th:object="${chore}">
    <ul>
        <li th:each="chore: ${choresDue}">
            <input type="checkbox" name="choreIds" th:value="${chore.id}"/>
            <label th:text="${chore.name}"></label>
        </li>
    </ul>
    <input type="submit" value="Mark Chores Complete">
</form>

<form method="post" action="#" th:action="@{/chores}" th:object="${chore}">
    <input type="text" th:field="*{name}" placeholder="Chore name">
    <span class="validationError"
          th:if="${#fields.hasErrors('name')}"
          th:errors="*{name}">Chore name is invalid</span>
    <br>

    <input type="text" th:field="*{daysBetween}" placeholder="Do chore every # days">
    <span class="validationError"
          th:if="${#fields.hasErrors('daysBetween')}"
          th:errors="*{daysBetween}">Chore name is invalid</span>
    <br>
    <input type="submit" value="Add chore">
</form>

<hr>
<h1>All Chores</h1>
<form th:method="delete" th:action="@{/deleteChore}" th:object="${chore}">
<ul>
    <li th:each="chore: ${allChores}">
        <input type="checkbox" name="choreIds" th:value="${chore.id}"/>
        <label th:text="${chore.name} + ' every ' + ${chore.daysBetween} + ' days'"></label>
    </li>
</ul>
    <input type="submit" value="Delete selected chores">
</form>

</body>

【问题讨论】:

    标签: java spring forms validation


    【解决方案1】:

    解决方案是将Errors 添加到Model

    @PostMapping("/chores")
    public String addNewChore(@ModelAttribute @Valid Chore chore,
                              Errors errors,
                              Model model)
    {
        if (errors.hasErrors())
        {
            model.addAttribute("error", errors);
            var tomorrow = LocalDate.now().plusDays(1);
            var chores = choreRepository.findByDueBefore(tomorrow);
            model.addAttribute("choresDue", chores);
            model.addAttribute("allChores", choreRepository.findAll());
            return "chores";
        }
    
        chore.setDue(LocalDate.now().plusDays(chore.getDaysBetween()));
        choreRepository.save(chore);
        return "redirect:/chores";
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-07-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-02
      • 1970-01-01
      相关资源
      最近更新 更多