Spring Boot+Java+Thymeleaf环境下HTML页面无法加载问题排查
问题排查:Spring Boot中/numasc路径仅返回JSON不加载Thymeleaf页面
问题描述
访问/numasc路径时,后端AppController的getNumAsc方法已正确返回Troops列表的JSON数据,但对应的Thymeleaf HTML页面未被加载,其他结构类似的HTML页面均正常工作。
Controller代码
@Controller public class AppController { @Autowired private UserRepository userRepo; @GetMapping("") public String viewHomePage() { return "index"; } @GetMapping("/index") public String logoutPage() {return "index";} @GetMapping("/menu") public String menuPage() {return "menu";} @GetMapping("/register") public String showRegistrationForm(Model model) { model.addAttribute("user", new User()); return "signup_form"; } @PostMapping("/process_register") public String processRegister(User user) { BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder(); String encodedPassword = passwordEncoder.encode(user.getPassword()); user.setPassword(encodedPassword); userRepo.save(user); return "menu"; } @GetMapping("/users") public String listUsers(Model model) { List<User> listUsers = userRepo.findAll(); model.addAttribute("listUsers", listUsers); return "users"; } public List<Troops> getTroops() { List<Troops> TroopList = new LinkedList<>(); try { // File path to the XML file. Path filePath = Paths.get("C:\\Users\\amani\\OneDrive\\WYWM\\Java\\Capstone 1\\dataset.xml"); File file = new File(String.valueOf(filePath.toAbsolutePath())); if (file.exists()) { DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder(); Document document = documentBuilder.parse(String.valueOf(filePath.toAbsolutePath())); // Reads the XML tagName of full_name and id. NodeList[] user = { document.getElementsByTagName("full_name"), document.getElementsByTagName("id") }; for (int i = 0; i < user[0].getLength(); i++) { String fullName = user[0].item(i).getTextContent(); int id = Integer.parseInt(user[1].item(i).getTextContent()); Troops newTroop = new Troops(fullName, id); TroopList.add(newTroop); } } else { System.out.println("File not found"); } } catch (Exception e) { System.out.println(e.getMessage()); } // Returns the TroopList with data from the XML file. return TroopList; } @RequestMapping(value = "/numasc", method = RequestMethod.GET) @ResponseBody public List<Troops> getNumAsc() { List<Troops> ascList = new LinkedList<Troops>(); ascList.addAll(getTroops()); ascList.sort((u1, u2) -> u1.getId() - u2.getId()); return ascList; } }
返回的JSON数据
[{"fullName":"Maridel MacCostye","id":1},{"fullName":"Phineas Bonnet","id":2},{"fullName":"Oates McGillivray","id":3},{"fullName":"Curtice Comelli","id":4},{"fullName":"Phillis Wontner","id":5},{"fullName":"Bradley Hasell","id":6},{"fullName":"Carling Cokely","id":7},{"fullName":"Bertrand Samms","id":8},{"fullName":"Chiarra Trill","id":9},{"fullName":"Willie Balmadier","id":10}]
/numasc对应的HTML页面代码
<!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="ISO-8859-1"> <title>Soldiers Deployed</title> <link rel="stylesheet" type="text/css" href="/webjars/bootstrap/css/bootstrap.min.css" /> <script type="text/javascript" src="/webjars/jquery/jquery.min.js"></script> <script type="text/javascript" src="/webjars/bootstrap/js/bootstrap.min.js"></script> </head> <body> <div class="container text-center"> <div> <form th:action="@{/logout}" method="post"> <p> Welcome <b>[[${#request.userPrincipal.principal.fullName}]]</b> </p> <input type="submit" value="Sign Out" /> </form> </div> <div> <h1>Soldiers Deployed</h1> </div> <div> <table class="table table-striped table-bordered"> <thead class="thead-dark"> <tr> <th>ID</th> <th>Full Name</th> </tr> </thead> <tbody> <a th:href="@{/menu}" class="button primary">Back to Menu</a> <tr th:each=" ${ascList}"> <td th:text=${ascList.id}>ID</td>> <td th:text=${ascList.fullName}>Full name</td>> </tr> </tbody> </table> </div> </div> </body> </html>
排查分析与解决方案
核心问题1:@ResponseBody注解导致直接返回JSON
getNumAsc方法添加了@ResponseBody注解,这个注解会将方法返回的对象直接序列化为JSON响应体返回给前端,而非返回视图名称让Spring渲染Thymeleaf页面。其他正常方法(如listUsers)无此注解,通过返回视图名+Model传值实现页面渲染。
核心问题2:数据未传入Model,Thymeleaf无法获取数据
即使去掉@ResponseBody,当前方法也未将排序后的ascList放入Model,页面无法拿到渲染数据。
核心问题3:Thymeleaf遍历语法错误
页面中<tr th:each=" ${ascList}">语法错误,正确格式应为th:each="变量名 : ${集合}",需通过变量名访问集合元素的属性。
修改步骤
1. 修改Controller的getNumAsc方法
移除@ResponseBody,添加Model参数并传入数据,返回视图名称:
@GetMapping("/numasc") public String getNumAsc(Model model) { List<Troops> ascList = new LinkedList<>(getTroops()); ascList.sort((u1, u2) -> u1.getId() - u2.getId()); model.addAttribute("ascList", ascList); return "numasc"; }
2. 修正Thymeleaf页面的遍历代码
修改遍历语法与属性访问方式:
<tr th:each="troop : ${ascList}"> <td th:text="${troop.id}">ID</td> <td th:text="${troop.fullName}">Full name</td> </tr>
3. 确认页面路径
确保numasc.html放在Spring Boot默认Thymeleaf模板路径src/main/resources/templates/下,文件名与方法返回的视图名一致。
内容的提问来源于stack exchange,提问作者Neet
相关产品推荐
相关产品推荐

