如何将@Controller替换为@RestController结合AJAX实现页面自动加载教师表格数据
基于@RestController+AJAX的异步加载改造实现
1. 控制器层改造
把原来类上的@Controller注解直接换成@RestController,类级别的路径映射/teacherController保持不变。原来的单个/check接口同时承担两个职责:查教师数据、塞模型传给视图、返回整个页面,现在拆成两个独立接口,职责完全分开:
- 页面接口:不再查询数据,只负责返回教师列表的HTML视图
- 数据接口:保留原TeacherService的查询逻辑,直接把查询到的教师列表当返回值,由Spring自动转成JSON给前端
示例代码参考:
@RestController @RequestMapping("/teacherController") public class TeacherController { // 构造器注入TeacherService,规避字段注入的潜在问题 private final TeacherService teacherService; public TeacherController(TeacherService teacherService) { this.teacherService = teacherService; } // 专门返回教师列表页面的接口 @GetMapping("/page") public ModelAndView toTeacherListPage() { // 对应templates目录下的teacher/list.html视图 return new ModelAndView("teacher/list"); } // 专门返回教师列表JSON数据的接口 @GetMapping("/list") public List<Teacher> getTeacherData() { // 保留原有的查询逻辑,不需要操作ModelAndView return teacherService.queryAllTeachers(); } }
2. 前端页面结构调整
把原来Thymeleaf用th:each遍历后端传入teachers集合渲染表格行的代码删掉,只保留固定的表头结构,给表格的主体tbody加个唯一id,作为后续动态渲染数据的挂载点:
<table> <thead> <tr> <th>教师ID</th> <th>姓名</th> <th>职位</th> </tr> </thead> <!-- 留空的tbody,后续异步拿数据后动态塞行 --> <tbody id="teacherTableBody"> </tbody> </table>
3. 异步加载逻辑实现
在页面底部加一段原生JS,不用引入jQuery或者其他前端框架,监听DOM加载完成事件,自动发请求拿教师数据,遍历生成表格行塞到刚才留的tbody节点里就行:
// 等页面DOM结构加载完成自动执行 document.addEventListener('DOMContentLoaded', async () => { // 请求刚才写的/list接口拿JSON数据 const res = await fetch('/teacherController/list'); const teacherList = await res.json(); // 拿到对应的tbody节点 const tbody = document.getElementById('teacherTableBody'); // 遍历教师列表生成行 teacherList.forEach(teacher => { const tr = document.createElement('tr'); tr.innerHTML = ` <td>${teacher.id}</td> <td>${teacher.name}</td> <td>${teacher.position}</td> `; tbody.appendChild(tr); }); });
关键注意点
@RestController下所有方法默认会把返回值当JSON响应处理,所以返回页面的接口一定要明确返回ModelAndView对象,别直接返回字符串形式的视图名,不然字符串会被直接当响应内容输出到浏览器,不会走视图解析流程- 原来的/check接口如果要保留兼容,要做好路径区分,别和返回JSON的接口用同一个路径,避免语义冲突
- 整个链路是同域调用,不需要额外配置跨域规则,只要前端请求的路径和后端接口路径完全匹配就行
内容的提问来源于stack exchange,提问作者Jack
相关产品推荐
相关产品推荐

