开发者

GWT cross-domain rpc

I need to call a GWT application service from javascript which is running on different domain.

How could this be done? How do I point from my applicaton to the javascript url?

Thank y开发者_运维技巧ou.


The idea behind a cross domain request is the your java script creats a script tag which loads a generated java script from the forgein url. When loaded the generated java script is evaluated and calls a callback function you created.

The following code ist not testet and shows the idea:

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];
    }-*/;

}

If you create a CrossSiteDomainRequest Object for the URL http://www.test.com/loadXDR.js you have to evaluate the callbackId parameter and generate a java script which may looks like this:

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

The callbackId has to be replaced accordingly.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜