问题
My goal is to initiate RPC calls directly from javascript. I have come up with ways to fake callbacks (because of the asynchronous nature of RPC) but I can't figure out how to get custom objects into javascript.
So, I've created a class named Interop and I statically create the service I'm interested in (had to use static as it was all I could get working, I don't think it's relevant right now):
public class Interop {
private static final GreetingServiceAsync service = GWT.create(GreetingService.class);
...
}
I then create a function that will do the async calls and handle the responses:
public static void greetServer(final String success, final String failure) {
service.greetServer(
"Homer",
new AsyncCallback<String>() {
public void onFailure(Throwable caught) {
callback(failure, caught.toString());
}
public void onSuccess(String result) {
callback(success, result);
}
}
);
}
Then I create a JSNI function to export this function to javascript which I call from the onModuleLoad():
public static native void export() /*-{
$wnd.greetServer = $entry(@package.Interop::greetServer(Ljava/lang/String;Ljava/lang/String;));
}-*/;
And also create another JSNI function to deal with the callbacks:
public static native void callback(String func, String response) /*-{
$wnd[func](response);
}-*/;
So that the function names I pass into greetServer() initially for success and failure are called by the JSNI as callbacks. And this all works great when dealing with Strings or (I assume) a primitive type. But when I try to do this with custom types (note the altered Custom type parameter):
public static native void callback(String func, Custom response) /*-{
$wnd[func](response);
}-*/;
Then what ends up in javascript doesn't work. It seems to be a javascript object with cascading arrays and none of the methods are available.
So, the question is, how can Java-originated objects that aren't basic or primitives be accessed from within javascript (not JSNI)? From what I can tell JavaScriptObject needs to originate in javascript, but in my case, my objects are originating in Java. What can I do?
I've also looked into gwt-exporter and that shows how to instantiate java stuff from javascript, but not how to access java-originated stuff in javascript.
I know this is a bit confusing so please let me know if you have any questions. Thanks!
回答1:
With gwt-exporter this could be your code:
// Create and export a closure used to wrap javascript callbacks
@ExportClosure
public static interface InteropCallback extends Exportable {
void exec(String message);
}
// Make your Interop class exportable and export methods in it
@ExportPackage("foo")
@Export
public static class Interop implements Exportable {
final static GreetingServiceAsync service = GWT.create(GreetingService.class);
public static void greeting(String message,
final InteropCallback success,
final InteropCallback error) {
service.greetServer(message, new AsyncCallback<String>() {
public void onFailure(Throwable caught) {
error.exec(caught.getMessage());
}
public void onSuccess(String result) {
success.exec(result);
}
});
}
}
// In your onModuleLoad you have to make gwt-exporter export your stuff
@Override public void onModuleLoad() {
ExporterUtil.exportAll();
...
}
Finally call your java methods from handwritten javascript
window.foo.Interop.greeting("Hello",
function(s){console.log(s)},
function(s){console.log(s)}
);
来源:https://stackoverflow.com/questions/20709611/can-java-objects-be-accessed-from-javascript-in-gwt