最近做项目时遇到项目间相互调用的功能,开始打算用webservice来解决,但是考虑到性能问题已经时间等待问题,最终还是决定通过Java公式调用方式解决,一下为部分调用代码
package seentao.imp.formula;
import static test.imp.formula.FormulaExecTypeEnum.JAVA_METHOD;
import static test.imp.formula.FormulaExecTypeEnum.JS_SCRIPT;
import static test.imp.formula.FormulaExecTypeEnum.SQL_CAUSE;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import org.mozilla.javascript.Context;
import org.mozilla.javascript.ScriptableObject;
public class FormulaInvoker {
private Context cx;
private ScriptableObject scope;
private SimpleDateFormat dateFmt;
private boolean reInit = true;
private FormulaVO[] fmlVOs;
private static final String JAVA_METHOD_NAME_KEY = "invokeJavaMethod";
private static final String SQL_CAUSE_NAME_KEY = "invokeSqlCause";
private static final String JAVA_SCRIPT_NAME_KEY = "invokeJavaScript";
public void setFmlVOs(FormulaVO[] fmlVOs) {
this.fmlVOs = fmlVOs;
}
public void init() {
if (reInit) {
cx = Context.enter();
scope = cx.initStandardObjects();
dateFmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
for (FormulaVO vo : fmlVOs) {
String source = null;
if (JAVA_METHOD.equals(vo.getExec_type())) {
source = createScriptSource(vo.getFunc_name(), JAVA_METHOD_NAME_KEY, vo.getFml_code());
} else if (SQL_CAUSE.equals(vo.getExec_type())) {
source = createScriptSource(vo.getFunc_name(), SQL_CAUSE_NAME_KEY, vo.getFml_code());
} else if (JS_SCRIPT.equals(vo.getExec_type())) {
source = createScriptSource(vo.getFunc_name(), JAVA_SCRIPT_NAME_KEY, vo.getFml_code());
}
cx.evaluateString(scope, source, "", 0, null);
}
reInit = false;
}
}
public void reset() {
reInit = true;
}
public Object invoke(FormulaVO fmlVO, Map<String, Object> params) {
if (params == null) {
params = new HashMap<String, Object>();
}
// 注入参数
for (Entry<String, Object> entry : params.entrySet()) {
scope.put(entry.getKey(), scope, entry.getValue());
}
// 执行脚本函数
String funcExp = String.format("'' + %s", fmlVO.getFunc_name());
//可以直接得到调用项目的结果
Object result = cx.evaluateString(scope, funcExp, "", 0, null);
// 清除参数
for (Entry<String, Object> entry : params.entrySet()) {
scope.delete(entry.getKey());
}
// 处理结果
String returnType = fmlVO.getReturn_type();
try {
if (FormulaReturnType.BOOLEAN.equals(returnType)) {
return "true".equals(result);
} else if (FormulaReturnType.BYTE.equals(returnType)) {
return Byte.parseByte(result.toString());
} else if (FormulaReturnType.SHORT.equals(returnType)) {
return Short.parseShort(result.toString());
} else if (FormulaReturnType.INTEGER.equals(returnType)) {
return Integer.parseInt(result.toString());
} else if (FormulaReturnType.LONG.equals(returnType)) {
return Long.parseLong(result.toString());
} else if (FormulaReturnType.FLOAT.equals(returnType)) {
return Float.parseFloat(result.toString());
} else if (FormulaReturnType.DOUBLE.equals(returnType)) {
return Double.parseDouble(result.toString());
} else if (FormulaReturnType.STRING.equals(returnType)) {
return result.toString();
} else if (FormulaReturnType.DATE.equals(returnType)) {
return dateFmt.parse((String) result);
} else if (FormulaReturnType.ARRAY.equals(returnType)) {
return result.toString();
} else if (FormulaReturnType.TWO_DIM_ARRAY.equals(returnType)) {
return result.toString();
} else {
return result;
}
} catch (Exception e) {
e.printStackTrace();
return e.getMessage();
}
}
public void exit() {
Context.exit();
}
private String createScriptSource(String funcName, String methodName, String code) {
code = code.replaceAll("\"", "\\\\\"");
if (JAVA_SCRIPT_NAME_KEY.equals(methodName)) {
return createScriptSource(funcName, code);
} else {
if (SQL_CAUSE_NAME_KEY.equals(methodName)) {
code = code.trim();
if (code.indexOf("\\n") > 0) {
code = code.replaceAll("\\n", "");
}
}
String source = String.format("function %s {%n" +
"\treturn Packages.seentao.imp.formula.FormulaProxy.%s(\"%s\", arguments);%n" +
"}%n", funcName, methodName, code);
return source;
}
}
private String createScriptSource(String funcName, String code) {
code = code.indexOf("return ")>=0 ? code : "return " + code;
return String.format("function %s {try{%s;}catch(e){return e;}}%n", funcName, code);
}
}
关于Java引擎可参见:
http://blog.youkuaiyun.com/zhengyuanting/article/details/2973972