如何在HTML中访问Spring后端API控制器并展示返回数据
核心原因
你当前的控制器方法默认会将返回值直接序列化为JSON响应(如果类上加了@RestController注解,或者方法上加了@ResponseBody注解就会出现这个现象),这是后端接口的正常表现,不需要修改现有接口逻辑,单独编写HTML页面调用接口渲染数据即可。
具体实现步骤
新建静态HTML页面
Spring Boot默认会自动加载resources/static/、resources/public/目录下的静态HTML文件,你直接在对应目录下新建wildswimming.html即可,后续访问http://localhost:8080/wildswimming.html就能打开这个页面。编写页面结构、自定义样式与接口调用逻辑
页面里可以直接写CSS控制样式,用原生fetchAPI调用你写的接口,拿到JSON数据后动态生成页面内容即可,完整示例代码如下:
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>野泳点随机推荐</title> <style> /* 自定义样式可以按需修改 */ * { margin: 0; padding: 0; box-sizing: border-box; } .container { max-width: 1200px; margin: 2rem auto; padding: 0 1rem; } .page-title { font-size: 2rem; color: #1f2937; margin-bottom: 2rem; text-align: center; } .swim-card { border: 1px solid #e5e7eb; border-radius: 12px; padding: 1.5rem; margin-bottom: 1rem; box-shadow: 0 2px 8px rgba(0,0,0,0.06); transition: all 0.3s; } .swim-card:hover { box-shadow: 0 4px 12px rgba(0,0,0,0.1); transform: translateY(-2px); } .swim-card h3 { color: #165DFF; margin-bottom: 0.8rem; font-size: 1.3rem; } .swim-card p { color: #4b5563; line-height: 1.7; margin-bottom: 0.4rem; } .refresh-btn { display: block; margin: 0 auto 2rem; padding: 0.8rem 2rem; background: #165DFF; color: white; border: none; border-radius: 8px; font-size: 1rem; cursor: pointer; } .refresh-btn:hover { background: #0e42c9; } </style> </head> <body> <div class="container"> <h1 class="page-title">随机野泳点推荐</h1> <button class="refresh-btn" id="refreshBtn">换一批推荐</button> <div id="swimming-list"></div> </div> <script> const listContainer = document.getElementById('swimming-list'); const refreshBtn = document.getElementById('refreshBtn'); // 封装数据加载方法 async function loadSwimmingData() { listContainer.innerHTML = '<p style="text-align:center;color:#6b7280">数据加载中...</p>'; try { // 调用你现有的JSON接口,注意路径和控制器的RequestMapping前缀匹配 const res = await fetch('/wildswimming/getRandomWildSwimming'); const data = await res.json(); listContainer.innerHTML = ''; // 遍历返回的集合生成内容,注意字段名要和你WildSwimming实体类的属性一致 data.forEach(item => { const card = document.createElement('div'); card.className = 'swim-card'; card.innerHTML = ` <h3>${item.name || '未命名点位'}</h3> <p>📍 位置:${item.location || '暂无位置信息'}</p> <p>📝 描述:${item.description || '暂无点位描述'}</p> <p>💧 水质评分:${item.waterQuality || '暂无评分'}</p> `; listContainer.appendChild(card); }); } catch (err) { listContainer.innerHTML = '<p style="text-align:center;color:red">数据加载失败,请稍后重试</p>'; console.error('接口请求错误:', err); } } // 页面首次加载时拉取数据 document.addEventListener('DOMContentLoaded', loadSwimmingData); // 点击刷新按钮重新拉取数据 refreshBtn.addEventListener('click', loadSwimmingData); </script> </body> </html>
- (可选)访问接口路径直接跳转页面
如果你希望访问http://localhost:8080/wildswimming/getRandomWildSwimming时直接打开展示页面而非返回JSON,可以单独编写一个视图控制器,注意不要和提供JSON接口的方法写在同一个@RestController类中,示例代码:
@Controller @RequestMapping("/wildswimming") public class WildSwimmingPageController { @GetMapping("/getRandomWildSwimming") public String toSwimmingPage() { // 静态页面直接重定向到静态资源路径即可 return "redirect:/wildswimming.html"; // 如果使用Thymeleaf等模板引擎,就返回templates目录下的模板文件名,比如return "wildswimming"; } }
更推荐的实践是给所有JSON接口统一加
/api前缀,比如把现有接口路径改成/api/wildswimming/getRandomWildSwimming,页面映射路径保持普通路径,从根本上避免路径映射冲突。
补充说明
- 样式可以根据需求自由调整,不管是改卡片布局、配色、字体,还是加筛选、分页、收藏等交互,都可以直接在HTML的
<style>标签和<script>标签中编写逻辑实现。 - 如果项目集成了Thymeleaf、FreeMarker等模板引擎,逻辑完全一致,只是HTML文件需要放在
resources/templates/目录下,控制器方法返回对应的模板文件名即可。 - 如果你使用Vue、React等前端框架,核心逻辑不变:发起HTTP请求获取接口返回的JSON数据,将数据绑定到页面对应节点完成渲染。
内容的提问来源于stack exchange,提问作者Stephen Jankovic
相关产品推荐
相关产品推荐

