当前位置: 首页 > news >正文

北京网站建设亿玛酷出名5网站备案 域名备案

北京网站建设亿玛酷出名5,网站备案 域名备案,长臂挖机出租东莞网站建设,做的网站要花钱吗Java 模板变量替换——字符串替换器(思路Mybatis的GenericTokenParser) 思路字符串替换器 思路 模板变量替换无非是寻找出字符串(模板)中的特殊标记,用对应的变量进行字符串替换。 提到变量替换,大家第一能…

Java 模板变量替换——字符串替换器(思路Mybatis的GenericTokenParser)

  • 思路
  • 字符串替换器

思路

模板变量替换无非是寻找出字符串(模板)中的特殊标记,用对应的变量进行字符串替换。
提到变量替换,大家第一能联想到的可能是Mybatis的动态SQL语句的解析,又或者是mybatis.xml配置文件中用于解析"${username:root}"的默认值。
在Mybatis的源码中,这些功能则是通过GenericTokenParser类来实现的,通过查看源码可以很明显的知道GenericTokenParser只是查找指定的占位符,而具体的解析行为会根据其持有的TokenHandler实现的不同而有所不同,这里是采用了策略模式。
那么接下来我们就使用Mybatis的思路,试着写一个字符串替换器吧

字符串替换器

GenericTokenParser

public class GenericTokenParser {private final String openToken;private final String closeToken;private final TokenHandler handler;public GenericTokenParser(String openToken, String closeToken, TokenHandler handler) {this.openToken = openToken;this.closeToken = closeToken;this.handler = handler;}public String parse(String text) {if (text == null || text.isEmpty()) {return "";}// search open tokenint start = text.indexOf(openToken, 0);if (start == -1) {return text;}char[] src = text.toCharArray();int offset = 0;final StringBuilder builder = new StringBuilder();StringBuilder expression = null;while (start > -1) {if (start > 0 && src[start - 1] == '\\') {// this open token is escaped. remove the backslash and continue.builder.append(src, offset, start - offset - 1).append(openToken);offset = start + openToken.length();} else {// found open token. let's search close token.if (expression == null) {expression = new StringBuilder();} else {expression.setLength(0);}builder.append(src, offset, start - offset);offset = start + openToken.length();int end = text.indexOf(closeToken, offset);while (end > -1) {if (end > offset && src[end - 1] == '\\') {// this close token is escaped. remove the backslash and continue.expression.append(src, offset, end - offset - 1).append(closeToken);offset = end + closeToken.length();end = text.indexOf(closeToken, offset);} else {expression.append(src, offset, end - offset);offset = end + closeToken.length();break;}}if (end == -1) {// close token was not found.builder.append(src, start, src.length - start);offset = src.length;} else {builder.append(handler.handleToken(expression.toString()));offset = end + closeToken.length();}}start = text.indexOf(openToken, offset);}if (offset < src.length) {builder.append(src, offset, src.length - offset);}return builder.toString();}
}

TokenHandler

public interface TokenHandler {String handleToken(String content);
}

以上代码是Mybatis的源码,可以直接抄,接下来编写核心的逻辑:
这里的数据使用Map<String,Object>来存储,key是变量名称,value是变量值,value的类型下列代码仅支持了String和List,对应的可以实现直接变量替换和循环变量替换,有其他需要可以在此基础上新增功能,而List的泛型仅支持Map<String,String>,即不支持多层嵌套。
在这个例子中,我使用${变量名}表示普通变量,<变量名></变量名>表示循环变量,标签内的内容将被循环展示

public class ReportGenerator {public static void main(String[] args) {String reportTemplate = "这是一份贵司专属总结报告,请查收!\n" +"您的订单编号:${firstShowId},产品名称:${firstProductName},于${firstOnlineDate}正式生效,今天是贵司正式启用电子签名的第90天,截至今天,您的订单使用情况如下:#{${a}/${b}}\n" +"<orders>${orders.productName},累计消耗${orders.displayConsumeAmount}${orders.units}</orders>" +"如对使用情况和数据报告有任何疑问,可随时联系你的客户成功经理。\n" +"<contracts>合同编号${contracts.contractId},合同负责人:${contracts.contractManager},${name}</contracts>";Map<String, Object> data = new HashMap<>();data.put("firstShowId", "123456789");data.put("firstProductName", "测试产品");data.put("firstOnlineDate", "2023-01-01");data.put("productName", "测试产品");data.put("name", "张三");data.put("a", "100");data.put("b", "10");data.put("c", "10");List<Map<String, String>> orders = new ArrayList<>();Map<String, String> param1 = new HashMap<>();param1.put("productName", "测试产品1");param1.put("displayConsumeAmount", "100");param1.put("units", "元");orders.add(param1);Map<String, String> param2 = new HashMap<>();param2.put("productName", "测试产品2");param2.put("displayConsumeAmount", "200");param2.put("units", "元");orders.add(param2);data.put("orders", orders);List<Map<String, String>> contracts = new ArrayList<>();Map<String, String> param3 = new HashMap<>();param1.put("contractId", "12312543243213");param1.put("contractManager", "杜甫");contracts.add(param1);Map<String, String> param4 = new HashMap<>();param2.put("contractId", "1234353453");param2.put("contractManager", "李白");contracts.add(param2);data.put("contracts", contracts);String handler = handler(data, reportTemplate);// 打印报告System.out.println(handler);}public static String handler(Map<String, Object> data, String templateContent) {// 循环变量,仅支持一层嵌套Map<String, List<Map<String, String>>> loopVariables = new HashMap<>();// 基本参数Map<String, String> basicVariables = new HashMap<>();// 分类:循环变量,基本参数,计算参数for (Map.Entry<String, Object> entry : data.entrySet()) {String key = entry.getKey();Object value = entry.getValue();if (value instanceof List) {loopVariables.put(key, (List<Map<String, String>>) value);} else if (value instanceof String) {basicVariables.put(key, (String) value);}}// 处理循环变量for (Map.Entry<String, List<Map<String, String>>> entry : loopVariables.entrySet()) {String key = entry.getKey();List<Map<String, String>> value = entry.getValue();ForEachTokenParser forEachTokenParser = new ForEachTokenParser(key, value, "\n");GenericTokenParser genericTokenParser = new GenericTokenParser("<" + key + ">", "</" + key + ">", forEachTokenParser);templateContent = genericTokenParser.parse(templateContent);}// 处理基本参数VariableTokenParser variableTokenParser = new VariableTokenParser(basicVariables);GenericTokenParser genericTokenParser = new GenericTokenParser("${", "}", variableTokenParser);templateContent = genericTokenParser.parse(templateContent);// // 计算参数// EquationTokenParser equationTokenParser = new EquationTokenParser();// GenericTokenParser equationParser = new GenericTokenParser("#{", "}", equationTokenParser);// templateContent = equationParser.parse(templateContent);return templateContent;}/*** 循环变量参数*/static class ForEachTokenParser implements TokenHandler {private final String variableName;private final List<Map<String, String>> variables;private final String separator;public ForEachTokenParser(String variableName, List<Map<String, String>> variable, String separator) {this.variableName = variableName;this.variables= variable;this.separator = separator;}@Overridepublic String handleToken(String content) {if (variables == null || variables.isEmpty()) {throw new RuntimeException("变量不存在:" + content);}StringBuilder builder = new StringBuilder();for (Map<String, String> variable : variables) {VariableTokenParser variableTokenParser = new VariableTokenParser(variable);GenericTokenParser genericTokenParser = new GenericTokenParser("${" + variableName + ".", "}", variableTokenParser);builder.append(genericTokenParser.parse(content)).append(separator);}return builder.toString();}}/*** 基础变量参数*/static class VariableTokenParser implements TokenHandler {private final Map<String, String> variables;public VariableTokenParser(Map<String, String> variable) {this.variables= variable;}@Overridepublic String handleToken(String content) {String value = variables.get(content);if (value == null) {throw new RuntimeException("变量不存在:" + content);}return value;}}/*** 计算参数* 目前仅支持除法运算:#{100/10}*/// static class EquationTokenParser implements TokenHandler {////     @Override//     public String handleToken(String content) {//         return String.valueOf(evaluateExpression(content));//     }////     private static double evaluateExpression(String expression) {//         String[] parts = expression.split("/");//         if (parts.length == 2) {//             BigDecimal numerator = new BigDecimal(parts[0].trim());//             BigDecimal denominator = new BigDecimal(parts[1].trim());//             return numerator.divide(denominator, 2, RoundingMode.HALF_UP).doubleValue();//         }//         return 0;//     }// }
}
http://www.yayakq.cn/news/227757/

相关文章:

  • 网站联系方式修改电子商务网络平台建设
  • 重庆营销型网站创建一个公司要多少钱
  • 定制网站建设多少钱大数据营销的特征有哪些
  • 重庆招聘网站建设wordpress 模板 中文乱码
  • 国外网站模板下载js 网站校验
  • 网站的头尾和导航的公用文件兰州模板网站建设
  • 旅游网站建设毕业设计怎样设置网站访问权限
  • 专业北京网站建设公司哪家好省住房城乡建设厅门户网站
  • h5网站建设报价多少钱广东新闻联播主持人
  • 合肥市公司网站建设衡阳做网站的
  • 什么 a wordpress做seo网站的公司哪家好
  • 泰州网站建设方案优化高密住房和城乡建设部网站
  • 关于网站开发的一些论文网站自助建设源码
  • 免备案域名购买网站外贸网站大全
  • 连云港建设企业网站阿里云虚拟主机wordpress发送邮件
  • 做网站推广公司手机app软件开发机构
  • 什么装修网站做的好的腾讯云做网站需要报备
  • 宜春建设网站公司高端网站设计v芯hyhyk1推好
  • 厦门u 网站建设自适应网站建设哪家好
  • 宣讲家网站 家风建设深圳做seo有哪些公司
  • 做网站销售一个星期的计划wordpress new2主题使用
  • 南昌网站建设是什么意思怎么进行网站备案
  • 重生做皇帝小说网站微信官方微网站吗
  • 免费网站备案辽宁建设工程信息网招标文件怎么打开
  • 北京网站建设分析论文重庆律师网站建设
  • visual studio 2010 网站开发教程品牌建设的论文
  • 百度竞价网站人物介绍网页模板html
  • 南昌seo网站国家企业信用信息系统年报入口官网
  • 百合网网站建设与策划营销服务机构有哪些
  • wordpress 群站富阳网站建设价格