为何Thymeleaf路径变量会导致HTML页面异常?
问题分析与解决
问题描述
我写了两个测试@PathVariable注解的Controller方法,两者都硬编码设置了category和subCategory属性,没有使用传入的路径变量。但访问localhost:8080/1时页面显示正常,访问localhost:8080/asdf/asdf时HTML页面却出现异常。
Controller代码
@RequestMapping( value = "/1", method = {RequestMethod.GET}) public String two(Model model) { model.addAttribute("category", "acategory"); model.addAttribute("subCategory", "placeholder"); return "homePage"; } @RequestMapping( path = "/{category}/{subcategory}", method = {RequestMethod.GET}) public String three( @PathVariable("category") String category, @PathVariable("subcategory") String subcategory, Model model) { model.addAttribute("category", "acategory"); model.addAttribute("subCategory", "placeholder"); return "homePage"; }
HTML代码
</head> <body> <div class="wrapper"> <!-- Entire page wrapper? --> <!-- Thymeleaf fragment: commonHeader --> <div th:replace="fragments/commonFragments :: commonHeader"></div> <!-- Begin Page Content--> <div th:insert="'fragments/' + ${category} :: ${subCategory}"></div> <!-- End Page Content --> </div> <!-- Entire page wrapper closing tag? -->
Fragment代码
<div th:fragment="placeholder"> <div class="container"> <div class="row tagline"> <div class="col-sm-12"> <p><strong>Please see <a href="page2.html">page two</a> for all related links. </strong> <!--There's also a <a href="index_3col.html">3-column version</a> of this page.--> Link to a secondary page open accordion <a data-expand="#SecurityPanel" href="page2.html#collapse1">1</a>, <a data-expand="#SecurityPanel" href="page2.html#collapse2">2</a>, or <a data-expand="#SecurityPanel" href="page2.html#collapse3">3</a>.. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus hendrerit consectetur justo, vitae euismod nisl pulvinar id. In hac habitasse platea dictumst. Nam quis ante at mi auctor vehicula. <a href="page2.html">Learn more</a>. </p> </div> </div> ... more stuff cut for brevity </div> </div>
原因分析
问题核心在于静态资源和页面链接的相对路径错误:
- 访问
/1时,页面基础URL是localhost:8080/,浏览器请求相对路径资源(如CSS、JS、page2.html)时,会从根目录查找,路径正确。 - 访问
/asdf/asdf时,页面基础URL变为localhost:8080/asdf/,浏览器会把相对路径的资源请求指向localhost:8080/asdf/xxx,但这些资源实际存放在根目录下,导致404,最终页面样式错乱、链接失效,表现为“异常”。
注:你在Controller中手动添加的category和subCategory已经覆盖了@PathVariable自动注入的模型属性,所以fragment加载逻辑是正常的,异常并非来自fragment本身。
解决方案
把所有相对路径引用改为绝对路径,或使用Thymeleaf的@{...}语法生成正确的根路径URL:
1. 修复静态资源引用(如commonHeader中的CSS/JS)
原错误写法:
<link href="css/style.css" rel="stylesheet"> <script src="js/main.js"></script>
改为Thymeleaf标准写法:
<link th:href="@{/css/style.css}" rel="stylesheet"> <script th:src="@{/js/main.js}"></script>
2. 修复页面链接(如fragment中的page2.html)
原错误写法:
<a href="page2.html">page two</a> <a data-expand="#SecurityPanel" href="page2.html#collapse1">1</a>
改为Thymeleaf标准写法:
<a th:href="@{/page2.html}">page two</a> <a th:href="@{/page2.html#collapse1}" data-expand="#SecurityPanel">1</a>
这样无论访问哪个路径,Thymeleaf都会生成基于应用根目录的绝对路径,确保资源和链接能被正确找到。
内容的提问来源于stack exchange,提问作者old_dd
相关产品推荐
相关产品推荐

