You need to enable JavaScript to run this app. Spring Boot如何将控制器Java对象经Thymeleaf传给JS绘制图表
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot如何将控制器Java对象经Thymeleaf传给JS绘制图表

问题根源排查

1. 注解冲突导致视图渲染完全失效

  • 类上标注的@RestController是Spring的组合注解,等价于@Controller + 类下所有方法默认携带@ResponseBody,所有方法的返回值都会被直接序列化为JSON响应,完全绕过Thymeleaf视图解析流程。这就是你此前使用ModelAndView传值没有达到预期效果的核心原因。
  • 修正逻辑:拆分Controller的职责,专门负责返回页面的类使用@Controller注解;返回JSON的REST接口单独保留@RestController,两类逻辑不要混在同一个类中。

2. 视图路由与模板位置不匹配

  • 当前测试方法配置的视图路径为message/test,对应模板需要放置在resources/templates/message/test.html路径下,若你直接使用resources/templates/index.html作为可视化页面,视图名称与实际模板位置不匹配,会导致Thymeleaf无法找到对应模板。

3. 前端JS逻辑断层

  • 内联脚本中调用了未定义的buildChart()方法,实际图表初始化逻辑写在外部chart-action.js的window.onload事件中,存在函数作用域不连通、加载时机不匹配的问题,控制台会直接抛出buildChart is not defined的脚本错误,导致图表无法正常渲染。
  • 现有代码将coronaTest同时赋值给newConfirmed和totalConfirmed两个变量,数据逻辑存在冗余错误。
修正后的实现方案

1. 控制器代码调整

拆分控制器职责,避免注解冲突:

// 专门负责视图渲染的控制器,使用@Controller而非@RestController
@Controller
public class DashboardViewController {

    @Autowired
    private RestTemplate restTemplate;

    private final String urlCorona = "https://api.covid19api.com/";

    // 映射到项目首页,返回index.html视图
    @GetMapping("/dashboard")
    public ModelAndView getCoronaDashboard() {
        ModelAndView mav = new ModelAndView("index");
        CoronaInformation coronaInfo = restTemplate.getForObject(urlCorona + "summary", CoronaInformation.class);
        // 传递完整的全球统计对象到视图层,不要只传递单个字段
        mav.addObject("globalStats", coronaInfo.getGlobal());
        return mav;
    }
}

// 原有的REST接口控制器,保留@RestController即可
@RestController
@RequestMapping("/api")
public class CoronaApiController {
    @Autowired
    private RestTemplate restTemplate;

    private final String urlCorona = "https://api.covid19api.com/";

    @GetMapping("/corona/summary")
    public CoronaInformation getAllCoronaInformations() {
        return restTemplate.getForObject(urlCorona + "summary", CoronaInformation.class);
    }
}

2. 前端代码调整

  • 修改页面内联Thymeleaf脚本,将模型数据挂载到全局JS作用域,供外部图表逻辑读取,移除不存在的函数调用:
<!-- body开头的内联脚本 -->
<script th:inline="javascript">
    // 把Thymeleaf模型中的统计数据转为全局可访问的JS变量
    window.coronaGlobalStats = /*[[${globalStats}]]*/ {
        newConfirmed: 0,
        totalConfirmed: 0,
        newDeaths: 0,
        totalDeaths: 0
    };
</script>
  • 修改chart-action.js,读取全局变量完成图表初始化:
window.addEventListener('load', function () {
    const ctx = document.getElementById('coronaChart');
    const stats = window.coronaGlobalStats;

    new Chart(ctx, {
        type: 'pie',
        data: {
            labels: [
                '新增确诊',
                '累计确诊',
                '新增死亡',
                '累计死亡'
            ],
            datasets: [{
                label: '全球疫情统计',
                data: [
                    stats.newConfirmed,
                    stats.totalConfirmed,
                    stats.newDeaths,
                    stats.totalDeaths
                ],
                backgroundColor: [
                    'rgb(255, 99, 132)',
                    'rgb(54, 162, 235)',
                    'rgb(255, 205, 86)',
                    'rgb(75, 192, 192)'
                ],
                hoverOffset: 4
            }]
        },
        options: {
            scales: {
                y: {
                    beginAtZero: true
                }
            }
        }
    });
});
调试注意事项
  • 检查项目pom.xml中是否正确引入Thymeleaf启动依赖,确认视图解析器默认配置为模板路径classpath:/templates/、文件后缀.html。
  • 访问页面时直接输入视图路由(如http://localhost:8080/dashboard),不要与原有REST接口的路由定义混用。

内容的提问来源于stack exchange,提问作者Alcyl

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.23 15:24:03