You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 11:42:30