FreeMarker强大的自定义指令

FreeMarker强大的自定义指令

今天再次看了下FreeMarker的自定义指令

也写了个小小的不太严谨的demo

先看我的模版表达式

<@compute data=55 binary=8>10,15,12,32,15</@compute>

完整的模版文件如下 index5.ftl

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>freemarker</title>
</head>
<body>
<@compute data=55 binary=8>10,15,12,32,15</@compute>
</body>
</html>
以上代码最终输出的结果如下:


55的八进制是:67
10,15,12,32,15升序排列
10,12,15,15,32,

代码中的自定义指令意思是把data按照binary的方式转换,比如此例就是说把55按照八进制输出来,然后把中间的数据按照升序排列

data和中间的参数是必须存在的。binary参数不是必须的,其默认值就是2

下面我们直接上代码 Freemarker工具类CustomPageCounts


public class CustomPageCounts implements TemplateDirectiveModel {
	private int data = 0;
	private int binary = 2;
	private int count_data = 0,count_binary = 0;

	@Override
	public void execute(Environment arg0, Map arg1, TemplateModel[] arg2, TemplateDirectiveBody arg3)
			throws TemplateException, IOException {

		int lenght = arg1.size();
		
		Iterator<?> iter = arg1.entrySet().iterator();
		while(iter.hasNext()){
			Map.Entry ent = (Map.Entry) iter.next();
			String paramNames = (String) ent.getKey();
			TemplateModel paramValues = (TemplateModel) ent.getValue();
			if(paramNames.equals("data")){
				if(!(paramValues instanceof TemplateNumberModel)){
					throw new TemplateModelException("错误,data不是TemplateNumberModel类型");
				}
				this.data = ((TemplateNumberModel)paramValues).getAsNumber().intValue();
				this.count_data = 1;
			}else if(paramNames.equals("binary")){
				if(!(paramValues instanceof TemplateNumberModel)){
					throw new TemplateModelException("错误,binary不是TemplateNumberModel类型");
				}
				this.binary = ((TemplateNumberModel)paramValues).getAsNumber().intValue();
				this.count_binary = 1;
			}else{
				throw new TemplateModelException("错误,参数错误!");
			}
		}
		

		Writer out = arg0.getOut();
		
		if(this.count_data == 1 && this.count_binary == 0){
			//打印默认的2进制
			out.write(this.data+"的二进制是:"+Integer.toBinaryString(this.data));
		}
		if(this.count_data == 1 && this.count_binary == 1){
			if(this.binary == 8){
				out.write(this.data+"的八进制是:"+Integer.toOctalString(this.data));
			}
			if(this.binary == 10){
				out.write(this.data+"的十进制是:"+this.data);
			}
			if(this.binary == 16){
				out.write(this.data+"的十六进制是:"+Integer.toHexString(this.data));
			}
		}
		if(this.count_data == 0){
			out.write("错误,必须要有data数据");
			throw new TemplateModelException("错误,必须要有data数据");
		}
		out.write("<br>");
		if (arg3 != null) {
			arg3.render(new UpperCaseFilterWriter(arg0.getOut()));
        } else {
            throw new RuntimeException("missing body");
        }
		
	}

	private static class UpperCaseFilterWriter extends Writer{
		private final Writer out;
        
        UpperCaseFilterWriter (Writer out) {
            this.out = out;
        }

        public void write(char[] cbuf, int off, int len)
                throws IOException {
        	out.write(String.valueOf(cbuf)+"升序排列<br>");
            String []str = String.valueOf(cbuf).split(",");
        	int L = str.length;
        	int []data = new int[L];
        	for(int i=0;i<L;i++){
        		data[i] = Integer.parseInt(str[i]);
        	}
        	for(int i = 0 ; i < L-1 ; i++){
        		for(int j = i+1 ; j < L ; j++){
        			int temp ;
        			if(data[i] > data[j]){
        				temp = data[j];
        				data[j] = data[i];
        				data[i] = temp;
        			}
        		}
        	}
        	String str1 = "";
        	for(int i=0;i<L;i++){
        		str1 = str1+data[i]+",";
        	}
        	out.write(str1);
        }

        public void flush() throws IOException {
            out.flush();
        }

        public void close() throws IOException {
            out.close();
        }
	}
}
以上代码最大的不严谨的地方在于,将字符串数组转换为int数组的时候,没有过滤掉其中的无效字符,如回车符号,也没有进行判断所有的数据是否都是数字,就是判断是否都能转换为int,很好判断,只需要变量char[] cbuf,如果出现字母等符号,就表示不能转换。


由于时间关系,我就不补充了。大家可自行修改,本例只是测试,学习FreeMarkere的自定义指令

下面就是我们的Controller

@RequestMapping("/index5")
public String init5(HttpServletRequest request, HttpServletResponse response,ModelMap model){
	model.addAttribute("compute",new CustomPageCounts());
	return "aaa/index5";
}
地址栏输入地址测试:http://localhost:8080/freemarker/index/index5.jhtml



爆款云服务器s6 2核4G 低至0.46/天,具体规则查看活动详情Blog Img