Java解析Groovy和Shell的代码
一、使用场景
在整个系统中,通用型的代码基本没什么变化,需要变动的仅仅是业务相关的代码。那么我们就会把一些业务代码简单编码一下放在数据库中。通过数据库的配置,可以直接从数据库中查找出来编码处理一下,来调用,这样,会省去了不少重复上线的繁琐了。
二、项目实战
1.解析Groovy代码
private static GroovyClassLoader loader;
/**
* 调用Groovy代码
* @param code 数据库取出的代码
* @param params 调用方法的参数
* @return 返回值
*/
private Object processGroovyCode(String code, DyncCallParameter params) {
Object ret = null;
if (StringUtils.isNotBlank(code)) {
loader = new GroovyClassLoader(ScheduleJob.class.getClassLoader());
code = Base64.decode(code, "utf-8");
try {
Class groovyClass = loader.parseClass(code);
GroovyObject scriptInstance = (GroovyObject) groovyClass.newInstance();
ret = scriptInstance.invokeMethod("doTask", params);
} catch (Exception e) {
LOG.error("执行Groovy代码时抛错:", e);
}
}
return ret;
}
2.解析Shell
/**
* 调用Shell代码
* @param code 数据库取出的代码
* @param params 调用方法的参数
* @return 返回值
*/
private Object processShellCode(String code, DyncCallParameter params) {
Object ret = null;
if (StringUtils.isNotBlank(code)) {
code = Base64.decode(code, "utf-8");
try {
ret = runShell(code, params);
} catch (Exception e) {
LOG.error("执行Shell脚步抛错:", e);
}
}
return ret;
}
/**
* 执行shell脚本并返回结果
*
* @param shStr
* @return
* @throws Exception
*/
private List runShell(String shStr, DyncCallParameter params) throws Exception {
List<String> strList = new ArrayList();
Process process;
process = Runtime.getRuntime().exec(shStr);
InputStreamReader ir = new InputStreamReader(process.getInputStream());
LineNumberReader input = new LineNumberReader(ir);
String line;
process.waitFor();
while ((line = input.readLine()) != null) {
strList.add(line);
}
return strList;
}
对于Shell的调用,入参的结构复杂了,会不好处理。因为Shell本身的原因,调用shell时没有使用入参,这个比较棘手。