为啥这个 Spring Boot/Thymeleaf 按钮会隐藏我的数据或根本不起作用?

Posted

技术标签:

【中文标题】为啥这个 Spring Boot/Thymeleaf 按钮会隐藏我的数据或根本不起作用?【英文标题】:Why does this Spring Boot/Thymeleaf button hide my data or not work at all?为什么这个 Spring Boot/Thymeleaf 按钮会隐藏我的数据或根本不起作用? 【发布时间】:2020-09-26 20:06:46 【问题描述】:

我目前正在尝试通过遵循教程并使用它们提供的代码来学习 Spring Boot 和 Thymeleaf。我尝试实现一个额外的功能,但遇到了以下问题:代码应该显示一个由 ToDo-Objects 组成的 ToDo-List,每个 ToDo-Objects 都有一个名称、描述和一个布尔状态,表示它们是否完成。表格的每一行都应该有一个可以单击的按钮,以便将 ToDo 标记为已完成。

<table style="border-collapse:collapse; font-family: Arial,Arial,sans-serif;">
    <tr>
        <th padding: 5px"></th>
        <th> To-Do</th>
        <th> Description</th>
        <th> Done?</th>
    </tr>
    <tr th:each="todo : $todos">


        <td>
            <!-- <form method="POST" th:action="@/updateDone(exactToDo=$todo)">
                <button type="submit" name="submit" value="value" class="link-button">Done</button>
            </form> -->

            <form method="POST" th:action="@/updateDone">
                <input type="hidden" name="exactToDo" id="exactToDo" th:value="$todo.getName()" />
                <button type="submit" name="submit" value="value" class="link-button" >This is a link that sends a POST request</button>
            </form>
        </td>

        <td th:utext="$todo.name" style="border: 1px solid black;">...</td>
        <td th:utext="$todo.description" style="border: 1px solid black;">...</td>
        <td th:text="$todo.done ? 'Yes! ' : 'No' " style="border: 1px solid black;">...</td>
    </tr>
</table>

显示内容有效,但我的按钮在此配置中没有任何作用。我按照this older question 的指示进行操作,但它不会改变我的待办事项的状态。我可以在浏览器控制台中看到它发送了一个 Post 请求,但里面似乎什么都没有。 当前注释掉的部分使数据从我的表中消失,只留下第一行的标题。我尝试了各种我在网上找到的类似方法,但它们都有这两种结果之一。

这里是相关控制器的代码:

    @RequestMapping(value = "/updateDone", method=RequestMethod.POST)
public String completeTask(Model model, @RequestParam("exactToDo") String exactToDo)
    for (ToDo todo : todos)
        if (todo.getName().equals(exactToDo))
            todo.markDone();
        
    
    return "list";

将返回设置为“redirect:/list”修复了“消失”数据的问题,但 ToDo 的状态仍然没有改变。我认为问题在于 ToDo 对象未正确发送到该方法,但我不确定原因。您可能已经注意到我正在尝试直接发送 todo.getName() 而不是 ToDo 对象,这是因为当我尝试发送对象时,我在发布的控制器代码的第二行中收到错误,告诉我字符串无法转换为 ToDo-Object(控制器当然被配置为将 ToDo 对象作为参数)。这就是为什么我认为问题一定出在某个地方。

如果有人能帮助我解决这个问题或指出一种更好的方法来让 html 页面上的按钮激活我的 Java 代码中的方法,我将不胜感激。也非常感谢有关良好学习资源的提示。我正在尝试学习 Spring 和 Thymeleaf,以便为 Java 程序制作用户界面。

感谢您的宝贵时间!

【问题讨论】:

【参考方案1】:

第一件事第一件事。

为什么你需要为一个按钮写这么多(表单)?现在,如果您“必须”使用表单,那么您的表单标签中缺少 th:object="$todo" 。它将帮助 Controller 了解您将对什么对象采取一些行动。

但我建议您在“td”块中使用它而不是表单。它会为你做同样的工作。一旦您的请求成功,您可以将其重定向到您的列表,您应该会立即看到新的结果。

 <a href="/updateDone" th:href="@/updateDone">Mark Done</a>

您可以参考this 查看完整示例。在这里你会发现两件事。您可能感兴趣的用户控制器和任务控制器。

【讨论】:

感谢您的回答!我一定会浏览你链接的项目。我使用了一个表单,因为它允许我发送一个 POST 请求而不是 GET。我的理解是这样的操作更好。我不确定我是否正确理解了您的解决方案。将 th:object="$todo" 添加到我的表单并没有改变任何内容,我不明白该方法如何在您的第二个解决方案中获取它所需的参数。 我设法找到了一个解决方案,将参数包含在链接中。我仍然很好奇使用 POST 请求是否会更好?无论如何,感谢您的帮助!【参考方案2】:

对于以后可能会发现此问题的任何人,以下是答案:

Ajay Kumar 发布的链接最终可以使用,只需稍作调整即可包含必要的参数:

&lt;a href="/updateDone" th:href="@/updateDone(exactToDo=$todo.getName())" &gt;Mark Done&lt;/a&gt;

【讨论】:

以上是关于为啥这个 Spring Boot/Thymeleaf 按钮会隐藏我的数据或根本不起作用?的主要内容,如果未能解决你的问题,请参考以下文章

为啥这个 Spring Boot 应用程序找不到主页?

为啥这个基于令牌的 Spring Security 过滤器没有被调用?

为啥这个 Spring Boot/Thymeleaf 按钮会隐藏我的数据或根本不起作用?

在mybatis跟spring集成的时候,为啥还要导入spring-jdbc的包呢,这里面不是

mybatis+spring3.1 dao继承SqlSessionDaoSupport后使用sqlsession.delete() 为啥返回-2147482646这个值?

为啥 Spring Webflux 只能并行接受 256 个请求?