调用JavaScript-Method时需要哪种Java-Datatype

时间:2015-05-19 07:31:50

标签: java javascript webview javafx-8

我试图通过以下方式从我的JavaFX-WebView中调用JavaScript方法:

JSObject win = (JSObject)getEngine().executeScript("window");
win.call("showPDF", myPDFFile /*typeof java.io.File*/);

此调用的结果是:

  

无效的参数对象:需要.data,.range或.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:
无法使用字符串,因为它将被视为URL 我想提交类似 ByteArray (我的具体文件),但使用byte[](而不是java.io.File)会导致相同的错误。

以下是JS函数的一些注释: https://github.com/mozilla/pdf.js/blob/master/src/display/api.js#L234

  

这是加载PDF并与之交互的主要入口点   注意:如果使用URL来获取PDF数据标准XMLHttpRequest(XHR)
  使用,这意味着它必须遵循任何XHR所具有的相同原始规则   例如没有CORS的跨域请求   
  @param {string | TypedArray | DocumentInitParameters | PDFDataRangeTransport} src
  可以是PDF所在的URL,类型数组(Uint8Array)
  已经填充了数据或参数对象。

我必须使用什么数据类型(在JAVA中),因此它将是JAVASCRIPT中的(例如) TypedArray(Uint8Array)

编辑2:
我在尝试Aarons的建议:

String encoded = Base64.getEncoder().encodeToString(Files.readAllBytes(myPDFFile.toPath()));
engine.executeScript("var src = _base64ToArrayBuffer('"+encoded+"'); showPDF(src);");

这会导致一个新问题:

  

错误:无效的PDF二进制数据:数据属性中应该是类型化数组,字符串或类数组对象。

此处抛出此(新)错误(稍后几行):https://github.com/mozilla/pdf.js/blob/master/src/display/api.js#L291

console.log(_base64ToArrayBuffer(encoded))返回:[object ArrayBuffer]

解决方案:
我设法做了这项工作(在亚伦的帮助下):

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页面加载到WebView后, 以下Java代码用于将PDF文件加载到页面:

String encoded = Base64.getEncoder().encodeToString(Files.readAllBytes(myPdfFile.toPath()));
webEngine.executeScript("var src = _base64ToBinaryString('"+encoded+"'); showPDF(src);");

1 个答案:

答案 0 :(得分:0)

尝试myPDFFile.getURI().getURL().toString(),因为该方法接受字符串形式的网址。由于WebKit在本地运行,您应该能够阅读file:// URL。

如果您想尝试ArrayBuffer,那么您可以在https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer

的MDN JavaScript文档中找到一些示例

这意味着您需要创建FileReader,传递URL,处理异步事件。如果你对JavaScript了解得很好,我只推荐这个。

不幸的是,这些示例都是为了处理网页中的文件,而不是将数据传递到页面中。

[编辑] 以下是如何将Base64编码的字符串转换为ArrayBuffer的示例:Convert base64 string to ArrayBuffer

因此,您需要将文件加载到Java byte[]数组中。然后将数组转换为Base64编码的Java String。然后,您可以将其粘贴到动态JavaScript中:

String encoded = ...byte[] -> Base64...
getEngine().executeScript("var src = _base64ToArrayBuffer('"+encoded+"'); showPDF(src);");