BeanShell(对象脚本语言)

来源:互联网 发布:王江涛背作文 知乎 编辑:程序博客网 时间:2024/06/08 01:15

BeanShell使用背景:公司的抓取管理平台,公司的产品人员每天都需要对各个地方的运营商网站看一些违规,投诉,公告等信息进行监控,为了保证产品人员不必要每天都上各个网站上看信息,所以针对内部需求,我们采用抓取策略,用程序模拟登录每一个网站,然后对我们要的信息,如公告信息进行抓取,当然抓取到网页之后还要配合HtmlParse技术进行处理,然后将我们提取出的信息显示到我们平台上,这样产品人员不需要登录每一个网站看信息,只要登录我们的抓取平台就可以看各个网站最新的公告等信息。因为每一个运营商的各个地方的网站是不一样的,也就是说抓取的各个业务是不一样的,针对这种情况,我们采用BeanShell来处理各个不同的业务。对不同的网站采用不同的BSH文件来处理,这样各个网站的抓取代码都放到不同的BSH文件中,不用每多抓取一个网站重新修改代码,重新发布。这样可以减少很多工作量。下面介绍一下BeanShell.

首先:BeanShell:是一种对象脚本语言http://www.beanshell.org)。BeanShell的解释器是用Java写的,开源并且免费的,它的运作方式它将脚本化对象看作简单闭包方法 simple method closure)来支持,就如同在 JavaScript中的一样。 它具有以下的一些特点:使用Java反射API以提供Java语句和表达式 的实时解释执行;可以透明地访问任何Java对象和API;可以在命令行模式、控制台模式、小程序模式和远程线程服务器模式等四种模式下面运行;与在应用 程序中一样,可以在小程序中(Applet)正常运行(无需编译器或者类装载器);非常精简的解释器jar文件大小为175k ”

     使用BeanShell可以处理现实中不规则的业务,举个很典型的例子,我们知道,一个保险公司有很多险种,每个险种的投入和收益的算法是很复杂的,无法 用规则的关系数据库模型来描述,所以很多保险系统在处理险种的算法都是硬编码,如果要在系统中新加一个险种,是非常麻烦的,重新修改代码,重新发布,这对 开发/维护人员和客户都是很痛苦的,有了BeanShell,我们可以从这种痛苦中解脱出来,对每个险种使用不同的脚本,新加的险种我们新配一个脚本,这 样既可以满足业务多变的要求,又可以减少工作量,节约成本。

     BeanShell的一个特点是动态执行Java代码,脚本文件改变不会影响当前脚本的调用,新脚本将在脚本的下一次调用生效,这不同于配置文件,配置文件改变一般都需要应用重启。

       一个BeanShell的简单例子:

通过建立一个BeanShell解释器,使用eval()source()命令,你可以在你的应用程序中求文本表达式的值和运行脚本。如果你希望在你的脚本内部使用一个对象,可以用set()方法传递对象的变量参照给BeanShell,并通过get()方法取得结果。

Java文件中

package com.an;

import java.io.FileNotFoundException;

import java.io.IOException;

 

import bsh.EvalError;

import bsh.Interpreter;

 

 

public class TestBeanShell {

    /**

     * 一个简单往BEANSHELL的文件传入参数,然后.java文件接收参数进行处理,然后返回结果

     * .java文件中打印结果

     */

    public static void main(String[] args) {

       Interpreter  inter  = new Interpreter();      

       try {

           //bsh文件中传入参数(BeanShell文件中可以直接用,不用再定义)

           inter.set("inValue",new Integer(1));  

           //调用并执行BSH文件

           inter.source("src/com/an/testBeanShell.bsh");

           //获得bsh文件中的结果

           String resultValue = inter.get("outValue").toString();

           System.out.println("=====输出结果========="+resultValue);

       } catch (EvalError e) {        

           e.printStackTrace();

       } catch (FileNotFoundException e) {          

           e.printStackTrace();

       } catch (IOException e) {         

           e.printStackTrace();

       }     

    }

}

Bsh文件

//BeanShell中打印调用print()函数

print("=======传入的参数======="+inValue);

outValue = inValue+1;

 

一些常用的命令 (绿色的是我在项目中用到的)

print()avaSystem.out.println()非常的相像,除非它能保证输出总是命令行。print()也可以显示一些对象的类型(如数组),但比Java的更详细。

source(), run() : 将一个bsh脚本读到解释器或运行在另一个解释器。

frame() - 显示一个FrameJFrameGUI组件.
load(), save() -
载入和保存一个序列化的对象到一个文件
.
cd(), cat(), dir(), pwd(), etc. -
unixshell命令。

exec() -
运行一个本地的程序。

javap() - 打印一个对象的方法和字段,类似于Javajavap命令。
setAccessibility() - 开启无限制的存取private protected的组件。

 

脚本方法

你可以在bsh中宣告和使用方法,就像在java的类中一样。只是bsh的方法可以有动态的(宽松的)参数和返回类型。

//bsh文件中的定义方法(两个数相加)

public int add(int num1 , int num2 ){

    return num1+num2;

}

int result = add(1,2);

print(result);

注意:bsh文件的加载顺序是从上到下加载,上面例子中如果

int result = add(1,2);

print(result);

public int add(int num1 , int num2 ){

    return num1+num2;

}

则会报

 

ourced file: src/com/an/testBeanShell.bsh : Typed variable declaration : Command not found: add( int, int ) : at Line: 1 : in file: src/com/an/testBeanShell.bsh : add ( 1 , 2 )

    at bsh.Name.invokeLocalMethod(Unknown Source)

这个是BSH文件中常到的一个错误Unknown Source未知源对象)。

原创粉丝点击