导读
本文介绍使用commons-ognl来对ongl表达式的AST树进行分析,对想要在OGNL表达式中提取出部分信息的需求有帮助。
为什么用commons-ognl呢?是因为commons-ognl比原始的ognl多了一个accept方法的支持(不支持accept树)。
另外本文的方法会简单修改commons-ognl的源码来实现。
获得commons-ognl
commons-ognl在github上有仓库,可直接克隆。
git clone https://github.com/apache/commons-ognl.git
源码改造
存在一个org.apache.commons.ognl.Node
接口,此接口是所有Ognl表达式AST树中的基本接口,所有类型的节点都是org.apache.commons.ognl.SimpleNode
类的派生类。
查看org.apache.commons.ognl.Node
接口,
包含一个accept方法,定义看图:
查看accept方法的实现,竟只对visitor回调了当前节点,并没有visit其树枝下的子节点(证实导读部分)。
我们想要的是分析AST树,而不仅仅是独立的节点。
所以修改一下源码,java8可以直接写在Node接口中:
default <R, P> R acceptTree(NodeVisitor<? extends R, ? super P> visitor, P data)throws OgnlException{
R result = accept(visitor, data);
for (int i = 0; i < jjtGetNumChildren(); i++) {
result = jjtGetChild(i).acceptTree(visitor, data);
}
return result;
}
添加一个adapter类NodeVisitorAdapter
package org.apache.commons.ognl;
public class NodeVisitorAdapter<R,P> implements NodeVisitor<R,P>{
@Override
public R visit(ASTSequence node, P data) throws OgnlException {
return null;
}
@Override
public R visit(ASTAssign node, P data) throws OgnlException {
return null;
}
@Override
public R visit(ASTTest node, P data) throws OgnlException {
return null;
}
@Override
public R visit(ASTOr node, P data