前段时间由于工作需要,需要一个轻量级模板工具,目前市面上的主流的模板引擎有:freemarker,velocity,smarty4j,jetbrick,handlebars,mustache,rocker,thymeleaf,beetl,httl,以上排序没有优先级直说,最长用的当属freemarker和velocity,这两个也是所有模板引擎的老前辈了,但是相对项目使用来说,这些引擎都比较重,实际项目使用可能不及引擎使用的3%,而且在实际项目使用中,如果不是特别复杂的话,就感觉引入这个一个jar有些鸡肋,所有自己写了一个小的模板工具,来顶替模板引擎.
实现原理相对简单一些,表达式支持 ${xxx} 的变量,通过正则去替换此类的数据就可以
/**
* 需求:
* 1. 引擎调用后动作服务,传递一个大的字符串,字符串中存在${}类似的变量,包括${A.b.c}、${A.b}
* 2. 需要后动作提供的解析服务,对文本中的字符串进行替换
* <p>
* <p>
* 设计思路:
* 1. 匹配出所有的${}
* 2. 通过getValue接口获取到所有的${}的值
* 3. 根据render方法替换掉
*/
@Slf4j
public class ParseUtils {
private static final String DEF_REGEX = "\\$\\{(.+?)\\}";
public static String render(String parseText, Map<String, Object> data) {
return render(parseText, data, DEF_REGEX);
}
private static String render(String parseText, Map<String, Object> data, String regex) {
if (Strings.isNullOrEmpty(parseText)) {
return parseText;
}
try {
StringBuffer sb = new StringBuffer();
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(parseText);
while (matcher.find()) {
String name = matcher.group(1);// 键名
String value = "";
if (MapUtils.isNotEmpty(data)) {
Object dta = data.get(name);
if (Objects.nonNull(dta)) {
value = String.valueOf(dta) ;// 键值
}
}
value = Matcher.quoteReplacement(value);
matcher.appendReplacement(sb, value);
}
matcher.appendTail(sb);
return sb.toString();
} catch (Exception e) {
log.error("解析文本异常:", e);
return parseText;
}
}
public static void main(String[] args) {
Map<String,Object> data = Maps.newHashMap();
data.put("area", "北京");
data.put("weather", "多云");
data.put("air", "良");
data.put("nowDate", "2019年12月25日");
System.out.println(ParseUtils.render("地区:${area}, 天气:${weather},空气质量:${air} 日期:${nowDate}", data));
}
}
打印结果为: