如何将数据从vaadin webapp传递到C#GUI app

时间:2018-09-21 14:22:13

标签: java c# web vaadin

我在Vaadin Framework 8中具有webapp。我在C#中具有Windows GUI应用程序。 gui应用程序正在使用WebBrowser组件来显示webapp。 WebBrowser组件在内部通过ActiveX使用IE11内核。我可以在gui应用浏览器组件中成功加载并显示webapp。

我需要将数据从webapp传递到gui应用。 Webapp在服务器端加载了许多行,而网格中仅显示了很少的几行。我想以某种格式(csv或json)将所有数据从webapp传递到gui应用。

我尝试了一些方法,但是没有成功。

[方法1]

Webapp:使用Link将具有预定义ID的可下载资源(csv)附加到FileDownloader。通过用户单击鼠标下载可以正常工作,弹出文件保存对话框,并且数据下载成功。

Link link = new Link("Data");
link.setId("myId");
StreamResource resource = getMyResource(data);
FileDownloader downloader = new FileDownloader(resource);
downloader.extend(link);

Page.getCurrent().getJavaScript().addFunction("test", new JavaScriptFunction() {
     @Override
     public void call(JsonArray arguments) {
         Page.getCurrent().getJavaScript()
             .execute("document.getElementById('myId').click()");
    }
});

Gui应用程序:在链接上引发onClick事件并捕获WebBrowser.FileDownload事件,捕获WebBrowser.Navigate事件。 我无法使用以下方法从C#引发onClick事件:

HtmlElement el = webBrowser.Document.GetElementById("myId");
el.RaiseEvent("onClick");
el.InvokeMember("click");
webBrowser.Document.InvokeScript("document.getElementById('myId').click();", null);
webBrowser.Document.InvokeScript("test", null);

结果: WebBrowser.FileDownload事件不起作用(被触发但无法捕获url或数据),捕获WebBrowser.Navigate事件则部分起作用(可以查看资源url,但不能使用byte[] b = new WebClient().DownloadData(e.Url);下载数据)。

[方法2]

类似于方法1.我尝试获取资源url,将直接url放置到Link,然后使用直接链接在c#中下载资源。我可以构造与用户单击链接时浏览器用来下载数据的资源相同的网址。

保留资源,密钥和连接器的扩展文件下载器:

public class ExtendedFileDownloader extends FileDownloader {
    private String myKey;
    private Resource myResource;
    private ClientConnector myConnector;

    public ExtendedFileDownloader(StreamResource resource, ClientConnector connector) {
        super(resource);
        myConnector = connector;
    }

    @Override
    protected void setResource(String key, Resource resource) {
        super.setResource(key, resource);
        myKey = key;
        myResource = resource;
    }

    public String getResourceUrl() {
        ResourceReference ref =
            ResourceReference.create(
                myResource,
                (myConnector != null) ? myConnector : this,
                myKey);
        String url = ref.getURL();
        return url;
    }
}

视图中:

// fix app://path... urls to /<base-path>/path urls
private String fixResourceReferenceUrl(String resourceReferenceUrl) {
    String resourceReferencePath = resourceReferenceUrl.replace("app://", "");
    String uiBaseUrl = ui.getUiRootPath();
    String fixedUrl = uiBaseUrl + "/" + resourceReferencePath;
    return fixedUrl;
}

Link link2 = new Link("Data2");
link2.setId("myId2");
StreamResource resource = getMyResource(data);
ExtendedFileDownloader downloader = new ExtendedFileDownloader(resource, this);
String fixedResourceUrl = fixResourceReferenceUrl(downloader.getResourceUrl());
link2.setResource(new ExternalResource(fixedResourceUrl));    

结果: 无法使用此链接,服务器错误410或NotFound错误下载数据。

有什么想法吗?还有其他尝试的方法吗?

1 个答案:

答案 0 :(得分:0)

我终于解决了问题。解决方案非常接近方法2。 资源url在具有自定义属性的元素中传递。 C#) VALUES ("abc123");需要从WebClientWebBrowser HTTP标头设置cookie。数据可以通过C#应用成功下载。

vaadin webapp中的元素属性可以使用Vaadin-addon Attributes进行设置。

可以使用此solution来检索C#应用程序中的Cookie。

Referer

在视图中(使用上方的// Fix resource urls begining with app:// public String fixResourceReferenceUrl(String resourceReferenceUrl) { try { String uiRootPath = UI.getCurrent().getUiRootPath(); URI location = Page.getCurrent().getLocation(); String appLocation = new URIBuilder() .setScheme(location.getScheme()) .setHost(location.getHost()) .setPort(location.getPort()) .setPath(uiRootPath) .build() .toString(); String resourceReferencePath = resourceReferenceUrl.replace("app://", ""); String fixedUrl = appLocation + "/" + resourceReferencePath; return fixedUrl; } catch (Exception e) { return null; } }

ExtendedFileDownloader

在C#应用中:

Link link = new Link("Data");
link.setId("myId");
StreamResource resource = getMyResource(data);
ExtendedFileDownloader downloader = new ExtendedFileDownloader(resource);
downloader.extend(link);
Attribute attr = new Attribute("x-my-data", fixResourceReferenceUrl(downloader.getResourceUrl()));
attr.extend(link);
link.setVisible(true);