2019独角兽企业重金招聘Python工程师标准>>>
突然想起之前做过的一个小项目,项目虽小,需求却不小,要求解析特定格式的字符串,并且特定格式并非一成不变,想要一套系统能够支持解析多变的规则且更改规则时不能起停服务。
java先天因素决定了他不能支持热加载,所以就着手从其它语言结合使用,于是javascript就被揪出来了,编写容易,与java易集成。下面是对其简单做了封装,使其通用易迁移。
IJSEngine.java 核心接口
package com.voole.p2pauth.util.js.service;import java.util.Map;public interface IJSEngine {String getStringReturn(String jsFile, String functionname);String getStringReturn(String jsFile, String functionname, Object... args);String getStringReturnByRealPath(String jsFile, String functionname);String getStringReturnByRealPath(String jsFile, String functionname, Object... args);Boolean addGlobleJavaObj(Map<String, Object> globleJavaObjMap);
}
JSEngineImpl.java 接口实现
package com.voole.p2pauth.util.js.center;import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;import javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;import org.apache.log4j.Logger;import com.voole.p2pauth.util.js.service.IJSEngine;public class JSEngineImpl implements IJSEngine {private static final Logger LOGGER = Logger.getLogger(JSEngineImpl.class);private static final ScriptEngineManager manager = new ScriptEngineManager();private static final ScriptEngine engine = manager.getEngineByName("javascript");private Map<String, Object> globleJavaObj = new HashMap<>();private boolean evalJSByClassPathFile(String jsfileName) {try {ClassLoader classLoader = JSEngineImpl.class.getClassLoader();InputStream reader = classLoader.getResourceAsStream("rule/" + jsfileName + ".js");if (null == reader) {return false;}if (null != this.globleJavaObj && this.globleJavaObj.size() > 0) {for (Entry<String, Object> obj : this.globleJavaObj.entrySet()) {engine.put(obj.getKey(), obj.getValue());}}engine.eval(new BufferedReader(new InputStreamReader(reader)));return true;} catch (ScriptException e) {LOGGER.error(e.getMessage(), e);// e.printStackTrace();return false;}}private boolean evalJSByRealPathFile(String jsfileName) {try {if (null != this.globleJavaObj && this.globleJavaObj.size() > 0) {for (Entry<String, Object> obj : this.globleJavaObj.entrySet()) {engine.put(obj.getKey(), obj.getValue());}}engine.eval(new BufferedReader(new FileReader(jsfileName)));return true;} catch (ScriptException | FileNotFoundException e) {LOGGER.error(e.getMessage(), e);// e.printStackTrace();return false;}}@Overridepublic String getStringReturn(String jsFile, String functionname) {if (this.evalJSByClassPathFile(jsFile)) {if (engine instanceof Invocable) {return this.invoke(functionname);}}return null;}@Overridepublic String getStringReturn(String jsFile, String functionname, Object... args) {if (this.evalJSByClassPathFile(jsFile)) {if (engine instanceof Invocable) {return this.invoke(functionname, args);}}return null;}@Overridepublic String getStringReturnByRealPath(String jsFile, String functionname) {if (this.evalJSByRealPathFile(jsFile)) {if (engine instanceof Invocable) {return this.invoke(functionname);}}return null;}@Overridepublic String getStringReturnByRealPath(String jsFile, String functionname, Object... args) {if (this.evalJSByRealPathFile(jsFile)) {if (engine instanceof Invocable) {return this.invoke(functionname, args);}}return null;}private <T> T invoke(String funcname, Object... args) {Invocable invocable = (Invocable) engine;try {return (T) invocable.invokeFunction(funcname, args);} catch (NoSuchMethodException | ScriptException e) {LOGGER.error(e.getMessage(), e);// e.printStackTrace();return null;}}@Overridepublic Boolean addGlobleJavaObj(Map<String, Object> globleJavaObjMap) {this.globleJavaObj = globleJavaObjMap;return true;}}
调用
public static void main(String[] args) {IJSEngine ENGINE = SccUtilFactory.instanceJSEngine();// 设置js全局变量Map<String, Object> globleJavaObj = getGlobleObj();ENGINE.addGlobleJavaObj(globleJavaObj);// 执行js规则解析,并返回解析后的playurlString play_url = ENGINE.getStringReturn(test.jd,……);
}
js文件
function auth_validate_1_0(data){LOGGER.info("data:"+data);var jdata=eval('(' + data + ')');var urlObj=eval('(' + JsUtil.urlToObject(jdata.url) + ')');}