beanshell、jcef

BeanShell

BeanShell是一个小型嵌入式Java源代码解释器,具有对象脚本语言特性,能够动态地执行标准JAVA语法。

BeanShell不仅仅可以通过运行其内部的脚本来处理Java应用程序,还可以在运行过程中动态执行你java应用程序执行java代码。因为BeanShell是用java写的,运行在同一个虚拟机的应用程序,因此可以自由地引用对象脚本并返回结果。

BeanShell - Introduction

1、eval()

对脚本进行反射式访问的最简单形式是通过 eval() 命令....

工程在pom.xml引入

    <dependency><groupId>org.beanshell</groupId><artifactId>bsh-core</artifactId><version>2.0b4</version></dependency>

eval返回值为Object,可以通过eval()求文本表达式的值或者运行脚本;

Object o=interpreter.eval(str);

 bsh(BeanShell)动态执行java代码

public static void main(String[] args) throws EvalError {Interpreter bsh = new Interpreter();//循环打印变量bsh.eval("for(int i=0; i<5; i++) { System.out.println(\"hello\"); }");
}

2、source

把刚刚的"beanshell脚本"修改一下输出,放入一个文件中

String bshPath="C:\\Users\\Administrator\\Desktop\\slenium\\demo.bsh";
Interpreter bsh = new Interpreter();
//导入并执行一个脚本文件
bsh.source(bshPath);  // or bsh.eval("source(\"myscript.bsh\")");

1


3、松类型变量

Java是强类型的语言,必须声明类型,但是 BeanShell松散类型,可以不用定义变量类型。

元类型:省略掉变量类型

foo = "Foo";
num = (2 + 3) * 10 / 2;
System.out.println(foo + " = " + num);

运行结果:

对象类型:省略掉变量类型。

button = new JButton( "My Button" );
frame = new JFrame( "My Frame" );
frame.getContentPane().add( button, "Center" );
frame.pack();
frame.setVisible(true);

运行结果


4、set()和get()

set()方法传递对象的变量参数给BeanShell

将10赋值给num

interpreter.set("num", 10);

通过get()方法去取得BeanShell中的变量

interpreter.get("num");
Interpreter interpreter = new Interpreter();
interpreter.set("num", 5);
interpreter.get("num");

5、脚本方法

可以声明和使用方法就像在Java中一样。

在main函数里执行脚本,并调用demo.bsh里的函数

 public static void main(String[] args) throws EvalError, IOException {String bshPath = "C:\\Users\\Administrator\\Desktop\\slenium\\demo.bsh";Interpreter bsh = new Interpreter();//导入并执行脚本bsh.source(bshPath);//调用脚本的函数Object eval = bsh.eval("addTwoNumbers(2,8)");System.out.println(eval);//10}

扩展:获取脚本中定义了哪些方法

getMethods() 返回 bsh.BshMethod 对象的数组,这些对象是 BeanShell 脚本方法的内部解析表示形式的包装器:

int addTwoNumbers( int a, int b ) {return a + b;
}
//打印此命名空间中定义的方法
System.out.println(this.namespace.getMethods()); 

java 反射 API 使用特殊的类值来表示基本类型,例如 int、char、boolean。这些类型是各自原始包装类中的静态字段。例如 Integer.TYPE、Character.TYPE、Boolean.TYPE。

要调用脚本方法,请调用其 invoke() 方法,并传递参数数组、解释器引用和“callstack”引用。

int subTwoNumbers( int a, int b ) {System.out.println("调用方法subTwoNumbers");return a - b;
}
//查找定义的方法
name="subTwoNumbers";
signature = new Class [] { Integer.TYPE, Integer.TYPE };
bshMethod = this.namespace.getMethod( name, signature );
//调用方法
bshMethod.invoke( new Object [] { new Integer(10), new Integer(2) }, this.interpreter, this.callstack );

6、添加第三方jar

准备好我们的第三方jar,如:fastjson.jar

在demo.bsh脚本中使用fastjson.jar中的方法

添加第三方jar的方法如下:
interpreter.getClassManager().addClassPath(jarFile.getAbsoluteFile().toURI().toURL());

调用bsh脚本并执行

String bshPath = "C:\\Users\\Administrator\\Desktop\\slenium\\demo.bsh";
Interpreter bsh = new Interpreter();
//最关键的一步,添加第三方jar
File jarFile = new File("E:\\tmp\\fastjson-1.2.29.jar");
bsh.getClassManager().addClassPath(jarFile.getAbsoluteFile().toURI().toURL());
//接着就可以在脚本中引入并使用了
bsh.source(bshPath);

运行结果如下


JCEF

JCEF的官方网站(chromiumembedded / java-cef / wiki / Home — Bitbucket)

Java Chromium嵌入式框架(JCEF)。 一个简单的框架,用于使用Java编程语言在其他应用程序中嵌入基于Chromium的浏览器

进程模型

Browser被定义为主进程,负责窗口管理,界面绘制和网络交互Blink的渲染和Js的执行被放在一个独立的Render 进程中;除此之外,Render进程还负责Js Binding和对Dom节点的访问 默认的进程模型中,会为每个标签页创建一个新的Render进程

Browser和Render进程可以通过发送异步消息进行双向通信

一个从Browser进程发送到Render进程的消息将会在CefRenderProcessHandler::OnProcessMessageReceived()方法里被接收。一个从Render进程发送到Browser进程的消息将会在CefClient::OnProcessMessageReceived()方法里被接收。

JavaScript被集成在Render进程,但是需要频繁和Browser进程交互。 JavaScript API应该被设计成可使用闭包异步执行。


入门案例

初始化JCEF:在应用程序启动时,必须先初始化JCEF

import org.cef.CefApp;
import org.cef.CefClient;
import org.cef.CefSettings;
import org.cef.OS;
import org.cef.browser.CefBrowser;
import org.cef.handler.CefAppHandlerAdapter;import javax.swing.*;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;public class TestFrame extends JFrame {private static final long serialVersionUID = -7410082787754606408L;public static void main(String[] args) {new TestFrame();}public TestFrame() {//是否Linux系统boolean useOSR = OS.isLinux();//是否透明boolean isTransparent = false;//添加Handler,在CEFAPP状态为终止时退出程序CefApp.addAppHandler(new CefAppHandlerAdapter(null) {@Overridepublic void stateHasChanged(org.cef.CefApp.CefAppState state) {// Shutdown the app if the native CEF part is terminatedif (state == CefApp.CefAppState.TERMINATED) System.exit(0);}});//--------------------------初始化JCEF---------------------------CefSettings settings = new CefSettings();settings.windowless_rendering_enabled = useOSR;//获取CefApp实例CefApp cefApp = CefApp.getInstance(settings);//创建客户端实例CefClient cefClient = cefApp.createClient();//-----------------------------创建浏览器实例-------------------------------//创建一个新的浏览器实例,并打开指定的URLCefBrowser cefBrowser = cefClient.createBrowser("http://hao.fly63.com/", useOSR, isTransparent);//将浏览器UI添加到窗口中getContentPane().add(cefBrowser.getUIComponent(), BorderLayout.CENTER);pack();setTitle("JCEF打开极简导航");setSize(800, 600);setVisible(true);//添加一个窗口关闭监听事件addWindowListener(new WindowAdapter() {@Overridepublic void windowClosing(WindowEvent e) {CefApp.getInstance().dispose();dispose();}});}
}

CefSettings

CefSettings结构体允许定义全局的CEF配置,经常用到的配置项如下

single_process 设置为true时,Browser和Renderer使用一个进程。

locale 此设置项将传递给Blink。如果此项为空,将使用默认值“en-US”。

log_file 此项设置的文件夹和文件名将用于输出debug日志。如果此项为空,默认的日志文件名为debug.log,位于应用程序所在的目录

log_severity 此项设置日志级别。只有此等级、或者比此等级高的日志的才会被记录。此项可以通过命令行参数“log-severity”配置,可以设置的值为“verbose”,“info”,“warning”,“error”,“error-report”,“disable”。

emote_debugging_port 此项可以设置1024-65535之间的值,用于在指定端口开启远程调试。例如,如果设置的值为8080,远程调试的URL为http://localhost:8080。CEF或者Chrome浏览器能够调试CEF


执行JavaScript代码

一旦有了浏览器实例,就可以使用CefBrowser类提供的方法与网页进行交互。例如,你可以执行JavaScript代码、发送消息给网页等

执行JavaScript代码

cefBrowser.executeJavaScript("document.getElementById('myElement').innerHTML = 'Hello, JCEF!';", "",0);

----


发送消息给网页

发送消息给网页:

CefProcessMessage message = CefProcessMessage.create("myMessage");
message.getArgumentList().setString(0, "Hello, JCEF!"); cefBrowser.sendProcessMessage(CefProcessId.BROWSER, message);


处理网页发送的消息

render进程和browser进程之间是通两端的消息路由传递消息的,

创建了一个CefMessageRouterHandlerAdapter的子类,重写了onQuery方法来处理来自JavaScript的查询。

import org.cef.browser.CefBrowser;
import org.cef.browser.CefFrame;
import org.cef.callback.CefQueryCallback;
import org.cef.handler.CefMessageRouterHandlerAdapter;public class JCEFMessageRouterHandler extends CefMessageRouterHandlerAdapter {//重写了onQuery方法来处理来自JavaScript的查询@Overridepublic boolean onQuery(CefBrowser browser, CefFrame frame, long query_id, String request, boolean persistent,CefQueryCallback callback) {if (request.equals("getJavaData")) {String javaData = "This data is from Java";callback.success(javaData);return true;}return false;}
}

JCEF使得在Java应用程序中嵌入Chromium引擎成为可能,并且通过使用CefMessageRouter,您可以在Java和JavaScript之间实现双向的交互。

将这个JCEFMessageRouterHandler注册到CefMessageRouter中。这样,您就可以在JavaScript中使用cefQuery来与Java进行交互了

//配置一个查询路由,html页面可使用 window.java({}) 和 window.javaCancel({}) 来调用此方法
CefMessageRouter.CefMessageRouterConfig cmrc = new CefMessageRouter.CefMessageRouterConfig("java", "javaCancel");
//创建查询路由
CefMessageRouter router = CefMessageRouter.create(cmrc);
router.addHandler(new JCEFMessageRouterHandler(), true);
cefClient.addMessageRouter(router);

当JavaScript代码中调用cefQuery并传递"getJavaData"时,Java代码会返回一段数据。

// 在JavaScript中调用Java方法并获取返回值
cefQuery({request: "getJavaData",onSuccess: function (response) {console.log("Data from Java: " + response);},onFailure: function (errorCode, errorMessage) {console.error("Java query failed: " + errorCode + " - " + errorMessage);},
});

举例: 用js去打开文件选择对话框

    //打开文件选择器public static void openFileChooser(CefBrowser browser, final CefQueryCallback callback) {CefRunFileDialogCallback dialogCallBack = new CefRunFileDialogCallback() {@Overridepublic void onFileDialogDismissed(int selectedAcceptFilter, Vector<String> filePaths) {if (filePaths.size() == 0) {return;}File selectedFile = new File(filePaths.get(0));if (selectedFile != null) {String selectedPath = selectedFile.getAbsolutePath();System.out.println(selectedPath);callback.success(selectedPath);}}};browser.runFileDialog(CefDialogHandler.FileDialogMode.FILE_DIALOG_OPEN, "文件选择器", null, null, 0, dialogCallBack);}

弹出窗口处理

CefLifeSpanHandlerAdapter:弹出窗口创建一个处理的Handler

当我们点击target值为_blank的链接时,JCEF默认以弹出窗口的形式打开新页面。创建一个实现CefLifeSpanHandlerAdapter的类,重写onBeforePopup方法:根据url创建一个CefBrowser对象。

Browser生命周期(Browser Life Span)

public class LifeSpanHandler extends CefLifeSpanHandlerAdapter {private TabbedPaneTestFrame frame;public LifeSpanHandler(TabbedPaneTestFrame frame) {this.frame=frame;}/* (non-Javadoc)* @see org.cef.handler.CefLifeSpanHandlerAdapter#onBeforePopup(org.cef.browser.CefBrowser, org.cef.browser.CefFrame, java.lang.String, java.lang.String)*/@Overridepublic boolean onBeforePopup(CefBrowser browser, CefFrame frame, String target_url, String target_frame_name) {this.frame.createBrowser(target_url);//返回true表示取消弹出窗口return true;}
}

设置onBeforePopup方法的返回值为true,取消弹出窗口


Java SPI 机制

SPI(Service Provider Interface),是JDK内置的一种服务提供发现机制,可以用来启用框架扩展和替换组件。Java的SPI机制可以为某个接口寻找服务实现

WebService就是一个应用程序向外界暴露出一个能通过Web进行调用的API

WebService采用HTTP协议传输数据,采用XML格式封装数据

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/220667.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何在 VeriStand 中设置反射内存通道

环境 硬件 cPCI-5565PIORC 软件 VeriStand 我正在设置我的反射内存 PXI 卡&#xff08;例如 cPCI-5565PIORC&#xff09;。 我可以在我的 PXI 系统之间使用反射内存发送/接收什么&#xff1f; 如何设置我的 PXI 系统之间共享的通道&#xff1f; 使用反射内存&#xff0c;您…

水闸水雨情监测设施建设项目

功能设计 在水闸上、下游挡墙外侧各安装1套雷达水位计&#xff0c;水闸屋顶布置个雨量计&#xff0c;水位及雨量监测数据的采集与传输主要是实时的完成水位、雨量数据的采集与处理&#xff0c;并按照设定的工作方式、时间间隔、增量范围将数据上传至扬压力监测站边缘计算终端&…

数字电子技术期末知识点总结

文章目录 时序逻辑电路时序电路的分析同步时序电路的分析例子1&#xff08;有输入输出&#xff09;例子2 &#xff08;只有输出&#xff09;例子3&#xff08;没有输入、输出&#xff09; 异步时序电路的分析例子1 小结 时序电路的设计同步时序电路的设计串行数据检测器JK 触发…

【前端】HTML5 CSS3新特性(学习笔记)

HTML5 一、H5新增的语义化标签 以前布局&#xff0c;我们基本用 div 来做。div 对于搜索引擎来说&#xff0c;是没有语义的。 <header>&#xff1a;头部标签<nav>&#xff1a;导航标签<article>&#xff1a;内容标签<section>&#xff1a;定义文档某…

jdk21升级,asm报错Unsupported class file major version 65

环境 jdk21升级&#xff0c;asm报错&#xff0c;spring-core版本5.3.18&#xff0c;项目springboot版本为2.6.6 报错明细 Caused by: org.springframework.core.NestedIOException: ASM ClassReader failed to parse class file - probably due to a new Java class file ve…

QQ音乐评论爬虫程序【原创】

先找到一首歌&#xff0c;把请求参数替换到下面程序中 例如&#xff1a; ‘g_tk_new_20200303’: ‘5381’, ‘g_tk’:‘5381’, ‘topid’:‘102636799’, //歌曲ID ‘cv’:‘4747474’ … #此处修改请求的页数 if page >10: break import requests from urllib import p…

修改Element UI可清空Input的样式

如图所示&#xff0c;修改Input右侧的清空按钮位置&#xff1a; <el-input class"create-catalog-ipt"placeholder"请输入相关章节标题"v-model"currentCatalogTitle"clearable /> // SCSS环境 ::v-deep {.create-catalog-ipt {input {he…

利用svm进行模型训练

一、步骤 1、将文本数据转换为特征向量 &#xff1a; tf-idf 2、使用这些特征向量训练SVM模型 二、代码 from sklearn.model_selection import train_test_split from sklearn.feature_extraction.text import TfidfVectorizer from sklearn.svm import SVC from sklearn.m…

HTTP、HTTPS、SSL协议以及相关报文讲解

目录 HTTP/HTTPS介绍 HTTP/HTTPS基本信息 HTTP如何实现有状态 HTTP请求与应答报文 HTTP请求报文 HTTP响应报文 SSL协议 SSL单向认证 SSL双向认证 HTTP连接建立与传输步骤 HTTP访问全过程相关报文&#xff08;以访问www.download.cucdccom为例子&#xff09; DNS报文…

06_W5500_DHCP

1.DHCP协议介绍&#xff1a; DHCP&#xff08;Dynamic Host Configuration Protocol&#xff09;是一种用于自动分配IP地址和其他网络配置信息的协议。它允许网络中的设备&#xff08;如计算机、手机、打印机等&#xff09;在连接到网络时自动获取IP地址、子网掩码、默认网关、…

JavaEE:单例模式(饿汉模式和懒汉模式)精讲

前言 什么是单例模式&#xff1f; 其实用通俗的话就是程序猿约定俗成的一些东西&#xff0c;就比如如果你继承了一个抽象类&#xff0c;你就要重写里面的抽象方法&#xff0c;如果你实现了一个接口&#xff0c;你就要重写里面的方法。如果不进行重写&#xff0c;那么编译器就会…

2024上海智慧城市展会(世亚智博会)促进长三角地区智慧城市发展

上海市政府近期印发的《上海市进一步推进新型基础设施建设行动方案(2023-2026年)》标志着新一轮新基建的全面启动。市政府副秘书长、市发展改革委主任顾军指出&#xff0c;这一行动方案紧抓智能算力、大模型、数据要素、区块链、机器人等技术发展趋势和绿色低碳节能要求&#x…

【LeetCode:2132. 用邮票贴满网格图 | 二维前缀和 + 二维差分和】

&#x1f680; 算法题 &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;…

达索系统SOLIDWORKS 2024 Visualize新功能

SOLIDWORKS Visualize&#xff08;原名为 Bunkspeed&#xff09;是一整套独立的软件工具&#xff0c;Visualize模块主要是用于对SOLIDWORKS设计出的产品图进行渲染、做动画&#xff0c;方便用户更好的展示、宣传产品&#xff1b;以最快速、最轻松的方式创建专业的照片级图像、动…

基于YOLOv8深度学习的水稻害虫检测与识别系统【python源码+Pyqt5界面+数据集+训练代码】目标检测、深度学习实战

《博主简介》 小伙伴们好&#xff0c;我是阿旭。专注于人工智能、AIGC、python、计算机视觉相关分享研究。 ✌更多学习资源&#xff0c;可关注公-仲-hao:【阿旭算法与机器学习】&#xff0c;共同学习交流~ &#x1f44d;感谢小伙伴们点赞、关注&#xff01; 《------往期经典推…

《使用ThinkPHP6开发项目》 - 登录接口三【表单验证】

《使用ThinkPHP6开发项目》 - 登录接口一-CSDN博客 https://blog.csdn.net/centaury32/article/details/134974860 在设置用户登录时&#xff0c;由于安全问题会对登录密码进行加密 表单验证这里也可以使用ThinkPHP6自带的验证规则&#xff0c;创建一个验证管理员的文件 ph…

MYSQL各种日志

感谢B站up主的视频分享 黑马程序员 MySQL数据库入门到精通&#xff0c;从mysql安装到mysql高级、mysql优化全囊括_哔哩哔哩_bilibili

2023 亚马逊云科技 re:Invent 大会探秘:Aurora 无限数据库的突破性应用

文章目录 一、前言二、Amazon Aurora 无限数据库2.1 亚马逊云科技数据库产品发展历程2.2 什么是 Amazon Aurora Limitless Database&#xff08;无限数据库&#xff09;2.3 Amazon Aurora Limitless Database 设计架构2.4 Amazon Aurora Limitless Database 分片功能2.5 使用 A…

xtu oj 1194 Recipient

题目描述 快递小哥每天都辛苦的送快递&#xff0c;今天他需要送N份快递给N个收件人&#xff0c;第i份快递需要送给第i个收件人。 请问其中发生恰好K个送错了的情况数是多少&#xff1f; 输入 存在多样例。 每行输入两个整数N和K&#xff0c;1≤N≤1000,0≤K≤N。 如果两个都…

pytorch中的归一化:BatchNorm、LayerNorm 和 GroupNorm

1 归一化概述 训练深度神经网络是一项具有挑战性的任务。 多年来&#xff0c;研究人员提出了不同的方法来加速和稳定学习过程。 归一化是一种被证明在这方面非常有效的技术。 1.1 为什么要归一化 数据的归一化操作是数据处理的一项基础性工作&#xff0c;在一些实际问题中&am…