Freemarker自定义指令和方法
Posted 熊猫小牛牛
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Freemarker自定义指令和方法相关的知识,希望对你有一定的参考价值。
文章目录
之前在项目中使用了Freemarker的自定义指令和方法,感觉挺方便的,记录下,防止遗忘。Talk is cheap, show the code!
Freemarker模板
添加Freemarker的maven依赖
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.28</version>
</dependency>
hello.ftl
模板包含一个自定义手机号码隐位的方法和一个菜单展示的自定义指令
<html>
<head>
<title>你好,$username</title>
</head>
<body>
手机号码:$phoneMask(phone, 2, 4)
<@menus method="menus"; showAll>
<#if showAll>
<#if menus?? && menus?size gt 0>
<#list menus as item>
<h1>$item</h1>
</#list>
</#if>
<#else>
没有可用菜单
</#if>
</@menus>
</body>
</html>
自定义指令
自定义一个菜单展示指令:MenusTagDirective.java
import java.io.IOException;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import freemarker.core.Environment;
import freemarker.template.Configuration;
import freemarker.template.DefaultObjectWrapperBuilder;
import freemarker.template.TemplateBooleanModel;
import freemarker.template.TemplateDirectiveBody;
import freemarker.template.TemplateDirectiveModel;
import freemarker.template.TemplateException;
import freemarker.template.TemplateModel;
public class MenusTagDirective implements TemplateDirectiveModel
/**
* @param environment 环境变量(实现复杂功能时可能会用)
* @param map 在.ftl模板中使用自定义指令传的参数(key-value形式)
* @param templateModels 返回值,数组形式
* @param templateDirectiveBody 指令内容
* @throws TemplateException
* @throws IOException
*/
@Override
public void execute(Environment environment, Map map, TemplateModel[] templateModels, TemplateDirectiveBody templateDirectiveBody) throws TemplateException, IOException
DefaultObjectWrapperBuilder builder = new DefaultObjectWrapperBuilder(Configuration.VERSION_2_3_28);
if (map.containsKey("method") && "menus".equalsIgnoreCase(map.get("method").toString()))
// 这里直接new一个菜单列表,真实环境可以自己获取
List<String> menusList = new LinkedList<>();
menusList.add("用户管理");
menusList.add("角色管理");
menusList.add("权限管理");
menusList.add("系统设置");
environment.setVariable("menus", builder.build().wrap(menusList));
templateModels[0] = TemplateBooleanModel.TRUE;
else
templateModels[0] = TemplateBooleanModel.FALSE;
templateDirectiveBody.render(environment.getOut());
自定义方法
自定义手机号码隐位的method,继承自TemplateMethodModelEx,以前TemplateMethodModel被Deprecated。
import java.util.List;
import freemarker.template.TemplateMethodModelEx;
import freemarker.template.TemplateModelException;
/**
* 手机隐位
* $phoneMask(phone, beginIdx, suffixIdx)
*/
public class PhoneMask implements TemplateMethodModelEx
@Override
public Object exec(List args) throws TemplateModelException
if (args.size() != 3)
throw new TemplateModelException(
"the field number of phoneMask is wrong");
try
String phoneNum = args.get(0).toString();
int beginIdx = Integer.valueOf(args.get(1).toString().trim());
int suffixIdx = Integer.valueOf(args.get(1).toString().trim());
// 这里没有对begin和suffix做严格校验
StringBuilder sb = new StringBuilder();
int size = phoneNum.length();
if(size > beginIdx + suffixIdx)
String prefix = phoneNum.substring(0, beginIdx);
String suffix = phoneNum.substring(size - suffixIdx);
String middle = phoneNum.substring(beginIdx, size - suffixIdx).replaceAll(".", "*");
sb.append(prefix).append(middle).append(suffix);
else
sb.append(phoneNum);
return sb.toString();
catch (Exception e)
throw new TemplateModelException(
"phoneMask 处理异常", e);
测试方法
public static void main( String[] args )
Configuration cfg = new Configuration(Configuration.getVersion());
try
// 设置模板位置
cfg.setDirectoryForTemplateLoading(new File("D:\\\\workspaces\\\\freemarkerdemo\\\\src\\\\main\\\\resources"));
cfg.setDefaultEncoding("UTF-8");
cfg.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);
// 自定义指令\\方法
cfg.setSharedVariable("menus", new MenusTagDirective());
cfg.setSharedVariable("phoneMask", new PhoneMask());
Template temmplate = cfg.getTemplate("hello.ftl");
Map<String, String> map = new HashMap<>();
map.put("username", "admin");
map.put("phone", "13849323456");
StringWriter sw = new StringWriter();
try
temmplate.process(map,sw);
catch (TemplateException e)
e.printStackTrace();
System.out.println(sw.toString());
catch (IOException e)
e.printStackTrace();
测试结果
<html>
<head>
<title>你好,admin</title>
</head>
<body>
手机号码:13*******56
<h1>用户管理</h1>
<h1>角色管理</h1>
<h1>权限管理</h1>
<h1>系统设置</h1>
</body>
</html>
以上是关于Freemarker自定义指令和方法的主要内容,如果未能解决你的问题,请参考以下文章
SpringMVC和Freemarker整合,带自定义标签的使用方法
freemarker中调用java方法,除了内建函数,自定义的怎么调用?