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

一、背景现象

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

mask、substr两个指令,其中

mask实现

public class MaskDirective extendsDirective {

@OverridepublicString getName() {return "mask";

}

@Overridepublic intgetType() {returnLINE;

}

@Overridepublic boolean render(InternalContextAdapter ctx, Writer writer, Node node) throwsIOException, 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= newStringBuilder();for(int i = 0; i < count; i++) {

buff.append(maskChar);

}

writer.write(buff.toString());return true;

}

}

substr实现

public class SubstrDirective extendsDirective {

@OverridepublicString getName() {return "substr";

}

@Overridepublic intgetType() {returnLINE;

}

@Overridepublic boolean render(InternalContextAdapter ctx, Writer writer, Node node) throwsIOException, 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= newStringBuilder();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 classVelocityHelper {private SetuserExtDirective ;private final static String K_USERDIRECTIVE = "userdirective";private final static VelocityHelper VH = newVelocityHelper();privateVelocityHelper(){

}public static finalVelocityHelper getInstance(){returnVH;

}/*** 初始化*/

public void init() throwsException{

Properties prop= newProperties();

StringBuilder buff= newStringBuilder();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,渲染出实际的业务报文

*

*@paramcontext 业务上下文信息

*@paramtemplate 模板

*@return*@throwsIOException*/

public String evaluate(String template, final VelocityContext context) throwsIOException {

Writer writer= newStringWriter();try{

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

}finally{

IOUtils.closeQuietly(writer);

}

}/***

*@paramuserExtDirective

**/

public void setUserExtDirective(SetuserExtDirective){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= newVelocityEngine(prop);

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

原文: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、付费专栏及课程。

余额充值