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