调用 JavaScript-Method 时需要哪个 Java-Datatype
Which Java-Datatype is required when calling JavaScript-Method
我正在尝试通过以下方式从我的 JavaFX-WebView 中调用 JavaScript-Method:
JSObject win = (JSObject)getEngine().executeScript("window");
win.call("showPDF", myPDFFile /*typeof java.io.File*/);
这次调用的结果是:
Invalid parameter object: need either .data, .range or .url
这是 JavaScript-Part(不是我写的),它抛出错误:
var source;
if (typeof src === 'string') {
source = { url: src };
} else if (isArrayBuffer(src)) {
source = { data: src };
} else if (src instanceof PDFDataRangeTransport) {
source = { range: src };
} else {
if (typeof src !== 'object') {
error('Invalid parameter in getDocument, need either Uint8Array, ' +
'string or a parameter object');
}
if (!src.url && !src.data && !src.range) {
error('Invalid parameter object: need either .data, .range or .url');
}
}
实施isArrayBuffer
:
function isArrayBuffer(v) {
return typeof v === 'object' && v !== null && v.byteLength !== undefined;
}
所以我的问题是:
可以使用哪种类型的 (java) 对象才能使此调用有效?
win.call("showPDF", ???);
编辑 1:
String 不能使用,因为它将被视为 URL.
我想提交类似 ByteArray(我的具体文件)的内容,但使用 byte[]
(而不是 java.io.File
)会导致相同的错误。
以下是上面 JS 函数的一些注释:
https://github.com/mozilla/pdf.js/blob/master/src/display/api.js#L234
This is the main entry point for loading a PDF and interacting with it.
NOTE: If a URL is used to fetch the PDF data a standard XMLHttpRequest(XHR)
is used, which means it must follow the same origin rules that any XHR does
e.g. No cross domain requests without CORS.
@param {string|TypedArray|DocumentInitParameters|PDFDataRangeTransport} src
Can be a url to where a PDF is located, a typed array (Uint8Array)
already populated with data or parameter object.
我必须使用什么数据类型(在 JAVA 中),所以它将是(例如)TypedArray (Uint8Array) 在 JAVA脚本?
编辑 2:
我正在尝试 Aarons 的建议:
String encoded = Base64.getEncoder().encodeToString(Files.readAllBytes(myPDFFile.toPath()));
engine.executeScript("var src = _base64ToArrayBuffer('"+encoded+"'); showPDF(src);");
这导致了一个新问题:
Error: Invalid PDF binary data: either typed array, string or array-like object is expected in the data property.
此(新)错误在此处抛出(几行之后):https://github.com/mozilla/pdf.js/blob/master/src/display/api.js#L291
console.log(_base64ToArrayBuffer(encoded))
returns: [object ArrayBuffer]
解法:
我设法完成了这项工作(在 Aaron 的帮助下):
pdfViewer.html
<!doctype html>
<html>
<head>
<script src="web/compatibility.js"></script>
<script src="build/pdf.js"></script>
<script>
function _base64ToBinaryString(base64) {
var binary_string = window.atob(base64);
return binary_string;
}
function showPDF(pdfFile) {
console.log('calling showPDF...');
'use strict';
PDFJS.disableWorker = true; /* IMPORTANT TO DISABLE! */
PDFJS.workerSrc = 'build/pdf.worker.js';
console.log('TRYING TO GET DOCUMENT FROM BINARY DATA...');
PDFJS.getDocument({data: pdfFile}).then(function(pdf)
{
console.log('PDF LOADED.');
console.log('TRYING TO GET PAGE 1...');
pdf.getPage(1).then(function(page) {
console.log('PAGE 1 LOADED.');
var scale = 1.0;
var viewport = page.getViewport(scale);
var canvas = document.getElementById('the-canvas');
var context = canvas.getContext('2d');
canvas.height = viewport.height;
canvas.width = viewport.width;
var renderContext = {
canvasContext: context,
viewport: viewport
};
console.log('RENDERING PAGE 1...');
page.render(renderContext);
});
});
};
</script>
</head>
<body>
<canvas id="the-canvas" style="border:1px solid black;"/>
</body>
</html>
将上面的HTML-Page加载到WebView后,
以下 Java-代码用于将 PDF 文件加载到页面中:
String encoded = Base64.getEncoder().encodeToString(Files.readAllBytes(myPdfFile.toPath()));
webEngine.executeScript("var src = _base64ToBinaryString('"+encoded+"'); showPDF(src);");
尝试 myPDFFile.getURI().getURL().toString()
,因为该方法接受字符串形式的 URL。由于 WebKit 在本地 运行,您应该能够阅读 file://
URLs.
如果您想尝试 ArrayBuffer
,那么您可以在 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer
的 MDN Java脚本文档中找到一些示例
这意味着你需要创建一个FileReader
,传递URL,处理异步事件。我只在您非常了解 JavaScript 的情况下才推荐这个。
不幸的是,这些示例都适用于处理网页中的文件,而不是将数据传递到页面中。
[编辑] 下面是一个如何将 Base64 编码字符串转换为 ArrayBuffer
的示例:Convert base64 string to ArrayBuffer
因此您需要将文件加载到 Java byte[]
数组中。然后将数组转换为 Base64 编码的 Java 字符串。然后您可以将其粘贴到动态 JavaScript:
String encoded = ...byte[] -> Base64...
getEngine().executeScript("var src = _base64ToArrayBuffer('"+encoded+"'); showPDF(src);");
我正在尝试通过以下方式从我的 JavaFX-WebView 中调用 JavaScript-Method:
JSObject win = (JSObject)getEngine().executeScript("window");
win.call("showPDF", myPDFFile /*typeof java.io.File*/);
这次调用的结果是:
Invalid parameter object: need either .data, .range or .url
这是 JavaScript-Part(不是我写的),它抛出错误:
var source;
if (typeof src === 'string') {
source = { url: src };
} else if (isArrayBuffer(src)) {
source = { data: src };
} else if (src instanceof PDFDataRangeTransport) {
source = { range: src };
} else {
if (typeof src !== 'object') {
error('Invalid parameter in getDocument, need either Uint8Array, ' +
'string or a parameter object');
}
if (!src.url && !src.data && !src.range) {
error('Invalid parameter object: need either .data, .range or .url');
}
}
实施isArrayBuffer
:
function isArrayBuffer(v) {
return typeof v === 'object' && v !== null && v.byteLength !== undefined;
}
所以我的问题是:
可以使用哪种类型的 (java) 对象才能使此调用有效?
win.call("showPDF", ???);
编辑 1:
String 不能使用,因为它将被视为 URL.
我想提交类似 ByteArray(我的具体文件)的内容,但使用 byte[]
(而不是 java.io.File
)会导致相同的错误。
以下是上面 JS 函数的一些注释:
https://github.com/mozilla/pdf.js/blob/master/src/display/api.js#L234
This is the main entry point for loading a PDF and interacting with it.
NOTE: If a URL is used to fetch the PDF data a standard XMLHttpRequest(XHR)
is used, which means it must follow the same origin rules that any XHR does
e.g. No cross domain requests without CORS.
@param {string|TypedArray|DocumentInitParameters|PDFDataRangeTransport} src
Can be a url to where a PDF is located, a typed array (Uint8Array)
already populated with data or parameter object.
我必须使用什么数据类型(在 JAVA 中),所以它将是(例如)TypedArray (Uint8Array) 在 JAVA脚本?
编辑 2:
我正在尝试 Aarons 的建议:
String encoded = Base64.getEncoder().encodeToString(Files.readAllBytes(myPDFFile.toPath()));
engine.executeScript("var src = _base64ToArrayBuffer('"+encoded+"'); showPDF(src);");
这导致了一个新问题:
Error: Invalid PDF binary data: either typed array, string or array-like object is expected in the data property.
此(新)错误在此处抛出(几行之后):https://github.com/mozilla/pdf.js/blob/master/src/display/api.js#L291
console.log(_base64ToArrayBuffer(encoded))
returns: [object ArrayBuffer]
解法:
我设法完成了这项工作(在 Aaron 的帮助下):
pdfViewer.html
<!doctype html>
<html>
<head>
<script src="web/compatibility.js"></script>
<script src="build/pdf.js"></script>
<script>
function _base64ToBinaryString(base64) {
var binary_string = window.atob(base64);
return binary_string;
}
function showPDF(pdfFile) {
console.log('calling showPDF...');
'use strict';
PDFJS.disableWorker = true; /* IMPORTANT TO DISABLE! */
PDFJS.workerSrc = 'build/pdf.worker.js';
console.log('TRYING TO GET DOCUMENT FROM BINARY DATA...');
PDFJS.getDocument({data: pdfFile}).then(function(pdf)
{
console.log('PDF LOADED.');
console.log('TRYING TO GET PAGE 1...');
pdf.getPage(1).then(function(page) {
console.log('PAGE 1 LOADED.');
var scale = 1.0;
var viewport = page.getViewport(scale);
var canvas = document.getElementById('the-canvas');
var context = canvas.getContext('2d');
canvas.height = viewport.height;
canvas.width = viewport.width;
var renderContext = {
canvasContext: context,
viewport: viewport
};
console.log('RENDERING PAGE 1...');
page.render(renderContext);
});
});
};
</script>
</head>
<body>
<canvas id="the-canvas" style="border:1px solid black;"/>
</body>
</html>
将上面的HTML-Page加载到WebView后, 以下 Java-代码用于将 PDF 文件加载到页面中:
String encoded = Base64.getEncoder().encodeToString(Files.readAllBytes(myPdfFile.toPath()));
webEngine.executeScript("var src = _base64ToBinaryString('"+encoded+"'); showPDF(src);");
尝试 myPDFFile.getURI().getURL().toString()
,因为该方法接受字符串形式的 URL。由于 WebKit 在本地 运行,您应该能够阅读 file://
URLs.
如果您想尝试 ArrayBuffer
,那么您可以在 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer
这意味着你需要创建一个FileReader
,传递URL,处理异步事件。我只在您非常了解 JavaScript 的情况下才推荐这个。
不幸的是,这些示例都适用于处理网页中的文件,而不是将数据传递到页面中。
[编辑] 下面是一个如何将 Base64 编码字符串转换为 ArrayBuffer
的示例:Convert base64 string to ArrayBuffer
因此您需要将文件加载到 Java byte[]
数组中。然后将数组转换为 Base64 编码的 Java 字符串。然后您可以将其粘贴到动态 JavaScript:
String encoded = ...byte[] -> Base64...
getEngine().executeScript("var src = _base64ToArrayBuffer('"+encoded+"'); showPDF(src);");