在java中使用ScriptEngine,如何提取函数列表?
使用Jsoup,我提取html文件中的JavaScript部分。并将其存储为java字符串对象 我想使用javax.script.ScriptEngine JavaScript部分有几个功能部分 ex) 我的目标就在下面 列表函数列表 a B c 列表varListA a_1 a_2 列表varListB b_1 b_2 列表varListC c_1 c_2在java中使用ScriptEngine,如何提取函数列表?,java,javascript,scriptengine,Java,Javascript,Scriptengine,使用Jsoup,我提取html文件中的JavaScript部分。并将其存储为java字符串对象 我想使用javax.script.ScriptEngine JavaScript部分有几个功能部分 ex) 我的目标就在下面 列表函数列表 a B c 列表varListA a_1 a_2 列表varListB b_1 b_2 列表varListC c_1 c_2 如何提取函数列表和变量列表(或者可能是值)?我认为您可以在引擎中加载javascript后使用javascript自省来实现这一点-
如何提取函数列表和变量列表(或者可能是值)?我认为您可以在引擎中加载javascript后使用javascript自省来实现这一点-例如,对于函数:
ScriptEngine engine;
// create the engine and have it load your javascript
Bindings bind = engine.getBindings(ScriptContext.ENGINE_SCOPE);
Set<String> allAttributes = bind.keySet();
Set<String> allFunctions = new HashSet<String>();
for ( String attr : allAttributes ) {
if ( "function".equals( engine.eval("typeof " + attr) ) ) {
allFunctions.add(attr);
}
}
System.out.println(allFunctions);
脚本引擎;
//创建引擎并让它加载javascript
Bindings bind=engine.getBindings(ScriptContext.engine\u范围);
设置allAttributes=bind.keySet();
Set allFunctions=new HashSet();
for(字符串属性:allAttributes){
if(“function.”等于(engine.eval(“typeof”+attr))){
allFunctions.add(attr);
}
}
System.out.println(所有函数);
我还没有找到一种方法来提取函数中的变量(局部变量),而不深入研究javascript脚本引擎的内部机制(因此使用起来不安全) 我认为您可以在引擎中加载javascript后使用javascript内省来实现这一点,例如,对于函数:
ScriptEngine engine;
// create the engine and have it load your javascript
Bindings bind = engine.getBindings(ScriptContext.ENGINE_SCOPE);
Set<String> allAttributes = bind.keySet();
Set<String> allFunctions = new HashSet<String>();
for ( String attr : allAttributes ) {
if ( "function".equals( engine.eval("typeof " + attr) ) ) {
allFunctions.add(attr);
}
}
System.out.println(allFunctions);
脚本引擎;
//创建引擎并让它加载javascript
Bindings bind=engine.getBindings(ScriptContext.engine\u范围);
设置allAttributes=bind.keySet();
Set allFunctions=new HashSet();
for(字符串属性:allAttributes){
if(“function.”等于(engine.eval(“typeof”+attr))){
allFunctions.add(attr);
}
}
System.out.println(所有函数);
我还没有找到一种方法来提取函数中的变量(局部变量),而不深入研究javascript脚本引擎的内部机制(因此使用起来不安全) 这相当棘手<代码>脚本引擎API似乎不适合检查代码。所以,我有这样一个非常丑陋的解决方案,使用
实例
和cast
操作符
Bindings bindings = engine.getBindings(ScriptContext.ENGINE_SCOPE);
for (Map.Entry<String, Object> scopeEntry : bindings.entrySet()) {
Object value = scopeEntry.getValue();
String name = scopeEntry.getKey();
if (value instanceof NativeFunction) {
log.info("Function -> " + name);
NativeFunction function = NativeFunction.class.cast(value);
DebuggableScript debuggableFunction = function.getDebuggableView();
for (int i = 0; i < debuggableFunction.getParamAndVarCount(); i++) {
log.info("First level arg: " + debuggableFunction.getParamOrVarName(i));
}
} else if (value instanceof Undefined
|| value instanceof String
|| value instanceof Number) {
log.info("Global arg -> " + name);
}
}
Bindings Bindings=engine.getBindings(ScriptContext.engine\u范围);
对于(Map.Entry scopeEntry:bindings.entrySet()){
对象值=scopeEntry.getValue();
字符串名称=scopeEntry.getKey();
if(NativeFunction的值实例){
log.info(“函数->”+名称);
NativeFunction=NativeFunction.class.cast(值);
DebuggableScript debuggableFunction=function.getDebuggableView();
对于(int i=0;i”+名称);
}
}
这相当棘手<代码>脚本引擎API似乎不适合检查代码。所以,我有这样一个非常丑陋的解决方案,使用实例
和cast
操作符
Bindings bindings = engine.getBindings(ScriptContext.ENGINE_SCOPE);
for (Map.Entry<String, Object> scopeEntry : bindings.entrySet()) {
Object value = scopeEntry.getValue();
String name = scopeEntry.getKey();
if (value instanceof NativeFunction) {
log.info("Function -> " + name);
NativeFunction function = NativeFunction.class.cast(value);
DebuggableScript debuggableFunction = function.getDebuggableView();
for (int i = 0; i < debuggableFunction.getParamAndVarCount(); i++) {
log.info("First level arg: " + debuggableFunction.getParamOrVarName(i));
}
} else if (value instanceof Undefined
|| value instanceof String
|| value instanceof Number) {
log.info("Global arg -> " + name);
}
}
Bindings Bindings=engine.getBindings(ScriptContext.engine\u范围);
对于(Map.Entry scopeEntry:bindings.entrySet()){
对象值=scopeEntry.getValue();
字符串名称=scopeEntry.getKey();
if(NativeFunction的值实例){
log.info(“函数->”+名称);
NativeFunction=NativeFunction.class.cast(值);
DebuggableScript debuggableFunction=function.getDebuggableView();
对于(int i=0;i”+名称);
}
}
我也有类似的问题。也许这对其他人会有帮助。
我使用groove作为脚本语言。我的任务是从脚本中检索所有可调用的函数。然后根据一些条件过滤这些函数
不幸的是,这种方法只对groovy有用
获取脚本引擎:
public ScriptEngine getEngine() throws Exception {
if (engine == null)
engine = new ScriptEngineManager().getEngineByName(scriptType);
if (engine == null)
throw new Exception("Could not find implementation of " + scriptType);
return engine;
}
public void evaluateScript(String script) throws Exception {
Bindings bindings = getEngine().getBindings(ScriptContext.ENGINE_SCOPE);
bindings.putAll(binding);
try {
if (engine instanceof Compilable)
compiledScript = ((Compilable)getEngine()).compile(script);
getEngine().eval(script);
} catch (Throwable e) {
e.printStackTrace();
}
}
public Object executeFunc(String name) throws Exception {
return ((Invocable)getEngine()).invokeFunction(name);
}
编译和评估脚本:
public ScriptEngine getEngine() throws Exception {
if (engine == null)
engine = new ScriptEngineManager().getEngineByName(scriptType);
if (engine == null)
throw new Exception("Could not find implementation of " + scriptType);
return engine;
}
public void evaluateScript(String script) throws Exception {
Bindings bindings = getEngine().getBindings(ScriptContext.ENGINE_SCOPE);
bindings.putAll(binding);
try {
if (engine instanceof Compilable)
compiledScript = ((Compilable)getEngine()).compile(script);
getEngine().eval(script);
} catch (Throwable e) {
e.printStackTrace();
}
}
public Object executeFunc(String name) throws Exception {
return ((Invocable)getEngine()).invokeFunction(name);
}
从脚本获取函数。除了反射之外,我没有找到从脚本获取所有可调用方法的其他方法。是的,我知道这种方法依赖于ScriptEngine实现,但这是唯一的一种:)
脚本示例:
import com.vssk.CalculatedField;
def utilFunc(s) {
s
}
@CalculatedField
def func3() {
utilFunc('Testing func from groovy')
}
通过名称调用脚本函数的方法:
public ScriptEngine getEngine() throws Exception {
if (engine == null)
engine = new ScriptEngineManager().getEngineByName(scriptType);
if (engine == null)
throw new Exception("Could not find implementation of " + scriptType);
return engine;
}
public void evaluateScript(String script) throws Exception {
Bindings bindings = getEngine().getBindings(ScriptContext.ENGINE_SCOPE);
bindings.putAll(binding);
try {
if (engine instanceof Compilable)
compiledScript = ((Compilable)getEngine()).compile(script);
getEngine().eval(script);
} catch (Throwable e) {
e.printStackTrace();
}
}
public Object executeFunc(String name) throws Exception {
return ((Invocable)getEngine()).invokeFunction(name);
}
我也有类似的问题。也许这对其他人会有帮助。 我使用groove作为脚本语言。我的任务是从脚本中检索所有可调用的函数。然后根据一些条件过滤这些函数 不幸的是,这种方法只对groovy有用 获取脚本引擎:
public ScriptEngine getEngine() throws Exception {
if (engine == null)
engine = new ScriptEngineManager().getEngineByName(scriptType);
if (engine == null)
throw new Exception("Could not find implementation of " + scriptType);
return engine;
}
public void evaluateScript(String script) throws Exception {
Bindings bindings = getEngine().getBindings(ScriptContext.ENGINE_SCOPE);
bindings.putAll(binding);
try {
if (engine instanceof Compilable)
compiledScript = ((Compilable)getEngine()).compile(script);
getEngine().eval(script);
} catch (Throwable e) {
e.printStackTrace();
}
}
public Object executeFunc(String name) throws Exception {
return ((Invocable)getEngine()).invokeFunction(name);
}
编译和评估脚本:
public ScriptEngine getEngine() throws Exception {
if (engine == null)
engine = new ScriptEngineManager().getEngineByName(scriptType);
if (engine == null)
throw new Exception("Could not find implementation of " + scriptType);
return engine;
}
public void evaluateScript(String script) throws Exception {
Bindings bindings = getEngine().getBindings(ScriptContext.ENGINE_SCOPE);
bindings.putAll(binding);
try {
if (engine instanceof Compilable)
compiledScript = ((Compilable)getEngine()).compile(script);
getEngine().eval(script);
} catch (Throwable e) {
e.printStackTrace();
}
}
public Object executeFunc(String name) throws Exception {
return ((Invocable)getEngine()).invokeFunction(name);
}
从脚本获取函数。除了反射之外,我没有找到从脚本获取所有可调用方法的其他方法。是的,我知道这种方法依赖于ScriptEngine实现,但这是唯一的一种:)
脚本示例:
import com.vssk.CalculatedField;
def utilFunc(s) {
s
}
@CalculatedField
def func3() {
utilFunc('Testing func from groovy')
}
通过名称调用脚本函数的方法:
public ScriptEngine getEngine() throws Exception {
if (engine == null)
engine = new ScriptEngineManager().getEngineByName(scriptType);
if (engine == null)
throw new Exception("Could not find implementation of " + scriptType);
return engine;
}
public void evaluateScript(String script) throws Exception {
Bindings bindings = getEngine().getBindings(ScriptContext.ENGINE_SCOPE);
bindings.putAll(binding);
try {
if (engine instanceof Compilable)
compiledScript = ((Compilable)getEngine()).compile(script);
getEngine().eval(script);
} catch (Throwable e) {
e.printStackTrace();
}
}
public Object executeFunc(String name) throws Exception {
return ((Invocable)getEngine()).invokeFunction(name);
}
您希望执行代码还是静态检查代码<代码>脚本引擎可能适合执行,尽管它缺少DOM之类的东西。如果您想检查代码,AST解析器更合适(例如Antlr或Mozilla)