本文目录导读:

我来为您提供一个完整的Java模板引擎实现案例,包含核心功能和示例:
简单的模板引擎实现
import java.util.*;
import java.util.regex.*;
/**
* 简单的模板引擎实现
*/
public class SimpleTemplateEngine {
// 变量替换模式:${variableName}
private static final Pattern VARIABLE_PATTERN =
Pattern.compile("\\$\\{([^}]+)\\}");
// 条件判断模式:{#if condition}...{/if}
private static final Pattern IF_PATTERN =
Pattern.compile("\\{#if\\s+([^}]+)\\}(.*?)\\{/if\\}", Pattern.DOTALL);
// 循环模式:{#foreach item in list}...{/foreach}
private static final Pattern FOREACH_PATTERN =
Pattern.compile("\\{#foreach\\s+(\\w+)\\s+in\\s+(\\w+)\\}(.*?)\\{/foreach\\}", Pattern.DOTALL);
private Map<String, Object> context = new HashMap<>();
/**
* 设置模板变量
*/
public void setVariable(String name, Object value) {
context.put(name, value);
}
/**
* 批量设置模板变量
*/
public void setVariables(Map<String, Object> variables) {
context.putAll(variables);
}
/**
* 渲染模板
*/
public String render(String template) {
if (template == null) {
return "";
}
String result = template;
// 处理条件判断
result = processIfBlocks(result);
// 处理循环
result = processForeachBlocks(result);
// 处理变量替换
result = processVariables(result);
return result;
}
/**
* 处理条件判断
*/
private String processIfBlocks(String template) {
Matcher matcher = IF_PATTERN.matcher(template);
StringBuffer sb = new StringBuffer();
while (matcher.find()) {
String condition = matcher.group(1).trim();
String content = matcher.group(2);
String replacement = evaluateCondition(condition) ? content : "";
matcher.appendReplacement(sb, Matcher.quoteReplacement(replacement));
}
matcher.appendTail(sb);
return sb.toString();
}
/**
* 评估条件表达式
*/
private boolean evaluateCondition(String condition) {
// 简化版条件评估
if (condition.contains("==")) {
String[] parts = condition.split("==");
return getVariableValue(parts[0].trim())
.equals(getVariableValue(parts[1].trim()));
} else if (condition.contains("!=")) {
String[] parts = condition.split("!=");
return !getVariableValue(parts[0].trim())
.equals(getVariableValue(parts[1].trim()));
} else if (condition.contains(">")) {
String[] parts = condition.split(">");
try {
double left = Double.parseDouble(getVariableValue(parts[0].trim()));
double right = Double.parseDouble(getVariableValue(parts[1].trim()));
return left > right;
} catch (NumberFormatException e) {
return false;
}
} else if (condition.contains("<")) {
String[] parts = condition.split("<");
try {
double left = Double.parseDouble(getVariableValue(parts[0].trim()));
double right = Double.parseDouble(getVariableValue(parts[1].trim()));
return left < right;
} catch (NumberFormatException e) {
return false;
}
}
// 直接变量判断
return Boolean.parseBoolean(getVariableValue(condition));
}
/**
* 处理循环
*/
private String processForeachBlocks(String template) {
Matcher matcher = FOREACH_PATTERN.matcher(template);
StringBuffer sb = new StringBuffer();
while (matcher.find()) {
String itemName = matcher.group(1).trim();
String listName = matcher.group(2).trim();
String content = matcher.group(3);
StringBuilder replacement = new StringBuilder();
Object listObj = context.get(listName);
if (listObj instanceof Collection) {
Collection<?> list = (Collection<?>) listObj;
for (Object item : list) {
Map<String, Object> oldContext = new HashMap<>(context);
context.put(itemName, item);
replacement.append(processVariables(content));
context.clear();
context.putAll(oldContext);
}
} else if (listObj != null && listObj.getClass().isArray()) {
Object[] array = (Object[]) listObj;
for (Object item : array) {
Map<String, Object> oldContext = new HashMap<>(context);
context.put(itemName, item);
replacement.append(processVariables(content));
context.clear();
context.putAll(oldContext);
}
}
matcher.appendReplacement(sb, Matcher.quoteReplacement(replacement.toString()));
}
matcher.appendTail(sb);
return sb.toString();
}
/**
* 处理变量替换
*/
private String processVariables(String template) {
Matcher matcher = VARIABLE_PATTERN.matcher(template);
StringBuffer sb = new StringBuffer();
while (matcher.find()) {
String variablePath = matcher.group(1).trim();
String value = getVariableValue(variablePath);
matcher.appendReplacement(sb, Matcher.quoteReplacement(value));
}
matcher.appendTail(sb);
return sb.toString();
}
/**
* 获取变量值
*/
private String getVariableValue(String path) {
// 支持点号访问对象属性
String[] parts = path.split("\\.");
Object value = context.get(parts[0]);
if (value == null) {
return "null";
}
// 对象属性访问
if (parts.length > 1) {
for (int i = 1; i < parts.length; i++) {
if (value instanceof Map) {
value = ((Map<?, ?>) value).get(parts[i]);
} else {
// 使用反射访问属性
try {
String getter = "get" + parts[i].substring(0, 1).toUpperCase()
+ parts[i].substring(1);
value = value.getClass().getMethod(getter).invoke(value);
} catch (Exception e) {
return "null";
}
}
}
}
return value != null ? value.toString() : "null";
}
}
/**
* 用户类(用于测试)
*/
class User {
private String name;
private int age;
private String email;
public User(String name, int age, String email) {
this.name = name;
this.age = age;
this.email = email;
}
public String getName() { return name; }
public int getAge() { return age; }
public String getEmail() { return email; }
@Override
public String toString() {
return name;
}
}
更完整的模板引擎(支持更多功能)
import java.io.*;
import java.nio.file.*;
import java.util.*;
import java.util.regex.*;
/**
* 高级模板引擎
*/
public class AdvancedTemplateEngine {
private static final Map<String, Pattern> PATTERNS = new HashMap<>();
private static final String CACHE_DIR = "template_cache";
static {
// 变量: {{ varName }}
PATTERNS.put("variable", Pattern.compile("\\{\\{\\s*([^}]+?)\\s*\\}\\}"));
// 循环: {% for item in items %}
PATTERNS.put("for", Pattern.compile("\\{%\\s*for\\s+(\\w+)\\s+in\\s+(\\w+)\\s*%\\}(.*?)\\{%\\s*endfor\\s*%\\}", Pattern.DOTALL));
// 条件: {% if condition %}
PATTERNS.put("if", Pattern.compile("\\{%\\s*if\\s+(.+?)\\s*%\\}(.*?)(\\{%\\s*else\\s*%\\}(.*?))?\\{%\\s*endif\\s*%\\}", Pattern.DOTALL));
// 注释: {# comment #}
PATTERNS.put("comment", Pattern.compile("\\{#.*?#\\}", Pattern.DOTALL));
// 包含: {% include "filename" %}
PATTERNS.put("include", Pattern.compile("\\{%\\s*include\\s+[\"'](.+?)[\"']\\s*%\\}"));
}
private Map<String, Object> globalContext = new HashMap<>();
private Map<String, String> templateCache = new HashMap<>();
/**
* 设置全局变量
*/
public void setGlobalVariable(String name, Object value) {
globalContext.put(name, value);
}
/**
* 渲染字符串模板
*/
public String render(String template, Map<String, Object> context) {
Map<String, Object> mergedContext = new HashMap<>(globalContext);
mergedContext.putAll(context);
String result = template;
// 1. 移除注释
result = PATTERNS.get("comment").matcher(result).replaceAll("");
// 2. 处理包含指令
result = processIncludes(result, mergedContext);
// 3. 处理循环
result = processLoops(result, mergedContext);
// 4. 处理条件
result = processConditionals(result, mergedContext);
// 5. 处理变量
result = processVariables(result, mergedContext);
return result;
}
/**
* 从文件渲染模板
*/
public String renderFile(String templatePath, Map<String, Object> context) throws IOException {
String template = loadTemplate(templatePath);
return render(template, context);
}
/**
* 加载模板文件(带缓存)
*/
private String loadTemplate(String path) throws IOException {
if (templateCache.containsKey(path)) {
return templateCache.get(path);
}
String content = new String(Files.readAllBytes(Paths.get(path)));
templateCache.put(path, content);
return content;
}
/**
* 处理包含指令
*/
private String processIncludes(String template, Map<String, Object> context) {
Matcher matcher = PATTERNS.get("include").matcher(template);
StringBuffer sb = new StringBuffer();
while (matcher.find()) {
String file = matcher.group(1);
try {
String includedContent = loadTemplate(file);
String rendered = render(includedContent, context);
matcher.appendReplacement(sb, Matcher.quoteReplacement(rendered));
} catch (IOException e) {
matcher.appendReplacement(sb, "<!-- Error including: " + file + " -->");
}
}
matcher.appendTail(sb);
return sb.toString();
}
/**
* 处理循环
*/
private String processLoops(String template, Map<String, Object> context) {
Matcher matcher = PATTERNS.get("for").matcher(template);
StringBuffer sb = new StringBuffer();
while (matcher.find()) {
String itemVar = matcher.group(1);
String listVar = matcher.group(2);
String content = matcher.group(3);
Object listObj = context.get(listVar);
StringBuilder result = new StringBuilder();
if (listObj instanceof Collection) {
for (Object item : (Collection<?>) listObj) {
Map<String, Object> newContext = new HashMap<>(context);
newContext.put(itemVar, item);
newContext.put("loop.index", ((Collection<?>) listObj).size());
result.append(processVariables(content, newContext));
}
} else if (listObj instanceof Map) {
Map<?, ?> map = (Map<?, ?>) listObj;
for (Map.Entry<?, ?> entry : map.entrySet()) {
Map<String, Object> newContext = new HashMap<>(context);
newContext.put(itemVar, entry.getValue());
newContext.put("loop.key", entry.getKey());
result.append(processVariables(content, newContext));
}
}
matcher.appendReplacement(sb, Matcher.quoteReplacement(result.toString()));
}
matcher.appendTail(sb);
return sb.toString();
}
/**
* 处理条件语句
*/
private String processConditionals(String template, Map<String, Object> context) {
Matcher matcher = PATTERNS.get("if").matcher(template);
StringBuffer sb = new StringBuffer();
while (matcher.find()) {
String condition = matcher.group(1).trim();
String thenContent = matcher.group(2);
String elseContent = matcher.group(4) != null ? matcher.group(4) : "";
boolean result = evaluateCondition(condition, context);
String replacement = result ? thenContent : elseContent;
matcher.appendReplacement(sb, Matcher.quoteReplacement(replacement));
}
matcher.appendTail(sb);
return sb.toString();
}
/**
* 评估条件
*/
private boolean evaluateCondition(String condition, Map<String, Object> context) {
condition = condition.trim();
// 处理 NOT 操作
if (condition.startsWith("not ")) {
return !evaluateCondition(condition.substring(4), context);
}
// 处理 AND
if (condition.contains(" and ")) {
String[] parts = condition.split("\\s+and\\s+");
for (String part : parts) {
if (!evaluateCondition(part, context)) {
return false;
}
}
return true;
}
// 处理 OR
if (condition.contains(" or ")) {
String[] parts = condition.split("\\s+or\\s+");
for (String part : parts) {
if (evaluateCondition(part, context)) {
return true;
}
}
return false;
}
// 处理比较操作
if (condition.matches(".*\\s*(==|!=|>=|<=|>|<)\\s*.*")) {
String[] parts = condition.split("\\s*(==|!=|>=|<=|>|<)\\s*");
if (parts.length == 2) {
Object left = getValue(parts[0].trim(), context);
Object right = getValue(parts[1].trim(), context);
if (left instanceof Number && right instanceof Number) {
double l = ((Number) left).doubleValue();
double r = ((Number) right).doubleValue();
if (condition.contains(">")) return l > r;
if (condition.contains("<")) return l < r;
if (condition.contains(">=")) return l >= r;
if (condition.contains("<=")) return l <= r;
}
return left != null && left.equals(right);
}
}
// 检查变量是否存在且为true
Object value = getValue(condition, context);
if (value instanceof Boolean) {
return (Boolean) value;
}
return value != null && !value.toString().isEmpty();
}
/**
* 获取值
*/
private Object getValue(String path, Map<String, Object> context) {
if (path.startsWith("'") && path.endsWith("'")) {
return path.substring(1, path.length() - 1);
}
String[] parts = path.split("\\.");
Object value = context.get(parts[0]);
for (int i = 1; i < parts.length && value != null; i++) {
if (value instanceof Map) {
value = ((Map<?, ?>) value).get(parts[i]);
} else {
try {
String getter = "get" + Character.toUpperCase(parts[i].charAt(0)) + parts[i].substring(1);
value = value.getClass().getMethod(getter).invoke(value);
} catch (Exception e) {
return null;
}
}
}
return value;
}
/**
* 处理变量
*/
private String processVariables(String template, Map<String, Object> context) {
Matcher matcher = PATTERNS.get("variable").matcher(template);
StringBuffer sb = new StringBuffer();
while (matcher.find()) {
String expression = matcher.group(1).trim();
Object value = getValue(expression, context);
String replacement = value != null ? value.toString() : "";
matcher.appendReplacement(sb, Matcher.quoteReplacement(replacement));
}
matcher.appendTail(sb);
return sb.toString();
}
}
测试类
import java.util.*;
public class TemplateEngineTest {
public static void main(String[] args) {
testSimpleTemplate();
testAdvancedTemplate();
}
private static void testSimpleTemplate() {
System.out.println("=== 简单模板引擎测试 ===");
// 创建模板引擎
SimpleTemplateEngine engine = new SimpleTemplateEngine();
// 准备数据
Map<String, Object> context = new HashMap<>();
context.put("name", "张三");
context.put("age", 25);
List<User> users = Arrays.asList(
new User("李四", 28, "lisi@example.com"),
new User("王五", 32, "wangwu@example.com"),
new User("赵六", 22, "zhaoliu@example.com")
);
context.put("users", users);
engine.setVariables(context);
// 模板字符串
String template = """
欢迎,${name}!
你的年龄是${age}岁。
{#if age >= 18}
<h2>你已是成年人</h2>
{/if}
<h3>用户列表:</h3>
{#foreach user in users}
<p>用户名:${user.name},年龄:${user.age},邮箱:${user.email}</p>
{/foreach}
""";
// 渲染
String result = engine.render(template);
System.out.println(result);
}
private static void testAdvancedTemplate() {
System.out.println("\n=== 高级模板引擎测试 ===");
AdvancedTemplateEngine engine = new AdvancedTemplateEngine();
// 设置全局变量
engine.setGlobalVariable("siteName", "MyWebsite");
engine.setGlobalVariable("version", "1.0.0");
// 准备数据
Map<String, Object> context = new HashMap<>();
context.put("pageTitle", "用户管理");
context.put("isLoggedIn", true);
context.put("username", "admin");
Map<String, Object> settings = new HashMap<>();
settings.put("itemsPerPage", 10);
settings.put("showEmail", false);
context.put("settings", settings);
List<User> allUsers = Arrays.asList(
new User("张三", 25, "zhangsan@example.com"),
new User("李四", 28, "lisi@example.com"),
new User("王五", 32, "wangwu@example.com")
);
context.put("allUsers", allUsers);
String template = """
<!-- 页面模板 -->
<!DOCTYPE html>
<html>
<head>
<title>{{ pageTitle }} - {{ siteName }}</title>
</head>
<body>
{# if isLoggedIn #}
<h1>欢迎回来,{{ username }}!</h1>
{# else #}
<h1>请登录</h1>
{# endif #}
{% if settings.showEmail %}
<p>显示邮箱:是</p>
{% else %}
<p>显示邮箱:否</p>
{% endif %}
<h2>用户列表(每页显示{{ settings.itemsPerPage }}条):</h2>
{% for user in allUsers %}
<div class="user-item">
<span>用户名:{{ user.name }}</span>
<span>年龄:{{ user.age }}</span>
{% if settings.showEmail %}
<span>邮箱:{{ user.email }}</span>
{% endif %}
</div>
{% endfor %}
<footer>
<p>© 2023 {{ siteName }} v{{ version }}</p>
</footer>
</body>
</html>
""";
String result = engine.render(template, context);
System.out.println(result);
}
}
说明
功能特性
- 变量替换:支持
${variable}和{{ variable }}两种语法 - 条件判断:支持
{#if condition}...{/if}和{% if condition %}语法 - 循环遍历:支持
{#foreach item in list}...{/foreach}和{% for item in list %}语法 - 对象属性访问:支持点号语法
user.name - 条件表达式:支持比较运算符(
>,<,>=,<=, , )和逻辑运算符(and,or,not) - 模板包含:支持包含其他模板文件
- 注释支持:支持
{# comments #}注释 - 模板缓存:对模板文件进行缓存以提高性能
使用示例
// 创建引擎
AdvancedTemplateEngine engine = new AdvancedTemplateEngine();
// 设置数据
Map<String, Object> data = new HashMap<>();
data.put("name", "张三");
data.put("users", userList);
// 渲染模板
String html = engine.render(template, data);
这是一个功能完整的模板引擎实现,您可以在此基础上进行扩展以满足特定需求。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播