一个简单的Java模板工具类(一)—正则加替换实现

原创
2014/04/15 12:37
阅读数 1.5W

    基于表达式解析实现的简单模板: http://my.oschina.net/haogrgr/blog/469882 


    模板有很多的开源框架, freemarker, vilocity 等等.

    但是现在我只是要一个简单的手机短信模板,不要那么复杂啊~~~

    以前做过手机模板, 为了灵活,用的 XML+ OGNL , 挺蛋疼的, 在xml里面写ognl表达式~~~

    现在又要弄手机模板了,我不要那么复杂~~~~

    以上是废话(最近废话比较多),直接上代码吧....

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

public class SimpleTempletUtil {
    
    public static final String DEFAULT_SPLIT = "$$";
    
    public static void main(String[] args) {
        Set<String> paramNames = getParamNames("dddd$$aaa$$$$bbb$$ccc$$", "$$");
        System.out.println(paramNames);
        
        Map<String, String> context = new HashMap<String, String>();
        context.put("aaa", "value1");
        context.put("bbb", "value2");
        String render = render("dddd$$aaa$$$$bbb$$ccc$$", context );
        System.out.println(render);
    }
    
    /**
     * 使用context中对应的值替换templet中用$$包围的变量名(也是context的key)
     * @param templet 模板
     * @param context 用于替换模板中的变量
     * @return 例如  参数 : dddd$$aaa$$$$bbb$$ccc$$, $$, {<aaa, value1>, <bbb, value2>}  结果:ddddvalue1value2ccc$$
     */
    public static String render(String templet, Map<String, String> context) {
        return render(templet, DEFAULT_SPLIT, context);
    }
    
    /**
     * 使用context中对应的值替换templet中用split包围的变量名(也是context的key)
     * @param templet 模板
     * @param split 用于标识变量名的标志
     * @param context 用于替换模板中的变量
     * @return 例如  参数 : dddd$$aaa$$$$bbb$$ccc$$, $$, {<aaa, value1>, <bbb, value2>}  结果:ddddvalue1value2ccc$$
     */
    public static String render(String templet, String split, Map<String, String> context) {
        Set<String> paramNames = getParamNames(templet, split);

        for (String name : paramNames) {
            String value = context.get(name);
            value = value == null ? "" : value;
            String regex = "\\Q" + split + name + split + "\\E";
            templet = templet.replaceAll(regex, value);
        }

        return templet;
    }
    
    /**
     * 根据分割符从模板中取得变量的名字($$变量名$$) eg:
     * $$aaa$$$$bbb$$ccc$$ 返回   aaa,bbb
     * @param templet 模板
     * @param split 包围变量名的字符串
     * @return 模板中的变量名
     */
    public static Set<String> getParamNames(String templet, String split) {
        Set<String> paramNames = new HashSet<String>();
        
        int start = 0, end = 0;
        while (end < templet.length()) {
            start = templet.indexOf(split, end) + split.length();
            if (start == -1) {
                break;
            }
            end = templet.indexOf(split, start);
            if (end == -1) {
                break;
            }
            paramNames.add(templet.substring(start, end));
            end = end + split.length();
        }
        return paramNames;
    }
    
}

    使用很简单运行下面的代码

        Set<String> paramNames = getParamNames("dddd$$aaa$$$$bbb$$ccc$$", "$$");
        System.out.println(paramNames);
        
        Map<String, String> context = new HashMap<String, String>();
        context.put("aaa", "value1");
        context.put("bbb", "value2");
        String render = render("dddd$$aaa$$$$bbb$$ccc$$", context );
        System.out.println(render);

    显示结果:

[aaa, bbb]
ddddvalue1value2ccc$$


    比较简单,如果为了灵活的配置,可以写到Spirng的配置文件中. 如

<!-- 发送短信 -->
	<bean id="smsMessageService" class="com.xxxx.core.service.impl.SmsMessageServiceImpl">
		<!--线程池-->
		<property name="taskExecutor" ref="taskExecutor" />
		<property name="sendUrl" value="${sms.url}" />
		<property name="userName" value="${sms.user.name}" />
		<property name="userPassword" value="${sms.user.password}" />
		<property name="templetMap">
			<map>
				<entry key="verification" value="您的验证码是:$$verification$$。请不要把验证码泄露给其他人。如非本人操作,可不用理会!" />
			</map>
		</property>
	</bean>

    这样以后改模板就只用改Spring配置文件了.

    如果想要改了不重启马上生效,那么可以放数据库...

    简单的东西只适用于简单的情况, 改类不是万能的, 请悠着点...

    以上皆为原创,转载请注明!

展开阅读全文
打赏
0
16 收藏
分享
加载中
谢谢分享。
解决一个bug。
getParamNames
while (end < templet.length()) {
start = templet.indexOf(split, end) + split.length();//Bug
if (start == -1) {
break;
}
}
====改成
while (end < templet.length()) {
start = templet.indexOf(split, end);
if (start == -1) {
break;
}
start += split.length();
}
2017/04/27 18:45
回复
举报
更多评论
打赏
1 评论
16 收藏
0
分享
OSCHINA
登录后可查看更多优质内容
返回顶部
顶部