2023-02-17 396
我正在JAVAFX中开发一个数据挖掘应用程序,该应用程序依赖于WebView(也是WebEngine).采矿以2个步骤进行:首先,用户使用UI导航到WebView中的网站以配置可以在其中搜索有趣的数据.其次,使用定期运行的背景任务,WebEngine加载相同的文档并尝试从已加载文档中提取数据.
这在大多数情况下都非常有效,但是最近我在使用Ajax呈现内容的页面上遇到了一些麻烦.要检查WebEngine是否已加载文档,我会收听loadWorker’S stateProperty.如果状态过渡到成功,我知道该文档已加载(以及可能在document..ready()或等价上运行的任何JavaScript).这是因为JavaScript如果我没记错的话在javafx线程上执行( .oracle.com/javafx/entry/communcommating_between_javascript_and_javafx ).但是,如果启动了AJAX调用,则JavaScript执行完成,引擎让我知道文档已经准备就绪,尽管显然不是因为目录由于出色的Ajax调用而可能仍会更改.
.
是否有任何方法可以注入钩子,所以当Ajax调用完成后,我会收到通知吗?我尝试在$.ajaxSetup()中安装默认完整处理程序,但这很狡猾,因为如果Ajax调用覆盖完整的处理程序,则不会调用默认值.另外,我只能在文档首先加载文档后才注入(到那时某些AJAX调用可能已经在运行).我已经用上呼叫测试了此注射,它适用于在命令上发射的Ajax调用(在注射默认处理程序之后)不提供自己的完整处理程序.
我正在寻找两件事:首先:一种通用的方法,可以将Ajax呼叫的完整处理程序连接起来,其次:等待WebEngine完成所有Ajax呼叫并之后通知我的方法.
.
我也遇到了这个问题,并通过提供自己的sun.net.www.protocol.http.HttpURLConnection实现来解决它,我用来处理任何AJAX请求.我的类方便地称为AjaxHttpURLConnection,将其挂在getInputStream()函数中,但不会返回其原始输入流.相反,我将PipedInputStream的实例返回到WebEngine.然后,我读取来自原始输入流的所有数据,然后将其传递到我的管道流.
这样,我获得了2个好处:
首先,您必须告诉Java使用您的URLConnection实现而不是默认一个.为此,您必须为其提供自己的URLStreamHandlerFactory版本.您可以在这里找到许多线程(例如 this )或通过Google通过Google.话题.为了设置您的工厂实例,请在main方法的早期将以下内容放置.这就是我的样子.
import java.net.URLStreamHandler;
import java.net.URLStreamHandlerFactory;
public class MyApplication extends Application {
// ...
public static void main(String[] args) {
URL.setURLStreamHandlerFactory(new URLStreamHandlerFactory() {
public URLStreamHandler createURLStreamHandler(String protocol) {
if ("http".equals(protocol)) {
return new MyUrlConnectionHandler();
}
return null; // Let the default handlers deal with whatever comes here (e.g. https, jar, ...)
}
});
launch(args);
}
}
第二,我们必须提出自己的Handler,该>告诉程序何时使用URLConnection.
import java.io.IOException;
import java.net.Proxy;
import java.net.URL;
import java.net.URLConnection;
import sun.net.www.protocol.http.Handler;
import sun.net.www.protocol.http.HttpURLConnection;
public class MyUrlConnectionHandler extends Handler {
@Override
protected URLConnection openConnection(URL url, Proxy proxy) throws IOException {
if (url.toString().contains("ajax=1")) {
return new AjaxHttpURLConnection(url, proxy, this);
}
// Return a default HttpURLConnection instance.
return new HttpURLConnection(url, proxy);
}
}
最后但并非最不重要的一点,这是AjaxHttpURLConnection.
import java.io.IOException;
import java.io.InputStream;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
import java.net.Proxy;
import java.net.URL;
import java.util.concurrent.locks.ReentrantLock;
import org.apache.commons.io.IOUtils;
import sun.net.www.protocol.http.Handler;
import sun.net.www.protocol.http.HttpURLConnection;
public class AjaxHttpURLConnection extends HttpURLConnection {
private PipedInputStream pipedIn;
private ReentrantLock lock;
protected AjaxHttpURLConnection(URL url, Proxy proxy, Handler handler) {
super(url, proxy, handler);
this.pipedIn = null;
this.lock = new ReentrantLock(true);
}
@Override
public InputStream getInputStream() throws IOException {
lock.lock();
try {
// Do we have to set up our own input stream?
if (pipedIn == null) {
PipedOutputStream pipedOut = new PipedOutputStream();
pipedIn = new PipedInputStream(pipedOut);
InputStream in = super.getInputStream();
/*
* Careful here! for some reason, the getInputStream method seems
* to be calling itself (no idea why). Therefore, if we haven't set
* pipedIn before calling super.getInputStream(), we will run into
* a loop or into EOFExceptions!
*/
// TODO: timeout?
new Thread(new Runnable() {
public void run() {
try {
// Pass the original data on to the browser.
byte[] data = IOUtils.toByteArray(in);
pipedOut.write(data);
pipedOut.flush();
pipedOut.close();
// Do something with the data? Decompress it if it was
// gzipped, for example.
// Signal that the browser has finished.
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}
} finally {
lock.unlock();
}
return pipedIn;
}
}
这是 @dadoosh答案的延伸…
为https做这件事是委派的噩梦,因为HttpsURLConnection(Impl)不能像HttpURLConnection
那样实例化
import sun.net.www.protocol.https.Handler;
public class MyStreamHandler extends Handler {
@Override
protected URLConnection openConnection(URL url) throws IOException {
URLConnection connection = super.openConnection(url);
if (url.toString().contains("ajax=1")) {
return new MyConnection((HttpsURLConnection) connection);
} else {
return connection;
}
}
}
所以我得到了本来可以返回的连接,并在必要时将其交给MyConnection,以便它可以委派所有呼叫并修改getInputStream()方法.
顺便说一句,我找到了另一个用于检测AJAX请求末尾的解决方案.我只是等待close()被调用:
@Override
public synchronized InputStream getInputStream() throws IOException {
if (cachedInputStream != null) {
return cachedInputStream;
}
System.out.println("Open " + getURL());
InputStream inputStream = delegate.getInputStream();
cachedInputStream = new FilterInputStream(inputStream) {
@Override
public void close() throws IOException {
super.close();
// Signal that the browser has finished.
}
};
return cachedInputStream;
}
以上所述是小编给大家介绍的JavaFX WebEngine等待ajax完成,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对77isp云服务器技术网的支持!
原文链接:https://77isp.com/post/34141.html
=========================================
https://77isp.com/ 为 “云服务器技术网” 唯一官方服务平台,请勿相信其他任何渠道。
数据库技术 2022-03-28
网站技术 2022-11-26
网站技术 2023-01-07
网站技术 2022-11-17
Windows相关 2022-02-23
网站技术 2023-01-14
Windows相关 2022-02-16
Windows相关 2022-02-16
Linux相关 2022-02-27
数据库技术 2022-02-20
抠敌 2023年10月23日
嚼餐 2023年10月23日
男忌 2023年10月22日
瓮仆 2023年10月22日
簿偌 2023年10月22日
扫码二维码
获取最新动态