GWT междоменный RPC - PullRequest
       4

GWT междоменный RPC

0 голосов
/ 29 июня 2011

Мне нужно вызвать службу приложений GWT из javascript, которая работает в другом домене.

Как это могло быть сделано? Как я могу указать от моего приложения на URL JavaScript?

Спасибо.

1 Ответ

0 голосов
/ 05 июля 2011

Идея междоменного запроса заключается в том, что ваш java-скрипт создает тег сценария, который загружает сгенерированный java-скрипт из поддельного URL. При загрузке сгенерированный Java-скрипт оценивается и вызывает созданную вами функцию обратного вызова.

Следующий код не тестируется и показывает идею:

public class CrossSiteDomainRequest {

    /** Counter to create unique ids for callback function. */
    private static int idCounter = 0;

    /** Url to load the javascript from. */
    private String url;

    /**
     * Creates a new loader with the given <code>url</code>.
     * @param url to load the java script from {@link #url}.
     */
    public CrossSiteDomainRequest(String url) {
        this.url = url;
    }

    /**
     * Uses the {@link #url} to load the data from another url. 
     */
    public void load() {
        String callbackId = "callbackId" + idCounter++;
        String prepend = url.indexOf("?") != -1 ? "&" : "?";
        String u = url + prepend + "callback=" + callbackId// Add more Parameters

        createCallback(this, transId);

        Element script = DOM.createElement("script");
        script.setAttribute("src", u);
        script.setAttribute("id", callbackId);
        script.setAttribute("type", "text/javascript");
        script.setAttribute("language", "JavaScript");

        getHead().appendChild(script);
    }

    /**
     * Destroys the callback with the given <code>id</code>.
     * @param id of the script tag and native javascript callback function which should be destroyed.
     */
    protected void destroyCallbackmethod(String id) {
        getHead().removeChild(DOM.getElementById(id));
        removeCallback(id);
    }

    /**
     * This method is invoked by the callback to handel the loaded data.
     * @param callbackId DOM-Id of the callback whick invoked this method.
     * @param jso Object that encapsultes the loaded data.
     */
    @SuppressWarnings("unchecked")
    protected void onReceivedData(String callbackId, JavaScriptObject jso) {
        try {
            // Read data
        } catch (Exception e) {
            // Handle Error
        }
        destroyCallbackmethod(callbackId);
    }

    /**
     * Creates a native javascript callback.
     * @param cscr to invoke the {@link #onReceivedData(String, com.google.gwt.core.client.JavaScriptObject)} on when the data has been loaded.
     * @param callbackId DOM-Id to create the callback back.
     */
    private native void createCallback(CrossSiteDomainRequest cscr, String callbackId) /*-{
        $wnd[callbackId] = function(j) {
            proxy.@com.test.package.client.CrossSiteDomainRequest::onReceivedData(Ljava/lang/String;Lcom/google/gwt/core/client/JavaScriptObject;)(callbackId, j);
        };
    }-*/;

    private native void removeCallback(String callbackId) /*-{
        $wnd[callbackId] = null;
    }-*/;

    public static native Element getHead() /*-{
        return $doc.getElementsByTagName('head')[0];
    }-*/;

}

Если вы создаете объект CrossSiteDomainRequest для URL http://www.test.com/loadXDR.js Вы должны оценить параметр callbackId и сгенерировать Java-скрипт, который может выглядеть следующим образом:

callbackId({"menu": {
    "id": "file",
    "value": "File",
    "popup": {
        "menuitem": [
             {"value": "New", "onclick": "CreateNewDoc()"},
             {"value": "Open", "onclick": "OpenDoc()"},
             {"value": "Close", "onclick": "CloseDoc()"}
         ]
    }
}});

callbackId необходимо заменить соответствующим образом.

...