如何实现Thymeleaf向Spring Boot Controller传值并完成外部重定向?
我正在实现Thymeleaf的Spring MVC数据访问教程,但不理解message/list的含义。我做了一个Spring Boot应用,调用第三方API获取JSON数据并存入PostgreSQL,数据库里有一列是来自API的URL,用Thymeleaf在前端展示。现在想实现点击前端的URL链接跳转到外部网站,需要同时实现Thymeleaf向Controller传数据,以及Controller重定向到外部网站,但当前代码报错:
java.lang.IllegalArgumentException: Model has no value for key 'rate.news_link'
前端代码
<!DOCTYPE HTML> <html lang="en" xmlns:th="http://www.thymeleaf.org" xmlns:c="http://www.w3.org/1999/XSL/Transform" xmlns:https="http://www.w3.org/1999/xhtml"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <title>Spring Boot Thymeleaf Hello World Example</title> <link rel="stylesheet" th:href="@{/webjars/bootstrap/css/bootstrap.min.css}"/> <link rel="stylesheet" th:href="@{/styles/db.css}"/> <script type="text/javascript" th:src="@{/webjars/bootstrap/js/bootstrap.min.js}"></script> </head> <body> <ul> <li><a href="http://localhost:8080/">Home</a></li> <li><a href="https://github.com/Andreas-Kreouzos" target="_blank">Github</a></li> </ul> <main role="main" class="container"> <div class="starter-template"> <h1>Cryptocurrency News</h1> </div> </main> <!--Display DB contents on HTML and Thymeleaf--> <div class="container text-center" id="tasksDiv"> <hr> <div class="table-responsive"> <table class="table table-striped table-bordered"> <thead> <tr> <th>News Provider Name</th> <th>News Link</th> <th>Related Image</th> </tr> </thead> <tbody> <tr th:each="rate: ${rates}"> <td th:text="${rate.news_provider_name}"> </td> <td> <a href="#" th:href="${rate.news_link}" th:text="${rate.HEADLINE}"> </a> </td> <td> <img th:src="${rate.related_image}" alt="error displaying image"> </td> </tr> </tbody> </table> </div> </div> </body> </html>
控制器代码
@RequestMapping("/") public String redirect() { return "redirect:/${rate.news_link}"; }
错误原因
你的控制器代码存在两个核心问题:
@RequestMapping("/")方法返回的"redirect:/${rate.news_link}"是错误写法——${}是Thymeleaf模板表达式,不能直接用在Controller的字符串返回值里,Spring无法解析该表达式;同时该方法既没接收前端传递的news_link参数,也没向Model存入rate对象,因此会报Model无对应key的错误。- 你的前端代码其实已经通过
th:href="${rate.news_link}"绑定了外部URL,这种场景下完全可以直接跳转,不需要经过Controller中转。如果确实需要Controller介入(比如做日志记录、URL校验),才需要调整代码。
解决方案
方案1:直接前端跳转(最简方案)
只要rate.news_link是完整的HTTP/HTTPS开头的URL(比如https://example.com/news),当前前端的<a>标签已经可以直接跳转到外部网站,无需修改控制器,也不需要额外处理。
方案2:通过Controller中转跳转(需前置逻辑时用)
如果必须经过Controller处理(比如记录点击日志、验证URL合法性),按以下步骤修改:
1. 修改前端代码
将<a>标签的th:href改为指向Controller的跳转接口,并传递news_link参数:
<td> <a href="#" th:href="@{/redirect-to-news(link=${rate.news_link})}" th:text="${rate.HEADLINE}"></a> </td>
该写法会生成类似/redirect-to-news?link=https://example.com/news的请求地址。
2. 修改Controller代码
调整首页接口的逻辑,同时添加跳转处理接口:
// 首页接口:返回新闻列表页面,需向Model存入数据 @RequestMapping("/") public String showNews(Model model) { // 此处补充从数据库获取rates数据的逻辑,例如: // List<Rate> rates = rateService.getAllRates(); model.addAttribute("rates", rates); return "你的页面模板名称"; // 比如对应你的HTML页面名称,如"news" } // 跳转处理接口:接收URL参数并重定向到外部网站 @RequestMapping("/redirect-to-news") public String redirectToExternalSite(@RequestParam("link") String newsLink) { // 可在此添加前置逻辑,比如日志记录、URL合法性校验 return "redirect:" + newsLink; }
注意:重定向外部URL时,必须确保newsLink是带http/https前缀的完整地址,否则Spring会认为是内部路径。
关于message/list的说明
你参考的教程里,message/list是一个示例请求路径,对应Controller中处理消息列表展示的接口,用来演示如何从Controller向Thymeleaf模板传递数据(比如消息列表)。可以把它理解为一个业务接口的路径,对应展示某类数据列表的页面。
内容的提问来源于stack exchange,提问作者Vel_More

