调用 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);");