简介:这是一套基于SpringBoot+Thymeleaf构建的静态官网模板完整源码,面向Java Web初学者与前端入门开发者,解决快速搭建美观、可运行企业官网原型的实践需求。项目无需数据库即可一键启动,结构清晰、注释充分,支持灵活修改页面内容与样式,特别适合教学演示、课程设计或个人作品集部署。压缩包共362个文件,含26个HTML页面模板、16个CSS样式文件、10个JS交互脚本、18个Java控制器类(如IndexController、NewsController、ProductController等)及配套配置类(yml、xml),辅以大量图片资源(126个PNG+116个JPG)和少量视频(2个MP4)用于素材展示,整体大小为41.18MB。已有1116人学习下载,提供开箱即用的前后端整合方案、典型MVC分层结构示例及异常处理(MyExceptionHandler)、WebSocket(WebSocketServer)等扩展能力参考,助新手扎实理解SpringBoot Web开发全流程。
1. 这不是「静态官网」,而是一套可热加载、免数据库、开箱即用的 SpringBoot 官网骨架
你可能刚在 CSDN 上看到那篇标题为《springboot+thymeleaf+maven+html+css实现精美大方好看官网模板完整源码》的文章,点开 ZIP 包发现:没 SQL 文件、没 application.properties 里写死的 MySQL 密码、连 H2 都没配——但它真能mvn spring-boot:run启动,localhost:8080 刷出带轮播图、产品列表、新闻栏、响应式导航的完整官网页面。这不是前端静态页套了个 SpringBoot 外壳,而是 Thymeleaf 模板引擎深度参与 DOM 构建的典型实践:所有 HTML 页面都通过@Controller返回逻辑视图名,Thymeleaf 在服务端完成th:each循环渲染、th:if条件判断、th:fragment片段复用,CSS 用的是纯原生 flex + media query 实现三栏自适应,连鼠标悬停动画(:hover伪类)和字体渐变效果都写在static/css/style.css里,不依赖任何 JS 框架。它面向两类人:一是 Java 新手想绕过 MyBatis/Hibernate 复杂配置,直接理解「请求 → Controller → Model → Thymeleaf 渲染 HTML」的最小闭环;二是已有项目需快速交付企业官网,把src/main/resources/static/images/换成自家 banner 图,改几处th:text="${product.name}"就能上线。关键在于——它把「模板复用性」和「前端表现力」同时做实了,不是 demo 级玩具。
2. Thymeleaf 模板驱动的静态内容架构:从 fragment 复用到国际化占位符预埋
2.1 为什么选 Thymeleaf 而非 FreeMarker 或 JSP?核心是「前后端分离友好」与「HTML 原生可读性」
这个官网模板没用 JSP(已淘汰)、没选 FreeMarker(语法偏模板引擎专属),坚持用 Thymeleaf,根本原因在于其th:*属性天然嵌入 HTML 标签内。打开src/main/resources/templates/index.html,你会看到:
<!doctype html> <html lang="zh-cn" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title th:text="#{index.title}">企业官网</title> <link rel="stylesheet" th:href="@{/css/style.css}"> </head> <body> <header th:replace="fragments/header :: header"></header> <main class="container"> <section th:replace="fragments/banner :: banner"></section> <section th:replace="fragments/products :: products"></section> </main> <footer th:replace="fragments/footer :: footer"></footer> </body> </html>提示:
th:replace是 Thymeleaf 最关键的复用机制,它把fragments/下的独立 HTML 片段(如header.html)注入当前位置,且片段内可定义th:fragment="header"显式声明入口点。这比 JSP 的<jsp:include>更灵活,因为片段本身也是合法 HTML,设计师用浏览器直接打开fragments/header.html就能看到样式效果,无需启动 SpringBoot。
对比 FreeMarker 的<#include "header.ftl">,后者文件后缀.ftl表明它已脱离 HTML 生态,前端无法独立预览;而 Thymeleaf 的.html后缀让整个模板体系保持「所见即所得」——这是新手上手快的核心设计选择。
2.2fragments/目录结构解析:header、banner、products、footer 四大复用单元
项目中src/main/resources/templates/fragments/目录下有 4 个核心片段文件,每个都遵循「结构语义化 + CSS 类命名规范」原则:
header.html:含导航栏<nav>,使用th:each="menu : ${menus}"动态生成菜单项,数据来自IndexController的model.addAttribute("menus", Arrays.asList(...))banner.html:轮播图区域,用th:each="slide : ${banners}"渲染List<Banner>,Banner 对象仅含title、desc、imageUrl三个字段,无数据库映射products.html:三列产品展示区,th:each="product : ${products}"遍历List<Product>,每个Product类含name、summary、iconUrl,图标路径为static/images/product-icon-1.pngfooter.html:版权信息与联系方式,th:text="${site.copyright}"绑定配置项,避免硬编码
这些片段被index.html、product.html、news.html共同引用,修改fragments/header.html即全局生效。实际开发中,我一般会把menus数据抽离到application.yml中:
site: menus: - name: 首页 url: / - name: 产品中心 url: /products - name: 新闻动态 url: /news - name: 关于我们 url: /about然后在IndexController中通过@Value("${site.menus}")注入,比硬编码更易维护。
2.3 国际化占位符预埋:#{index.title}背后的 message.properties 机制
虽然摘要说「不需要数据库」,但模板已为国际化预留接口。观察index.html中的<title th:text="#{index.title}">,它指向src/main/resources/messages.properties:
# messages.properties(中文) index.title=XX科技有限公司官网 index.welcome=欢迎访问我们的官方网站 product.list.title=核心产品对应英文版messages_en.properties:
# messages_en.properties index.title=XX Technology Co., Ltd. Official Website index.welcome=Welcome to our official website product.list.title=Core ProductsSpringBoot 默认启用MessageSource自动扫描messages_*.properties。要触发切换,只需在 URL 后加?lang=en(如http://localhost:8080/?lang=en),或在application.yml中配置默认语言:
spring: messages: basename: messages encoding: UTF-8 cache-duration: 3600注意:
th:text="#{xxx}"中的键名必须与 properties 文件中完全一致,大小写敏感。若页面显示??index.title??,说明messages.properties编码不是 UTF-8(用 Notepad++ 保存为 UTF-8 无 BOM 格式可解决)。
3. Maven 构建与静态资源管理:从阿里云镜像加速到 CSS 响应式断点实战
3.1pom.xml关键依赖解析:为什么只引入spring-boot-starter-thymeleaf而非spring-boot-starter-webflux
打开pom.xml,核心依赖只有三项:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency>没有spring-boot-starter-data-jpa、没有mybatis-spring-boot-starter,印证了「免数据库」承诺。spring-boot-starter-thymeleaf自动配置了TemplateResolver、SpringTemplateEngine和ThymeleafViewResolver,无需手动注册 Bean。特别注意spring-boot-devtools:它启用热重载(Hot Reload),修改templates/下 HTML 或static/css/下 CSS 后,刷新浏览器即可生效,省去重启服务时间——这对前端样式调试至关重要。
Maven 仓库配置方面,国内用户务必修改~/.m2/settings.xml,添加阿里云镜像(否则mvn clean package可能卡在下载thymeleaf-spring5):
<mirrors> <mirror> <id>aliyunmaven</id> <mirrorOf>*</mirrorOf> <name>阿里云公共仓库</name> <url>https://maven.aliyun.com/repository/public</url> </mirror> </mirrors>3.2static/目录下的 CSS 工程实践:三行模式布局与:hover伪类动画实现
官网的视觉效果主要由src/main/resources/static/css/style.css驱动。该文件采用「移动优先」策略,关键 CSS 规则如下:
/* 三行模式:header + main + footer */ body { margin: 0; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; } header, footer { background: #2c3e50; color: white; padding: 1rem 0; } main { min-height: calc(100vh - 200px); /* 减去 header/footer 高度 */ } /* 响应式三栏产品展示 */ .products-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 1.5rem; padding: 2rem 1rem; } /* 鼠标悬停动画:卡片上浮 + 阴影增强 */ .product-card { background: white; border-radius: 8px; overflow: hidden; box-shadow: 0 2px 4px rgba(0,0,0,0.1); transition: all 0.3s ease; } .product-card:hover { transform: translateY(-5px); box-shadow: 0 8px 16px rgba(0,0,0,0.15); } /* 字体渐变效果(现代 CSS 写法) */ .gradient-title { background: linear-gradient(45deg, #ff6b6b, #4ecdc4, #44b5b1); -webkit-background-clip: text; -webkit-text-fill-color: transparent; }提示:
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr))是「三行模式」的核心——在宽度 ≥300px 时每行放 1 个卡片,≥600px 放 2 个,≥900px 放 3 个,自动适配屏幕。transition: all 0.3s ease与:hover配合,实现平滑上浮动画,比 jQuery 的animate()更轻量。
3.3application.yml静态资源配置:禁用模板缓存与设置默认编码
为确保开发阶段 HTML/CSS 修改即时生效,application.yml中必须关闭 Thymeleaf 缓存:
spring: thymeleaf: cache: false # 开发环境务必设为 false enabled: true prefix: classpath:/templates/ suffix: .html encoding: UTF-8 servlet: content-type: text/html resources: static-locations: classpath:/static/ add-mappings: true若忽略cache: false,修改index.html后刷新页面仍显示旧内容,新手常在此卡住。另外,encoding: UTF-8防止中文乱码,static-locations明确指定静态资源根目录为classpath:/static/,对应src/main/resources/static/。
4. Controller 层数据供给逻辑:从@Controller返回视图到WebResultMap统一响应封装
4.1IndexController的极简数据模型:Model对象如何承载首页所需全部数据
IndexController.java是整个官网的数据中枢,其index()方法代码不足 20 行:
@Controller public class IndexController { @GetMapping("/") public String index(Model model) { // 轮播图数据(纯内存 List) List<Banner> banners = Arrays.asList( new Banner("AI平台", "一站式AI开发与部署平台", "/images/banner-1.jpg"), new Banner("云服务", "高可用、弹性伸缩的云基础设施", "/images/banner-2.jpg") ); model.addAttribute("banners", banners); // 产品列表 List<Product> products = Arrays.asList( new Product("智能客服", "基于NLP的多轮对话系统", "/images/icon-customer.png"), new Product("数据分析", "可视化BI报表与实时监控", "/images/icon-analytics.png") ); model.addAttribute("products", products); // 导航菜单(来自 application.yml 配置) model.addAttribute("menus", getMenusFromConfig()); return "index"; // 对应 templates/index.html } }这里的关键是:所有数据都是new Banner(...)构造的内存对象,不查数据库。Banner和Product是普通 POJO,仅含 getter/setter,无 JPA 注解。这种设计让新手一眼看懂「Controller 怎么把数据塞给模板」,也方便后续拓展——当需要接入数据库时,只需把Arrays.asList(...)替换为productService.findAll()即可,模板层th:each语法完全不用改。
4.2WebResultMap:轻量级统一响应格式的设计意图与使用边界
项目中存在WebResultMap.class,它是一个 Map 子类,用于封装 AJAX 接口返回值:
public class WebResultMap extends HashMap<String, Object> { public WebResultMap success(String msg) { this.put("code", 200); this.put("msg", msg); this.put("data", new HashMap<>()); return this; } public WebResultMap data(Object data) { this.put("data", data); return this; } }但它并未在官网 HTML 渲染流程中使用。IndexController返回String视图名,走 Thymeleaf 渲染;而NewsController中的@ResponseBody方法才用WebResultMap:
@RestController public class NewsController { @GetMapping("/api/news/latest") public WebResultMap getLatestNews() { return new WebResultMap() .success("获取成功") .data(Arrays.asList( new News("公司获AI创新奖", "2023-10-01"), new News("新版本V2.1发布", "2023-09-15") )); } }提示:
WebResultMap是为未来「后台管理界面」预留的 AJAX 响应结构,当前官网静态页不调用/api/接口。若你想在首页用 JS 动态加载新闻,可在index.html中加:<script th:inline="javascript"> $.get('/api/news/latest', function(res) { if (res.code === 200) { $('#news-list').html( res.data.map(n => `<li>${n.title} <small>${n.date}</small></li>`).join('') ); } }); </script>此时
WebResultMap才真正发挥作用。
4.3MyBasicErrorController:自定义 404/500 页面的 Thymeleaf 实现
SpringBoot 默认错误页简陋,本项目通过MyBasicErrorController提供友好提示:
@Controller public class MyBasicErrorController implements ErrorController { @RequestMapping("/error") public String handleError(HttpServletRequest request, Model model) { Integer statusCode = (Integer) request.getAttribute(RequestDispatcher.ERROR_STATUS_CODE); model.addAttribute("statusCode", statusCode); model.addAttribute("errorMsg", statusCode == 404 ? "页面未找到" : "服务器内部错误"); return "error"; // 对应 templates/error.html } @Override public String getErrorPath() { return "/error"; } }对应的templates/error.html使用 Thymeleaf 渲染状态码和提示语:
<div class="error-container"> <h1 th:text="${statusCode}">404</h1> <p th:text="${errorMsg}">页面未找到</p> <a href="/" class="btn">返回首页</a> </div>这比 SpringBoot 默认的白页更专业,且完全复用现有 Thymeleaf 机制,无需额外技术栈。
5. 新手快速上手四步法:替换图片、修改文案、调整 CSS、验证响应式
5.1 替换官网 Banner 图片与产品图标:static/images/目录操作指南
所有静态图片存放在src/main/resources/static/images/,结构清晰:
images/ ├── banner-1.jpg ← 首页轮播图1 ├── banner-2.jpg ← 首页轮播图2 ├── icon-customer.png ← 产品图标1 ├── icon-analytics.png ← 产品图标2 └── logo.png ← 顶部 Logo替换步骤:
- 准备新图片:Banner 图建议尺寸 1200×400px(宽高比 3:1),图标建议 64×64px PNG 透明背景
- 覆盖同名文件:将新
banner-1.jpg拖入static/images/,覆盖原文件 - 修改
IndexController中的路径(若文件名变更):new Banner("AI平台", "一站式AI开发与部署平台", "/images/new-banner-1.jpg") - 启动项目,访问
http://localhost:8080查看效果
注意:图片路径以
/images/开头,表示从static/目录起始,Thymeleaf 会自动映射为http://localhost:8080/images/xxx.jpg。
5.2 修改文案与 SEO 元信息:messages.properties与index.html双轨更新
官网文案分两类:
- 动态文案(支持国际化):存于
messages.properties,如index.title=新公司名称官网 - 静态文案(不需翻译):直接写在
index.html中,如<h2>关于我们</h2>中的「关于我们」
SEO 关键元信息在index.html<head>内:
<meta name="description" content="XX科技提供AI平台、云服务等解决方案" th:attr="content=#{index.description}"> <meta name="keywords" content="AI,云计算,大数据" th:attr="content=#{index.keywords}">因此需同步修改:
messages.properties中新增:index.description=XX科技提供AI平台、云服务等解决方案 index.keywords=AI,云计算,大数据index.html中th:attr="content=#{...}"引用对应键名
5.3 调整 CSS 断点与悬停效果:style.css中可安全修改的参数表
static/css/style.css中以下参数可按需调整,不影响整体结构:
| CSS 属性 | 当前值 | 推荐范围 | 效果说明 |
|---|---|---|---|
.products-grid gap | 1.5rem | 1rem ~ 2rem | 控制产品卡片间距 |
.product-card:hover transform | translateY(-5px) | -3px ~ -10px | 悬停上浮幅度 |
@media (max-width: 768px) | grid-template-columns: 1fr | 可删减此媒体查询 | 移动端单列显示 |
.gradient-title background | linear-gradient(45deg, #ff6b6b, #4ecdc4, #44b5b1) | 替换为品牌色 HEX | 字体渐变色 |
修改后保存 CSS 文件,因spring.thymeleaf.cache=false,刷新浏览器立即生效。
5.4 验证响应式与跨浏览器兼容性:Chrome DevTools 设备模拟与真实手机测试
最后一步必须验证:
- Chrome DevTools:F12 打开开发者工具 → 点击左上角「Toggle device toolbar」→ 选择 iPhone SE / iPad / Responsive 拉伸窗口,检查导航栏是否折叠、轮播图是否适配、产品网格是否换行
- 真实手机访问:确保电脑与手机在同一局域网,启动项目后,在手机浏览器输入
http://[电脑IP]:8080(如http://192.168.1.100:8080),测试触摸交互(如轮播图手势滑动、导航菜单点击展开)
若移动端文字过小,检查index.html中<meta name="viewport">是否存在且content="width=device-width, initial-scale=1.0"未被注释。这是 HTML5 响应式基石,缺之则所有 CSS 媒体查询失效。
CSS 伪类选择器:hover在触摸设备上无效果,故产品卡片悬停动画在手机端自动降级为静态样式——这正是「渐进增强」设计思想的体现,无需额外 JS 适配。
本文还有配套的精品资源,点击获取