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/天,具体规则查看活动详情