vendredi 21 septembre 2018

How to pass data from vaadin webapp to C# GUI app

I have webapp in Vaadin Framework 8. I have Windows GUI app in C#. The gui app is using WebBrowser component to display webapp. WebBrowser component is internally using IE11 core through ActiveX. I can successfully load and display the webapp in the gui app browser component.

I need to pass data from webapp to the gui app. The webapp has many rows loaded on server side, only few are displayed in grid. I want to pass all data from webapp to gui app in some format (csv or json).

I have tryed some approaches, but I wasn't successfull.

[Approach 1]

Webapp: attach downloadable resource (csv) to Link with predefined id using FileDownloader. Download by user mouse click works fine, file save dialog pops up and data are downloaded successfully.

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 app: raise onClick event on link and capture WebBrowser.FileDownload event, capture WebBrowser.Navigate event. I have failed to raise onClick event from C# using:

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);

Result: WebBrowser.FileDownload event doesn't work (is fired but can't capture url nor data), capture WebBrowser.Navigate event works partialy (can see resource url, but can't download data using byte[] b = new WebClient().DownloadData(e.Url);).

[Approach 2]

Similar to approach 1. I tryed to get resource url, put the direct url to Link and download the resource in c# using direct link. I can construct the same resource url as is used by browser to download data when user clicks the link.

Extended file downloader that keeps resource, key and connector:

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;
    }
}

In view:

// 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);
String fixedResourceUrl = fixResourceReferenceUrl(downloader.getResourceUrl());
ExtendedFileDownloader downloader = new ExtendedFileDownloader(resource, this);
link2.setResource(new ExternalResource(fixedResourceUrl));    

Result: The data cannot be downloaded using this link, server error 410 or NotFound errors.

Any Ideas ? Any other approaches to try ?




Aucun commentaire:

Enregistrer un commentaire