velocity自定义函数_velocity自定义指令不生效问题解决之旅

一、背景现象

为了支持灵活的、可自定义的脱敏规则,工程拟采用velocity实现该目的,为此,自定义了:

mask、substr两个指令,其中

mask实现

public class MaskDirective extends Directive {

@Override

public String getName() {

return "mask";

}

@Override

public int getType() {

return LINE;

}

@Override

public boolean render(InternalContextAdapter ctx, Writer writer, Node node) throws IOException, ResourceNotFoundException, ParseErrorException, MethodInvocationException {

//fieldName

SimpleNode snField = (SimpleNode) node.jjtGetChild(0);

String maskChar = (String)snField.value(ctx);

snField = (SimpleNode) node.jjtGetChild(1);

int count = (int)snField.value(ctx);

StringBuilder buff = new StringBuilder();

for(int i = 0; i < count; i++) {

buff.append(maskChar);

}

writer.write(buff.toString());

return true;

}

}

substr实现

public class SubstrDirective extends Directive {

@Override

public String getName() {

return "substr";

}

@Override

public int getType() {

return LINE;

}

@Override

public boolean render(InternalContextAdapter ctx, Writer writer, Node node) throws IOException, ResourceNotFoundException, ParseErrorException, MethodInvocationException {

//fieldName

SimpleNode snField = (SimpleNode) node.jjtGetChild(0);

String fieldValue = (String)snField.value(ctx);

if(fieldValue == null || fieldValue.length() == 0){

return false;

}

int items = node.jjtGetNumChildren();

int startIdx = Integer.MIN_VALUE;

int endIdx = fieldValue.length();

if(items < 1){

return false;

}

try{

snField = (SimpleNode) node.jjtGetChild(1);

startIdx = (int)snField.value(ctx);

if(items > 2){

snField = (SimpleNode) node.jjtGetChild(2);

endIdx = (int)snField.value(ctx);

if(endIdx > fieldValue.length()){

endIdx = fieldValue.length();

}

}

if(startIdx >= endIdx){

return false;

}

StringBuilder buff = new StringBuilder();

if(items > 2){

writer.write(fieldValue.substring(startIdx,endIdx));

}else{

if(startIdx < 0){

startIdx = startIdx + fieldValue.length();

}

writer.write(fieldValue.substring(startIdx));

}

return true;

}catch(Exception e){

return false;

}

}

}

velocity初始化方法:

public final class VelocityHelper {

private Set userExtDirective ;

private final static String K_USERDIRECTIVE = "userdirective";

private final static VelocityHelper VH = new VelocityHelper();

private VelocityHelper(){

}

public static final VelocityHelper getInstance(){

return VH;

}

/**

* 初始化

*/

public void init() throws Exception{

Properties prop = new Properties();

StringBuilder buff = new StringBuilder();

for(String s : userExtDirective){

buff.append(s.trim()).append(",");

}

LogHelper.trace("start VelocityHelper.init[" + buff.toString() + "]");

prop.setProperty(K_USERDIRECTIVE, buff.toString().substring(0, buff.length()-1));

Velocity.init(prop);

LogHelper.trace("end VelocityHelper.init");

}

/**

* 根据报文模板和VelocityContext,渲染出实际的业务报文

*

* @param context 业务上下文信息

* @param template 模板

* @return

* @throws IOException

*/

public String evaluate(String template, final VelocityContext context) throws IOException {

Writer writer = new StringWriter();

try {

Velocity.evaluate(context, writer, StringUtil.EMPTY_STRING, template);

return writer.toString();

} finally {

IOUtils.closeQuietly(writer);

}

}

/**

*

* @param userExtDirective

*

*/

public void setUserExtDirective(Set userExtDirective){

this.userExtDirective = userExtDirective;

}

}

部署到服务器后,以下表达式始终未得到替换:#substr($maskField, 0, 3)#mask('*', 4)#substr($maskField, -4)

二、原因分析

开始怀疑是配置等问题,经过以下方法尝试均为解决问题:

1、怀疑spring xml配置问题----未解决

2、硬编码指令,在构造函数塞入指令----未解决

无奈,登录服务器grep velocity 得到了以下的输出(其中之一),茅塞顿开。

2019-02-02 07:49:52,315 [  - /// - ] INFO  assemble.VMRender - resource=class path resource [velocity/velocity.properties]

Velocity.ini及Velocity.evalute均是全局单一模式,既然有人捷足先登,自然不在做第二次初始化。

三、解决方案

采用VelocityEngine替换Velocity,实现jar包间隔离,独立管理自己的资源。

private VelocityEngine velocityEngine = null;

velocityEngine = new VelocityEngine(prop);

velocityEngine.evaluate(context, writer, StringUtil.EMPTY_STRING, template);

标签:return,自定义,之旅,int,snField,writer,velocity,public,String

来源: https://www.cnblogs.com/frazeworld/p/10347496.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值