news 2026/5/1 8:31:07

Spring Boot 模板引擎全家桶:项目实战与多引擎共存方案

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Spring Boot 模板引擎全家桶:项目实战与多引擎共存方案

目录

  1. Enjoy 模板引擎集成
  2. Freemarker 模板引擎集成
  3. Thymeleaf 模板引擎集成
  4. Beetl 模板引擎集成
  5. 多模板引擎共存配置
  6. 模板文件示例

1. Spring Boot 集成 Enjoy 模板引擎

添加依赖

<dependency> <groupId>com.jfinal</groupId> <artifactId>enjoy</artifactId> <version>5.1.5</version> </dependency>

配置类

@Configuration public class EnjoyConfig { @Bean public EnjoyTemplateEngine enjoyTemplateEngine() { EnjoyTemplateEngine engine = new EnjoyTemplateEngine(); engine.setDevMode(true); engine.setBaseTemplatePath("templates/"); engine.addSharedFunction("/common/_layout.html"); engine.addSharedMethod(new MyEnjoyExt()); return engine; } @Bean public ViewResolver enjoyViewResolver() { EnjoyViewResolver resolver = new EnjoyViewResolver(); resolver.setSuffix(".html"); resolver.setContentType("text/html;charset=UTF-8"); resolver.setOrder(0); resolver.setEngine(enjoyTemplateEngine()); return resolver; } } // Enjoy 扩展方法 public class MyEnjoyExt { public String formatDate(Date date) { return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date); } }

控制器示例

@Controller public class UserController { @GetMapping("/user") public String user(Model model) { model.addAttribute("userName", "张三"); model.addAttribute("createTime", new Date()); return "user"; // 对应 templates/user.html } }

2. Spring Boot 集成 Freemarker 模板引擎

添加依赖

<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-freemarker</artifactId> </dependency>

配置文件 (application.yml)

spring: freemarker: suffix: .ftl charset: UTF-8 content-type: text/html cache: false template-loader-path: classpath:/templates/ settings: datetime_format: yyyy-MM-dd HH:mm:ss number_format: 0.## classic_compatible: true

控制器示例

@Controller public class ProductController { @GetMapping("/products") public String products(Model model) { List<Product> products = Arrays.asList( new Product("手机", 2999.00), new Product("电脑", 5999.00) ); model.addAttribute("products", products); return "product/list"; // 对应 templates/product/list.ftl } }

3. Spring Boot 集成 Thymeleaf 模板引擎

添加依赖

<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <dependency> <groupId>org.thymeleaf.extras</groupId> <artifactId>thymeleaf-extras-springsecurity5</artifactId> </dependency> <dependency> <groupId>org.thymeleaf.extras</groupId> <artifactId>thymeleaf-extras-java8time</artifactId> </dependency>

配置文件 (application.yml)

spring: thymeleaf: prefix: classpath:/templates/ suffix: .html mode: HTML encoding: UTF-8 servlet: content-type: text/html cache: false check-template-location: true

配置类

@Configuration public class ThymeleafConfig { @Bean public ITemplateResolver templateResolver() { SpringResourceTemplateResolver resolver = new SpringResourceTemplateResolver(); resolver.setPrefix("classpath:/templates/"); resolver.setSuffix(".html"); resolver.setTemplateMode(TemplateMode.HTML); resolver.setCharacterEncoding("UTF-8"); resolver.setCacheable(false); return resolver; } @Bean public SpringTemplateEngine templateEngine() { SpringTemplateEngine engine = new SpringTemplateEngine(); engine.setTemplateResolver(templateResolver()); engine.setEnableSpringELCompiler(true); Set<IDialect> dialects = new HashSet<>(); dialects.add(new SpringSecurityDialect()); dialects.add(new Java8TimeDialect()); engine.setAdditionalDialects(dialects); return engine; } }

控制器示例

@Controller public class ArticleController { @GetMapping("/articles") public String articles(Model model) { List<Article> articles = Arrays.asList( new Article("Spring Boot教程", "内容..."), new Article("Thymeleaf指南", "内容...") ); model.addAttribute("articles", articles); model.addAttribute("currentTime", LocalDateTime.now()); return "article/index"; } }

4. Spring Boot 集成 Beetl 模板引擎

添加依赖

<dependency> <groupId>com.ibeetl</groupId> <artifactId>beetl</artifactId> <version>3.15.10.RELEASE</version> </dependency>

配置类

@Configuration public class BeetlConfig { @Bean public BeetlGroupUtilConfiguration getBeetlGroupUtilConfiguration() { BeetlGroupUtilConfiguration beetlGroupUtilConfiguration = new BeetlGroupUtilConfiguration(); try { String root = "templates/"; ClasspathResourceLoader classpathResourceLoader = new ClasspathResourceLoader( BeetlConfig.class.getClassLoader(), root); beetlGroupUtilConfiguration.setResourceLoader(classpathResourceLoader); Properties properties = new Properties(); properties.setProperty("DELIMITER_STATEMENT_START", "@"); properties.setProperty("DELIMITER_STATEMENT_END", null); properties.setProperty("RESOURCE.autoCheck", "true"); beetlGroupUtilConfiguration.setConfigProperties(properties); return beetlGroupUtilConfiguration; } catch (Exception e) { throw new RuntimeException(e); } } @Bean public BeetlSpringViewResolver getBeetlSpringViewResolver() { BeetlSpringViewResolver resolver = new BeetlSpringViewResolver(); resolver.setConfig(getBeetlGroupUtilConfiguration()); resolver.setContentType("text/html;charset=UTF-8"); resolver.setSuffix(".btl"); resolver.setOrder(0); return resolver; } }

自定义函数

public class BeetlFunctions { public String formatPrice(Object price) { if (price == null) return "0.00"; return String.format("¥%.2f", Double.parseDouble(price.toString())); } public String substring(String str, int length) { if (str == null || str.length() <= length) { return str; } return str.substring(0, length) + "..."; } }

注册自定义函数

@Configuration public class BeetlExtConfig { @Autowired private BeetlGroupUtilConfiguration beetlConfig; @PostConstruct public void config() { GroupTemplate groupTemplate = beetlConfig.getGroupTemplate(); groupTemplate.registerFunction("formatPrice", new BeetlFunctions()); groupTemplate.registerFunction("substring", new BeetlFunctions()); } }

控制器示例

@Controller public class OrderController { @GetMapping("/orders") public String orders(Model model) { List<Order> orders = Arrays.asList( new Order("ORDER001", 199.99, new Date()), new Order("ORDER002", 299.99, new Date()) ); model.addAttribute("orders", orders); model.addAttribute("totalAmount", 499.98); return "order/list"; } }

5. 多模板引擎共存配置

@Configuration public class MultiTemplateConfig { @Bean @Order(1) public ThymeleafViewResolver thymeleafViewResolver() { ... } @Bean @Order(2) public FreeMarkerViewResolver freeMarkerViewResolver() { ... } @Bean @Order(3) public BeetlSpringViewResolver beetlSpringViewResolver() { ... } }

通过设置@Order值,可以控制不同模板引擎的视图解析优先级。


6. 模板文件示例

Enjoy 模板 (user.html)

<h1>用户信息</h1> <p>用户名:#{userName}</p> <p>创建时间:#(formatDate(createTime))</p>

Freemarker 模板 (product/list.ftl)

<h1>商品列表</h1> <table> <#list products as product> <tr> <td>${product.name}</td> <td>${product.price?string("0.00")}</td> </tr> </#list> </table>

Thymeleaf 模板 (article/index.html)

<h1>文章列表</h1> <div th:each="article : ${articles}"> <h3 th:text="${article.title}">标题</h3> <p th:text="${article.content}">内容</p> </div> <p>当前时间:<span th:text="${#temporals.format(currentTime, 'yyyy-MM-dd HH:mm')}"></span></p>

Beetl 模板 (order/list.btl)

<h1>订单列表</h1> <table> <% for(order in orders){ %> <tr> <td>${order.orderNo}</td> <td>${formatPrice(order.amount)}</td> <td>${order.createTime, dateFormat="yyyy-MM-dd"}</td> </tr> <% } %> </table> <p>总金额:${formatPrice(totalAmount)}</p>

✅ 以上就是 Spring Boot 集成四大主流模板引擎的完整配置和示例,开发者可以根据项目需求自由选择或共存使用。


版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/26 10:57:26

Mac用户注意:Apple Silicon芯片需开启Rosetta

Mac用户注意&#xff1a;Apple Silicon芯片需开启Rosetta 在苹果全面转向自研芯片的今天&#xff0c;越来越多开发者选择在M1、M2乃至M3系列Mac上本地运行AI大模型。这类设备凭借出色的能效比和集成化的神经引擎&#xff0c;在语音识别、图像生成等边缘计算场景中展现出强大潜…

作者头像 李华
网站建设 2026/4/24 15:45:12

Elasticsearch教程:项目中集成搜索功能的完整指南

从零构建高性能搜索&#xff1a;Elasticsearch实战进阶指南你有没有遇到过这样的场景&#xff1f;用户在电商App里搜“无线蓝牙耳机”&#xff0c;结果跳出一堆标题带“线”的有线耳机&#xff1b;或者日志系统查个错误码&#xff0c;页面转了十秒才出结果。这时候&#xff0c;…

作者头像 李华
网站建设 2026/4/20 7:01:48

零基础理解I2S协议:串行音频通信通俗解释

从零开始搞懂I2S&#xff1a;串行音频通信的底层逻辑与实战解析你有没有想过&#xff0c;当你用手机播放音乐时&#xff0c;那首动听的歌曲是如何从芯片内部一路“走”到耳机里的&#xff1f;它不是靠魔法&#xff0c;而是依赖一套精密的数字语言——I2S协议。这门“语言”不传…

作者头像 李华
网站建设 2026/4/25 14:05:22

鸿蒙在教育场景的落地实践:智慧课堂的分布式设计思路

摘要 这几年&#xff0c;“智慧课堂”在中小学、高校、职业院校里已经不是新概念了。从最早的电子白板、PPT 投屏&#xff0c;到现在的学生平板答题、课堂数据分析、课堂回放&#xff0c;技术一直在升级。 但在真正落地时&#xff0c;很多学校都会遇到同一个问题&#xff1a; 设…

作者头像 李华
网站建设 2026/4/30 2:34:44

用户协议签署:明确双方权利义务关系

Fun-ASR WebUI 技术解析&#xff1a;从语音识别到工程落地的全链路实践 在智能办公与AI普惠的时代背景下&#xff0c;语音识别技术正悄然改变人机交互的方式。无论是会议纪要自动生成、客服录音分析&#xff0c;还是教学内容归档&#xff0c;高质量的语音转文字能力已成为企业数…

作者头像 李华
网站建设 2026/5/1 6:54:42

一文说清嘉立创PCB布线中的阻抗匹配要点

嘉立创PCB布线实战&#xff1a;如何搞定高速信号的阻抗匹配&#xff1f; 在做一块4层板的时候&#xff0c;你有没有遇到过这样的情况——电路原理没问题&#xff0c;元器件也没选错&#xff0c;可一上电&#xff0c;千兆以太网就丢包&#xff0c;USB 3.0握手失败&#xff0c;D…

作者头像 李华