首页
学习
活动
专区
圈层
工具
发布

Jfinal集成beanshell开发后端接口直接页面上编辑代码无需发布和重启服务

BeanShell是一种小型、免费、可嵌入的Java源代码解释器,具有以下核心特性和应用场景:

核心特性

兼容性与灵活性

完全支持标准Java语法,允许动态执行Java代码片段,同时扩展了脚本语言的特性(如松散类型、命令式编程、闭包等)。

解释器jar包大小仅约175KB,可轻松集成到任何Java应用程序中。

对象脚本语言特性

通过Java反射API实现动态调用,可透明访问所有Java对象和API,无需额外编译。

支持脚本化对象和闭包,允许在脚本中直接操作Java类和方法。

多模式运行支持

可在命令行、控制台、小程序(Applet)及远程线程服务器模式下运行,适应不同开发需求。

创建DynamicRouteController.java编写代码如下:

public class DynamicRouteController extends Controller {   public static String DEFAULT_ROUTE = "/v2/api";   private Interpreter bshInterpreter;   /**    * url 对应执行本方法    */   @Before({ GET.class })   public void index() {       LogKit.debug("enter DynamicRouteController index()");       execute();       // 调试完成后, 将debug方法内容更新到数据库并注释掉本方法!       // debug();   }   @Before({ POST.class })   public void post() {       LogKit.debug("enter DynamicRouteController index()");       execute();       // 调试完成后, 将debug方法内容更新到数据库并注释掉本方法!       // debug();   }   @Before({ POST.class, Authorization.class })   public void authpost() {       LogKit.debug("enter DynamicRouteController index()");       authexecute();       // 调试完成后, 将debug方法内容更新到数据库并注释掉本方法!       // debug();   } @Before({ GET.class, Authorization.class })   public void authget() {       LogKit.debug("enter DynamicRouteController index()");       authexecute();       // 调试完成后, 将debug方法内容更新到数据库并注释掉本方法!       // debug();   }   private void authexecute() {       // 动态执行java代码       // 进入自定义api       try {            LoginUsers usersModel = Common.getLoginUser(this);           bshInterpreter = new Interpreter();           bshInterpreter.set("request", this.getRequest());           bshInterpreter.set("response", this.getResponse());           bshInterpreter.set("usersModel", usersModel);             String _codes=       getAttrForStr("code");           if (_codes==null) {                    Result ret = new Result();               ret.setCode(500);               ret.setMsg(" _codes is null" );               ret.setSuccess(false);               renderJson(ret);               return;           }           Object da = bshInterpreter.eval(_codes); // 执行脚本           renderJson(da);       } catch (Exception e) {           Result ret = new Result();           ret.setCode(500);           ret.setMsg("Error executing script: " + e.getMessage());           ret.setSuccess(false);           renderJson(ret);       }   }   private void execute() {       // 动态执行java代码       // 进入自定义api       try {           bshInterpreter = new Interpreter();           bshInterpreter.set("request", this.getRequest());           bshInterpreter.set("response", this.getResponse());           String _codes=       getAttrForStr("code");           if (_codes==null) {                    Result ret = new Result();               ret.setCode(500);               ret.setMsg(" _codes is null" );               ret.setSuccess(false);               renderJson(ret);               return;           }           Object da = bshInterpreter.eval(_codes); // 执行脚本           renderJson(da);       } catch (Exception e) {           Result ret = new Result();           ret.setCode(500);           ret.setMsg("Error executing script: " + e.getMessage());           ret.setSuccess(false);           renderJson(ret);       }   }   /*    * 将需要调试的java代码放到本方法    */   private void debug() {       DynamicRouteController ctrl = this;       LogKit.fatal("debug only, 当出现这句话表明没有注释本方法!!!!!-----------------------");     }}

在configRoute中注册动态路由,路由为v2的接口说明为动态路由,配置支持get、post,如果需要登录@Before({Authorization.class })

// 注册动态路由  me.add(DynamicRouteController.DEFAULT_ROUTE, DynamicRouteController.class);

也可创建一张表来存储如下:

到处开发已经完成。接下来看看实际应用:已经实现的接口如下

分页查询数据,语法直接使用jfinal可无缝衔接。

import com.jfinal.plugin.activerecord.Page;import com.jfinal.plugin.activerecord.Record;import com.jfinal.plugin.activerecord.Db;import com.asxsydutils.utils.Result;import org.apache.commons.lang3.math.NumberUtils;Result ret = new Result();    int page = NumberUtils.toInt(request.getParameter("page"), 1);    int limit = NumberUtils.toInt(request.getParameter("limit"), 10);   Page  d = Db.paginate(page, limit, "select * ", "from dynamicroute");        ret.setCount((long) d.getTotalRow());           ret.setCode(0);           ret.setData(d.getList());           ret.setMsg("执行成功 ");           ret.setSuccess(true);

return ret;

请求如下:

注意事项

安全性

脚本沙箱

避免直接执行用户输入的脚本,建议使用白名单限制可调用的API。

权限控制

对脚本操作的对象(如数据库、文件系统)进行隔离。

输入校验

过滤恶意代码(如Runtime.getRuntime().exec())。

性能

解释执行开销

BeanShell是解释型语言,复杂逻辑建议用Java实现。

线程安全

Interpreter实例非线程安全,需为每个请求创建独立实例或使用线程局部变量。

错误处理

捕获EvalError等异常,返回友好的错误信息。

记录脚本执行日志,便于调试。

依赖管理

避免脚本中直接引用项目类,需通过setVariable显式注入。

也可使用lua集成,BeanShell和Lua是两种不同的脚本语言,在应用场景、语言特性等方面存在明显差异,以下为你详细对比:

语法与特性

BeanShell

语法

BeanShell是一种轻量级的Java源代码解释器,它的语法与Java高度兼容,支持标准Java语法,允许动态执行Java代码片段,对于熟悉Java的开发者来说,学习成本较低。

特性

具有松散类型、命令式编程、闭包等特性,支持动态类型的变量声明,如同Perl和JavaScript般便捷。它还提供了透明访问所有Java对象和API的能力,能够直接操作“活”的Java对象。

Lua

语法

Lua语法简单直观,易于理解和上手,它采用动态类型,用户在编程时不需要预先定义数据类型,增强了语言的灵活性。

特性

具有高效性、可扩展性、可移植性强等特点。Lua的解释器非常轻量级,运行速度快,并且占用系统资源少。它还支持多种编程范式,包括命令式、面向对象和函数式编程。

应用场景

BeanShell

Java应用扩展

适合在Java应用中需要动态执行代码的场景,例如在JFinal等Java框架中集成,实现动态逻辑扩展、快速原型开发、用户自定义逻辑等。

测试与调试

在测试阶段,可以通过BeanShell快速验证逻辑,后期再迁移到Java代码。

Lua

游戏开发

在游戏开发领域应用广泛,许多知名游戏引擎如Unity、CryEngine、Corona等都支持Lua作为脚本语言,用于控制游戏逻辑、配置数据、定义角色行为等。

嵌入式系统

由于其轻量级特性,适合用作嵌入式系统的脚本语言,在需要对底层硬件进行控制的场合,Lua可以作为一种高层次的语言,帮助开发者更快速地实现功能。

网络编程

在高并发的网络服务中,Lua可以通过协程的特性简化异步编程,提升代码可读性和管理性。例如,OpenResty是一个基于Nginx的Web应用服务器,它能够通过Lua脚本编写高性能的Web应用。

性能

BeanShell

由于是基于Java的解释执行,在性能上相对Java代码会有一定的开销,但对于一些对性能要求不高的动态逻辑处理场景,完全可以满足需求。

Lua

虽然是解释型语言,但Lua的执行速度较快,内存占用也低,适合资源有限的嵌入式设备,在解释型语言中性能表现较为出色。

生态系统

BeanShell

主要围绕Java生态系统,可以方便地与各种Java库和框架集成,但相对来说,其自身的生态系统相对较小,社区活跃度可能不如一些主流语言。

Lua

在游戏开发、嵌入式系统等领域拥有良好的支持,有许多成熟的库和框架可供使用,社区也比较活跃,开发者可以方便地获取相关的资源和帮助。

  • 发表于:
  • 原文链接https://page.om.qq.com/page/OExljPbIYq-IDim8srGxm1aw0
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。
领券