使用Rhino实现自定义函数


         因为一些特别的要求,系统要提供一个自定义的文本框,让用户输入自定义的计算,系统要提供对用户输入的内容的解析和结果计算功能。经过一些搜索、查找和分析,选择使用Rhino和BSF+Beanshell。首先是使用Rhino试验了一下,感觉还不错,记录下来。BSF+Beanshell还没有试,后面试了再说。


         先从 http://www.mozilla.org/rhino/下载最新版的rhino,当前是1.74版。解压,然后在IDE中添加对解压后的js.jar库文件引用。


         先写个简单的表达式计算:

	public class MathEval {
    public static void main(String[] args){
        Context cx = Context.enter();
        try{
            Scriptable scope =  cx.initStandardObjects();
            String str = "8*(1+2)";
            Object result = cx.evaluateString(scope,str, null,1,null);
            double res = Context.toNumber(result);
            System.out.println(res);
        }
        catch (Exception ex){

        }
        finally {
            Context.exit();
        }
    }
}

在控制台输出24,成功!

再写一个自定义函数的调用:

先定义一个自定义javascript函数isPrime,文件名isPrime.js:

function isPrime (num)
{
    if (num <= 1) {
        print("Please enter a positive integer >= 2.")
        return false
    }
    var prime = true
    var sqrRoot = Math.round(Math.sqrt(num))
    for (var n = 2; prime & n <= sqrRoot; ++n) {
        prime = (num % n != 0)
    }
    return prime
}

Java调用:

public class RunIsPrime {
    private Context cx;
    private Scriptable scope;

    public static void main(String[] args){
        String filename = System.getProperty("user.dir") + "\\src\\isprime.js";
        RunIsPrime rip = new RunIsPrime();
        String jsContent = rip.getJsContent(filename);
        Context cx = Context.enter();
        // 初始化Scriptable
        Scriptable scope = cx.initStandardObjects();
        // 这一句是必须的,否则  scope.get("isPrime", scope)返回不了Function,而是返回UniqueTag
        cx.evaluateString(scope,jsContent,filename,1,null);
        // 得到自定义函数
        Function isPrimeFn = (Function) scope.get("isPrime", scope);
        // 看看得到的对象是个什么类型,这里是Function
        System.out.println(isPrimeFn.getClassName());
        // 调用自定义函数,第三个参数一般应该是传调用对象,但我发现对函数来说,传null也可以得到同样的结果
        // 第四个参数是函数的参数,以对象数据的形式传递
        Object isPrimeValue = isPrimeFn.call(cx,isPrimeFn,null,new Object[]{31});
        System.out.println("31 is prime? " + Context.toBoolean(isPrimeValue));
        isPrimeValue = isPrimeFn.call(Context.getCurrentContext(),isPrimeFn,isPrimeFn,new Object[]{33});
        System.out.println("33 is prime? " + Context.toBoolean(isPrimeValue));

    }

    private String getJsContent(String filename)
    {
        LineNumberReader reader;
        try
        {
            reader = new LineNumberReader(new FileReader(filename));
            String s = null;
            StringBuffer sb = new StringBuffer();
            while ((s = reader.readLine()) != null)
            {
                sb.append(s).append("\n");
            }
            return sb.toString();
        }
        catch (Exception e)
        {
            e.printStackTrace();
            return null;
        }
    }

}

         Rhino还可以让自定义的javascript和java交换数据,可以网上搜一下,很多的,如http://lcllcl987.iteye.com/blog/87423

         Rhino可以实现动态的功能解析,给自定的功能扩展保留一定的空间。




  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值