Spring Boot调用/users接口遇TemplateInputException错误求助
我是Spring Boot新手,已经实现通过POST方法将HTML页面的用户输入数据插入数据库,但调用GET请求http://localhost:8080/users读取并展示数据时,出现模板解析异常,网页显示500白标错误。
错误日志
2023-08-26 12:20:28.125 ERROR 15292 --- [nio-8080-exec-3] org.thymeleaf.TemplateEngine : [THYMELEAF][http-nio-8080-exec-3] Exception processing template "users": Error resolving template [users], template might not exist or might not be accessible by any of the configured Template Resolvers
org.thymeleaf.exceptions.TemplateInputException: Error resolving template [users], template might not exist or might not be accessible by any of the configured Template Resolvers
白标错误页面内容
Whitelabel Error Page
This application has no explicit mapping for /error, so you are seeing this as a fallback.Sat Aug 26 12:20:28 IST 2023
There was an unexpected error (type=Internal Server Error, status=500).
相关代码
Controller代码
package com.forms.demo.htmlExample.controller; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.PostMapping; import com.forms.demo.htmlExample.model.User; import com.forms.demo.htmlExample.repo.UserRepository; import com.forms.demo.htmlExample.service.UserService; @Controller public class IndexController { @Autowired private UserRepository repo; @Autowired private UserService service; @GetMapping("/") public String index() { return "index"; } @GetMapping("/users") public List<User> getUsers() { return service.getUsers(); } @PostMapping("/register") public String userRegistration(@ModelAttribute User user, Model model) { System.out.println(user.toString()); System.out.println(user.getFname()); System.out.println(user.getLname()); System.out.println(user.getEmail()); System.out.println(user.getGender()); System.out.println(user.getDob()); System.out.println(user.getGender()); model.addAttribute("firstname", user.getFname()); model.addAttribute("lastname", user.getLname()); model.addAttribute("email", user.getEmail()); repo.save(user); model.addAttribute("message", user.getEmail() + " inserted"); return "welcome"; } }
Service类代码
package com.forms.demo.htmlExample.service; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.forms.demo.htmlExample.model.User; import com.forms.demo.htmlExample.repo.UserRepository; @Service public class UserService { @Autowired private UserRepository userRepo; public List<User> getUsers() { return userRepo.findAll(); } }
Repository类代码
package com.forms.demo.htmlExample.repo; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.repository.CrudRepository; import com.forms.demo.htmlExample.model.User; public interface UserRepository extends JpaRepository<User, Integer> { }
Entity类代码
package com.forms.demo.htmlExample.model; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.Table; @Entity @Table(name="user_data") public class User { @Id @GeneratedValue private int id; private String fname; private String lname; private String email; private String passwd; private String dob; private String gender; public String getFname() { return fname; } public String getPasswd() { return passwd; } public void setPasswd(String passwd) { this.passwd = passwd; } public void setFname(String fname) { this.fname = fname; } public String getLname() { return lname; } public void setLname(String lname) { this.lname = lname; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public String getDob() { return dob; } public void setDob(String dob) { this.dob = dob; } public String getGender() { return gender; } public void setGender(String gender) { this.gender = gender; } @Override public String toString() { return "User [fname=" + fname + ", lname=" + lname + ", email=" + email + ", passwd=" + passwd + ", dob=" + dob + ", gender=" + gender + "]"; } }
问题原因及解决方法
核心问题
你的@Controller下的getUsers方法返回List<User>,但Spring Boot默认会尝试用Thymeleaf渲染名为users的模板页面,而你并没有创建对应的users.html模板,因此抛出模板未找到异常。
两种解决方向
方向1:返回REST JSON数据(API接口)
如果需求是提供REST API返回用户数据,可将该方法所在的Controller改为@RestController,或在getUsers方法上添加@ResponseBody注解:
// 方案一:改用@RestController @RestController public class IndexController { // ... 其他代码不变 @GetMapping("/users") public List<User> getUsers() { return service.getUsers(); } } // 方案二:添加@ResponseBody @Controller public class IndexController { // ... 其他代码不变 @GetMapping("/users") @ResponseBody public List<User> getUsers() { return service.getUsers(); } }
修改后访问/users会直接返回JSON格式的用户列表,无需模板页面。
方向2:渲染Thymeleaf模板页面展示数据
如果需要在网页上展示用户数据,需完成以下两步:
- 在
src/main/resources/templates目录下创建users.html模板文件,示例如下:
<!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org"> <head> <title>用户列表</title> </head> <body> <h1>用户列表</h1> <table> <tr> <th>ID</th> <th>姓名</th> <th>邮箱</th> </tr> <tr th:each="user : ${users}"> <td th:text="${user.id}"></td> <td th:text="${user.fname + ' ' + user.lname}"></td> <td th:text="${user.email}"></td> </tr> </table> </body> </html>
- 修改
getUsers方法,将用户列表添加到Model中,并返回模板名称:
@GetMapping("/users") public String getUsers(Model model) { List<User> users = service.getUsers(); model.addAttribute("users", users); return "users"; }
修改后访问/users会渲染users.html页面并展示用户数据。
内容的提问来源于stack exchange,提问作者RDX

