由于Groovy最终会编译成符合Java类的字节码,为了体验Groovy的一些比较Cool的功能,我们不妨也在Java中用点Groovy,下面的例子我们用一个简单的权限控制来演示:
class AuthTreeConfig {
static def AUTH_TREE = """
<auths>
<auth id="1" text="客户管理1" index="0" leaf="false" expanded="false" act="CAREREQANALYZER,PROVINCEADMIN">
<auth id="11" text="客户管理11" index="0" leaf="false" expanded="false" act="CAREREQANALYZER,PROVINCEADMIN">
<auth id="111" text="客户管理111" index="1" leaf="true" expanded="false" act="CAREREQANALYZER,PROVINCEADMIN">
</auth>
</auth>
<auth id="12" text="客户管理12" index="2" leaf="true" expanded="false" act="CAREREQANALYZER,PROVINCEADMIN">
</auth>
</auth>
<auth id="2" text="客户管理2" index="2" leaf="true" expanded="false" act="DISTRICTADMIN">
</auth>
</auths>
""";
}
上面的代码是一个权限树的配置文件,因为Groovy的动态编译,所以他即是Groovy源程序由是配置文件。
import groovy.xml.DOMBuilder
import groovy.xml.dom.DOMCategory
import cn.com.xinli.ccp.core.TreeNode
import static cn.com.xinli.ccp.groovy.AuthTreeConfig.AUTH_TREE as AUTH_TREE
class AuthReader{
def empty = []
static TreeNode[] getAuthTreeById(String id){
def temp = []
def reader = new StringReader(AUTH_TREE)
def doc = DOMBuilder.parse(reader)
def auths = doc.documentElement
use (DOMCategory) {
def authList = auths.'auth'.'**'
4 == authList?.size()
def root = authList.find{it.'@id' == id}
assert "客户管理1" == root.'@text'
def children = root.'*'
1 == children.size()
children.each(){
def tn = new TreeNode(
Long.parseLong(it.'@id'),
Long.parseLong(it.'@index'),
it.'@text',
Boolean.parseBoolean(it.'@leaf'),
Boolean.parseBoolean(it.'@expanded'),
it.'@atc'
)
temp.add(tn)
}
}
return temp
}
}
这段代码我们利用GPath来遍历和读取配置文件,并构造成树节点,这个类中提供的静态方法将会被我们的Java程序直接调用。
public class TreeNode {
private Long id;
private String text;
private boolean expanded;
private boolean leaf;
private String act;
private Long index;
//getters and setters
}
调用代码可能像这样:
//...
private TreeNode[] getChildTreeNode(String id){
return AuthReader.getAuthTreeById(id);
}
//...
注意问题:
在实际开发的过程中,发现我们的Groovy生成的class文件放在WEB-INF/classes下面程序是找不到的,必须手动指定
Groovy生成类路径,并将它引入Java工程,而这个在部署到Web Server下面是就找不到了。所以这时候我们又需要将生成的类文件拷贝到WEB-INF/classes下面。而且我们要注意防止乱码。
当然我们还可以用Groovy类加载器来执行Groovy脚本,代码像这样:
import java.io.File;
import groovy.lang.GroovyClassLoader;
import groovy.lang.GroovyObject;
/**
* 动态加载Groovy脚本,调用它的方法
* @author samueli
*
*/
public class DynamicGroovy {
private GroovyObject groovyObject;
public Object getProperty(String name) {
return groovyObject.getProperty(name);
}
@SuppressWarnings("unchecked")
public Object invokeScriptMethod(String scriptName, String methodName,
Object[] args) {
ClassLoader parent = getClass().getClassLoader();
GroovyClassLoader loader = new GroovyClassLoader(parent);
try {
Class groovyClass = loader.parseClass(new File(scriptName));
groovyObject = (GroovyObject) groovyClass.newInstance();
return groovyObject.invokeMethod(methodName, args);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public static void main(String[] args) throws Exception {
DynamicGroovy dynamicGroovy = new DynamicGroovy();
Object[] params = { "1" };
Object result = dynamicGroovy.invokeScriptMethod(
"src/com/samueli/groovy/AuthReader.groovy",
"getAuthTreeById",
params);
System.out.println(result);
System.out.println(dynamicGroovy.getProperty("empty"));
}
}
本文介绍如何使用Groovy脚本语言实现权限树配置并整合到Java应用中。通过GPath遍历XML配置,构造树节点模型,提供Java接口调用。同时探讨了Groovy类加载器的应用及类文件的生成与部署问题。

424

被折叠的 条评论
为什么被折叠?



