一、使用场景
在整个系统中,通用型的代码基本没什么变化,需要变动的仅仅是业务相关的代码。那么我们就会把一些业务代码简单编码一下放在数据库中。通过数据库的配置,可以直接从数据库中查找出来编码处理一下,来调用,这样,会省去了不少重复上线的繁琐了。
二、项目实战
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 { ListstrList = 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时没有使用入参,这个比较棘手。