Spring返回String而非HTML视图的问题求助
Spring返回String而非HTML视图问题排查
我正在学习Spring框架,开发一个连接MySQL数据库的简单应用时,遇到Spring返回字符串"actor"而非对应的HTML视图的问题。
以下是完整代码:
Actor.java
package com.dbtest.dbTest; import jakarta.persistence.Entity; import jakarta.persistence.Id; @Entity public class Actor { @Id private Integer actor_id; private String first_name; private String last_name; private String last_update; public Actor(Integer actor_id, String first_name, String last_name, String last_update) { this.actor_id = actor_id; this.first_name = first_name; this.last_name = last_name; this.last_update = last_update; } public Actor() {} public Integer getActor_id() { return actor_id; } public void setActor_id(Integer actor_id) { this.actor_id = actor_id; } public String getFirst_name() { return first_name; } public void setFirst_name(String first_name) { this.first_name = first_name; } public String getLast_name() { return last_name; } public void setLast_name(String last_name) { this.last_name = last_name; } public String getLast_update() { return last_update; } public void setLast_update(String last_update) { this.last_update = last_update; } }
ActorRepository.java
package com.dbtest.dbTest; import org.springframework.data.repository.CrudRepository; public interface ActorRepository extends CrudRepository<Actor, Integer> { }
MainController.java(原代码)
package com.dbtest.dbTest; import java.util.Date; import java.text.SimpleDateFormat; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping(path="/actor") public class MainController { @Autowired private ActorRepository actorRepository; @PostMapping(path="/add") public @ResponseBody String addNewActor(@RequestParam String first_name, @RequestParam String last_name) { Actor a = new Actor(); a.setActor_id(this.getMaxId()+1); a.setFirst_name(first_name); a.setLast_name(last_name); Date date = new Date(System.currentTimeMillis()); SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss"); String formattedDate = sdf.format(date); a.setLast_update(formattedDate); actorRepository.save(a); return "OK!"; } @PostMapping(path="/delete") public @ResponseBody String deleteActorById(@RequestParam int id) { for(Actor a : this.actorRepository.findAll()) { if(a.getActor_id() == id) { this.actorRepository.deleteById(id); return "DELETED!"; } } return "USER NOT FOUND "+id; } public int getMaxId() { int max = 0; for(Actor a :actorRepository.findAll()) { if(a.getActor_id() > max) { max = a.getActor_id(); } } return max; } @GetMapping(path="/all") public String showActor(Model model) { model.addAttribute("actors", this.actorRepository.findAll()); return "actor"; } }
DbTestApplication.java
package com.dbtest.dbTest; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class DbTestApplication { public static void main(String[] args) { SpringApplication.run(DbTestApplication.class, args); } }
actor.html(原代码)
<!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title th:text="Listado de actores"></title> </head> <body> <table> <thead> <tr> <th>ID</th> <th>Nombre</th> <th>Apellido</th> <th>Última actualización</th> </tr> </thead> <tbody> <tr th:each="actor : ${actors}"> <td th:each="${actor.actor_id}"></td> <td th:each="${actor.first_name}"></td> <td th:each="${actor.last_name}"></td> <td th:each="${actor.last_update}"></td> </tr> </tbody> </table> </body> </html>
application.properties
spring.jpa.hibernate.ddl-auto=update spring.datasource.url=jdbc:mysql://${MYSQL_HOST:localhost}:3306/sakila spring.datasource.username=root spring.datasource.password=root spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver logging.level.root=INFO logging.file.name=spring.log
问题原因及解决方案
1. 控制器注解错误(核心问题)
@RestController 注解等价于 @Controller + @ResponseBody,会强制控制器中所有方法直接返回字符串/JSON,而不会将返回的字符串解析为视图名称。
修改方案:
将 MainController 上的 @RestController 替换为 @Controller,同时保留需要返回字符串的方法上的 @ResponseBody 注解:
@Controller @RequestMapping(path="/actor") public class MainController { // ... 其他代码不变 ... @PostMapping(path="/add") public @ResponseBody String addNewActor(...) { /* 代码不变 */ } @PostMapping(path="/delete") public @ResponseBody String deleteActorById(...) { /* 代码不变 */ } @GetMapping(path="/all") public String showActor(Model model) { /* 代码不变 */ } }
2. Thymeleaf模板语法错误
原 actor.html 中错误使用 th:each 来显示字段值,th:each 是用于循环集合的属性,显示字段值应该使用 th:text。
修改后的actor.html:
<!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title th:text="Listado de actores"></title> </head> <body> <table> <thead> <tr> <th>ID</th> <th>Nombre</th> <th>Apellido</th> <th>Última actualización</th> </tr> </thead> <tbody> <tr th:each="actor : ${actors}"> <td th:text="${actor.actor_id}"></td> <td th:text="${actor.first_name}"></td> <td th:text="${actor.last_name}"></td> <td th:text="${actor.last_update}"></td> </tr> </tbody> </table> </body> </html>
3. 额外优化建议
- 获取最大ID的方法
getMaxId()效率较低,每次都查询所有数据,建议通过JPA自定义查询实现:
然后在控制器中调用// 在ActorRepository中添加 @Query("SELECT MAX(a.actor_id) FROM Actor a") Integer findMaxActorId();actorRepository.findMaxActorId(),为空时返回0即可。
内容的提问来源于stack exchange,提问作者bdvazquez17
相关产品推荐
相关产品推荐

