Java自定义模板设计
来源:互联网 发布:马尔科夫转移概率知乎 编辑:程序博客网 时间:2024/06/05 07:05
还是首先讲一下需求。一个普通的web form表单提交,根据模板自动生成指定格式的结果。form的优势在格式化数据,使得各属性非常直观的展现出来,用户可以更加简单直观的进行输入。但业务上的最终结果却不可以是form,所以就有了这个需求。需求的本质有点类似el表达式的替换,但是这个表达式模板是动态配置的,而不是常见的xml静态文件。
总结一下需求,概括来讲是这样:根据用户的输入,将业务属性填充到实时设置的模板生成最终结果。
不难发现这里的几个关键点。
- 模板要实时可以配置,这里采用db方式。
- 存在用户输入的行为,也就意味着存在不稳定因素,包括特殊字符,空等。但是因为是填充,可以过滤掉特殊字符,只要处理null即可。(需求上需要处理null)
- 既然是填充,就要保证两点。一是填充的对象不能混淆错乱,二是填充的顺序不能出错。
- 该模板是当做第三方jar依赖注入的,所以必须规避掉任何业务因素。
想清楚了设计的重点,再来看看设计,先看类图。
实体层:
TemplateEl:el表达式的设计。因为只是简单的文本模板,所以只要关心el的前缀、后缀即可。这里的html配置是为了前台效果展示、编辑用的。propertyMethod是考虑到不同系统、程序员在声明getter、setter方法时可能不一致,所以显示表达了。
TemplateElFormat:针对特殊el属性,有一定的格式约定。我目前只用到了时间格式,后面会有介绍。
Template:常见的group+unique code 唯一标示模板。
TemplateElConfig:就是一张普通的mapping表。
ResultVo:根据业务需求返回指定的VO。这里建议用一个Abstract类来为模板服务。
Service层:
TemplateFactory:常规的工厂类,获取指定生成器。
TemplateGenerator:常规的生成器。
还是老话,结构jar提供,实现在业务层。包括vo。这样的好处是jar与业务完全隔离。坏处是每个业务系统都要写一遍实现,而且存在冲突的风险。
下面补上实现类的generator实现,其他代码没什么特别。
1. Exception是模板jar封装过的几类异常。因为不存在业务代码,所以无法控制调用方的传参,模板可能会不存在。
//1. 获取模板Template template = this.templateLogic.findByGroupAndCode(groupCode, templateCode);if (null == template) {logger.info("Invalid template access. group code:{}, template code:{}", groupCode, templateCode);result.setException(new TemplateNotExistException("Template not exists! Group code:" + groupCode + ",template code:" + templateCode) );return;}2. 读取模板配置的el。如果没有任何配置,warning。这里按seq读取,为模板拼接做准备。
//2. 读取模板配置List<TemplateElConfig> templateElConfigs = this.templateElConfigLogic.findByTemplateId(template.getId());if (null == templateElConfigs || templateElConfigs.isEmpty() ) {logger.info("There's no express configuration for template:{}", template.getName());return;}3. 解析el的配置,生成最终字符串。
for (TemplateElConfig templateElConfig : templateElConfigs) {TemplateEl el = this.templateElLogic.findOne(templateElConfig.getElId());if (el == null) {logger.info("Missing el config, template el config id:{}",templateElConfig.getId());continue;}String datasourceValue = "";//3.1 String methodName = el.getPropertyMethod();if (StringUtils.isEmpty(methodName)) {logger.info("Missing property method config for el:{}",el.getId());continue;}try {Method method = null;Object propertyValue;if (el.getEl().contains("Date")) {method = (Method)datasource.getClass().getMethod(methodName);propertyValue = (Date)method.invoke(datasource);}else {method = (Method)datasource.getClass().getMethod(methodName);propertyValue = (String)method.invoke(datasource);}if (propertyValue instanceof Date) {TemplateElFormat elFormat = this.templateElFormatLogic.findByElId(el.getId());String timeFormat = DEFAULT_DATE_FORMAT;if (null != elFormat) {timeFormat = elFormat.getFormat();}SimpleDateFormat format = new SimpleDateFormat(timeFormat);datasourceValue = format.format(propertyValue);}else if (propertyValue instanceof String) {datasourceValue = (String)propertyValue;}} catch (Exception e) {logger.error("No such method.", e);result.setException(new IllegalTemplateConfigException("No such method.", e));return;}if (StringUtils.isNoneEmpty(datasourceValue)) {if (StringUtils.isNoneEmpty(el.getPrefix())) {buffer.append(el.getPrefix());}buffer.append(datasourceValue);if (StringUtils.isNotEmpty(el.getSuffix())) {buffer.append(el.getSuffix());}if (StringUtils.isNoneEmpty(el.getHtmlPrefix())) {htmlBuffer.append(el.getHtmlPrefix());}htmlBuffer.append(datasourceValue);if (StringUtils.isNotEmpty(el.getHtmlSuffix())) {htmlBuffer.append(el.getHtmlSuffix());}}}
这里没有业务逻辑,所以是可以放到jar里面的,各业务系统只要控制如何结构化调用就行了。
1 0
- Java自定义模板设计
- java模板方法设计
- JAVA-模板设计模式
- java模板设计模式
- Java设计模式-模板设计
- myeclipse优化+自定义java注释模板+自定义Java代码模板
- 【Java】Eclipse 自定义代码模板
- Java自定义模板导出Excel
- 自定义View--------Android UI模板设计
- 自定义View----Android UI模板设计
- Java自定义Exception设计
- Java自定义异常设计
- java设计模式---模板方法
- Java设计模式---模板模式
- java模板方法设计模式
- java 设计模式-模板模式
- Java 模板方法设计模式
- Java设计模式之模板
- 陈怡暖:2015.5.12早间现货黄金白银操作建议
- Java多线程
- 思考:【滤镜仅在IE有效!】在style使用filter(滤镜)设置水平翻转(flipH)和竖直翻转(flipV)
- 【C/C++学习】const用法总结
- CF527A Playing with Paper
- Java自定义模板设计
- mysql 查看排序集
- 机器学习领域的几种主要学习方式
- VARCHART XGantt经典案例:Apper的芬兰公共交通系统
- 【Android】【Theme】Activity 全屏,透明
- 指针
- aac 文件数据帧读取分析
- 类string运算符的重载
- 数制转换