服务器之家

专注于服务器技术!
当前位置:首页 > Web服务器 > Apache

Java程序使用用BSF + Beanshell实现eval功能

发布时间:2014-04-08 来源:服务器之家

BSF(Bean Scripting Framework)最初是IBM Alpha工作组的项目,后来贡献给了Apache,BSF使Java能够更好的与各种流行脚本语言整合,实现不同语言之间的交互功能。Beanshell是一种完全符合Java语法的脚本语言。

运行以下代码需下载相关jar包(http://jakarta.apache.org/bsf/,http://www.beanshell.org/)

PS:新浪博客将“eval”视为危险角本,所以将下面例子里的所有“eval”方法替换成了“eval_r”。 

//测试类

public class BSFScript extends Scriptable {

    public static void main(String[] args) {

       try {

           // 根据(3 > 2)返回true/false

           Object flag = bsfEngine.eval_r(defaultEngine, 0, 0, "(3 > 2)");

           if (Boolean.valueOf(flag.toString())) {

              System.out.println("do something...");

           }

 

           AuthorBean bean = new AuthorBean();

           variableMap.put("author", "lijingcheng1984");

           // variableMap和AuthorBean类名在随后执行角本时,会预先注册到BSF管理器中,

           // 所以author和AuthorBean可以在角本中作为变量使用。

           String expr = "if(AuthorBean.getBlogAddress().lastIndexOf(author) != -1) "

                  + "{ return AuthorBean.getBlogAddress(); }";

           System.out.println(bean.getScriptable().eval_r(expr));

       } catch (Exception e) {

           System.out.println(e.getMessage());

       }

    }

}

 

//此接口用于标识继承类支持角本化

public interface IScriptableToken {

    Scriptable getScriptable();

}

 

//可角本化的Java Bean类

public class AuthorBean implements IScriptableToken {

    public String getBlogAddress() {

       return "http://blog.sina.com/lijingcheng1984";

    }

   

    @Override

    public Scriptable getScriptable() {

       return new Scriptable(this);

    }

}

 

import java.util.Hashtable;

import java.util.Map;

 

import org.apache.bsf.BSFEngine;

import org.apache.bsf.BSFException;

import org.apache.bsf.BSFManager;

 

//角本化功能类

public class Scriptable {

    private static BSFManager mgr;

    protected static BSFEngine bsfEngine;

    protected static Map<String, Object> variableMap;

    private IScriptableToken scriptableObject;

    protected static final String defaultEngine = "beanshell";

 

    public Scriptable() {

 

    }

 

    public Scriptable(IScriptableToken scriptableObject) {

       this.scriptableObject = scriptableObject;

    }

 

    static {

       try {

           mgr = new BSFManager();

           bsfEngine = mgr.loadScriptingEngine(defaultEngine);

           variableMap = new Hashtable<String, Object>();

       } catch (BSFException e) {

           e.printStackTrace();

       }

    }

 

    //注册并绑定对象,以后可以通过key值访问此对象

    private void putVariable(String key, Object value) throws BSFException {

       for (final Map.Entry<String, Object> entry : variableMap.entrySet()) {

           mgr.declareBean(entry.getKey(), entry.getValue(), entry.getValue()

                  .getClass());

       }

       mgr.declareBean(key, value, value.getClass());

    }

 

    //执行角本并提供返回值

    protected Object eval_r(final String expr) {

       try {

           String className = scriptableObject.getClass().getName();

           String key = className.substring(className.lastIndexOf(".") + 1);

           putVariable(key, scriptableObject);

           return mgr.eval_r(defaultEngine, "", 0, 0, expr);

       } catch (final BSFException e) {

           return e.getMessage();

       }

    }

}