Thymeleaf项目href链接无法找到HTML页面,报404错误
Thymeleaf项目页面链接404问题解决
问题概述
- 通过控制器可正常访问首页,但首页内的Thymeleaf链接点击后返回404错误
- IntelliJ支持链接跳转,路径看似正确
错误信息
原始服务器未找到目标资源的当前表示,或不愿透露资源存在
首页代码
<!DOCTYPE HTML> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>chessopenings</title> <link rel="stylesheet" href="https://fonts.googleapis.com/icon? family=Material+Icons"> <style th:inline="text"> body { background-image: url("/chess-background.jpeg"); background-repeat: no-repeat; background-size: cover; } .topnav { position: relative; overflow: hidden; background-color: #333; border: 2px; width: max-content; } .topnav a { float: left; color: #f2f2f2; text-align: center; padding: 14px 16px; text-decoration: none; font-size: 17px; border: 2px; } .topnav a:hover { background-color: #ddd; color: black; border: 2px; } .quote-text { position: absolute; color: white; align: center; left: 20px; top: 200px; font-family: cursive; font-size: 30px; } .instructions-text { position: absolute; color: white; align: center; left: 700px; top: 220px; font-family: Arial, Helvetica, sans-serif; font-size: 20px; } @media screen and (max-width: 500px) { .navbar a { float: none; display: block; } } </style> </head> <body> <div class="topnav"> <a th:href="@{/chessopeningsscreen2.html}"> <i class="material-icons" style="border:2px;font-size:60px;color:rgb(0, 0, 0);">search</i> </a> <a th:href="@{/chessopeningsscreen3.html}"> <i class="material-icons" style="border:2px;font-size:60px;color:rgb(0, 0, 0);">add_circle</i> </a> </div> </div> <div class="quote-text"> <p> "Really deep opening research has<br> been a hallmark of Kasparov's<br> domination of world chess."<br> - Graham Burgess </p> </div> <div class="instructions-text"> <p th> To use this tool, you can either enter an<br> opening or search for the player's opening.<br><br> To add an opening, click on the plus icon in<br> the top left hand corner. The next screen can be<br> completed to add the game to the database. You<br> can either select and already existing player or<br> add a new one. Date is an option, although it does<br> help players see openings that are currently<br> played. Finally, input the first ten moves of<br> the opening and submit.<br><br> To look for an opening, click on the search icon<br> above. In the next screen you can select names to<br> view their opening statistics. If you want<br> openings after a particluar date, fill in the<br> date field. If there is missing data inputted, these<br> results will not be shown unless the 'all results'<br> tick box is selected. </p> </div> </body> </html>
第二页代码
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>chessopenings2</title> <link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons"> <style> body { style="background-color:#FF0000; } .topnav { position: relative; overflow: hidden; background-color: #333; border: 2px; width:max-content; } .topnav a { float: left; color: #f2f2f2; text-align: center; padding: 14px 16px; text-decoration: none; font-size: 17px; border: 2px; } .topnav a:hover { background-color: #ddd; color: black; border: 2px; } .formformat { color: white; padding: 50px; font-size: 24px; font-family: Arial, Helvetica, sans-serif; } .instructions-text { position: absolute; color: white; align: center; left: 700px; top: 300px; font-family: Arial, Helvetica, sans-serif; font-size: 20px; } @media screen and (max-width: 500px) { .navbar a { float: none; display: block; } } </style> </head> <body style="background-color:rgb(68, 57, 57);"> <div class="topnav"> <a th:href="@{chessopeningsscreen1.html}"> <i class="material-icons" style="border:2px;font-size:60px;color:rgb(0, 0, 0);">arrow_back</i> </a> </div> <div class="formformat"> <br><br> <form> <label for="sfname">Select first name:</label> <select name="sfname" id="sfname"> <option value="sfname">testFirstName</option> </select> <label for="slname">Select last name:</label> <select name="slname" id="slname"> <option value="slname">testLastName</option> </select><br><br> <label for="date">Date from:</label><br> <input type="text" id="date" name="date"><br><br> <label for="allresults">All entries</label><br> <input type="checkbox" id="allresults" name="allresults"><br><br> <input type="submit"> </form> </div> <div class="instructions-text"> <p> Some entries my have missing dates or names. If<br> you wish these to be included in the statistics <br> generated, please tic the 'All entries' box.<br> </p> </div> </body> </html>
Maven项目文件结构

解决步骤
1. 补充控制器请求映射
Thymeleaf模板不能直接通过静态URL访问,必须通过Spring控制器转发。添加如下控制器类:
@Controller public class PageController { // 首页映射 @GetMapping("/") public String home() { return "chessopeningsscreen1"; // 自动匹配templates下的chessopeningsscreen1.html } // 第二页映射 @GetMapping("/chessopeningsscreen2") public String screen2() { return "chessopeningsscreen2"; } // 第三页映射 @GetMapping("/chessopeningsscreen3") public String screen3() { return "chessopeningsscreen3"; } }
2. 修正Thymeleaf链接路径
链接中不需要添加.html后缀,Thymeleaf会根据控制器返回的视图名自动拼接模板路径:
- 首页链接修改:
<a th:href="@{/chessopeningsscreen2}"> <i class="material-icons" style="border:2px;font-size:60px;color:rgb(0, 0, 0);">search</i> </a> <a th:href="@{/chessopeningsscreen3}"> <i class="material-icons" style="border:2px;font-size:60px;color:rgb(0, 0, 0);">add_circle</i> </a>
- 第二页返回首页链接修改:
<a th:href="@{/}"> <i class="material-icons" style="border:2px;font-size:60px;color:rgb(0, 0, 0);">arrow_back</i> </a>
3. 检查Thymeleaf配置
确保application.properties中Thymeleaf配置正确(默认配置通常已生效,可验证):
spring.thymeleaf.prefix=classpath:/templates/ spring.thymeleaf.suffix=.html spring.thymeleaf.mode=HTML spring.thymeleaf.encoding=UTF-8
内容的提问来源于stack exchange,提问作者Hywel Griffiths
相关产品推荐
相关产品推荐

