tags:

views:

54

answers:

2

Hi. Im moving first steps today on GWT framework. I need to understand (using the netbeans official tutorial how this application work :) I place the code :

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.yournamehere.client;

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.rpc.AsyncCallback;

/**
 * Main entry point.
 *
 * @author djfonplaz
 */
public class MainEntryPoint implements EntryPoint {
    /** 
     * Creates a new instance of MainEntryPoint
     */
    public MainEntryPoint() {
    }

    public static GWTServiceAsync getService() {
        // Create the client proxy. Note that although you are creating the
        // service interface proper, you cast the result to the asynchronous
        // version of the interface. The cast is always safe because the
        // generated proxy implements the asynchronous interface automatically.

        return GWT.create(GWTService.class);
    }

    public void onModuleLoad() {
        final Label quoteText = new Label();

        Timer timer = new Timer() {
            public void run() {
                //create an async callback to handle the result:
                AsyncCallback callback = new AsyncCallback() {
                    public void onFailure(Throwable arg0) {
                        //display error text if we can't get the quote:
                        quoteText.setText("Failed to get a quote");
                    }

                    public void onSuccess(Object result) {
                        //display the retrieved quote in the label:
                        quoteText.setText((String) result);
                    }
                };
                getService().myMethod(callback);
            }
        };

        timer.scheduleRepeating(1000);
        RootPanel.get().add(quoteText);
    }
}

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package org.yournamehere.client;

import com.google.gwt.user.client.rpc.RemoteService;
import com.google.gwt.user.client.rpc.RemoteServiceRelativePath;

/**
 *
 * @author djfonplaz
 */
@RemoteServiceRelativePath("gwtservice")
public interface GWTService extends RemoteService {
    public String myMethod();
}

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package org.yournamehere.client;

import com.google.gwt.user.client.rpc.AsyncCallback;

/**
 *
 * @author djfonplaz
 */
public interface GWTServiceAsync {
    public void myMethod(AsyncCallback callback);
}

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package org.yournamehere.server;

import com.google.gwt.user.server.rpc.RemoteServiceServlet;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import org.yournamehere.client.GWTService;

/**
 *
 * @author djfonplaz
 */
public class GWTServiceImpl extends RemoteServiceServlet implements GWTService {
    private Random randomizer = new Random();
    private static final long serialVersionUID = -15020842597334403L;
    private static List quotes = new ArrayList();

    static {
        quotes.add("No great thing is created suddenly - Epictetus");
        quotes.add("Well done is better than well said - Ben Franklin");
        quotes.add("No wind favors he who has no destined port - Montaigne");
        quotes.add("Sometimes even to live is an act of courage - Seneca");
        quotes.add("Know thyself - Socrates");
    }

    public String myMethod() {
        return (String) quotes.get(randomizer.nextInt(5));
    }
}

So (more or less) :

  1. the standard welcomeGWT.html is served to the server, which call directly trought the JS created the servlet MainEntryProject.java
  2. MainEntryProject.java (when is loaded trought onModuleLoad()) which should generate the string and send to the client.

Right at this point?

What i don't understand is :

  1. Who call the method myMethod() in GWTServiceImpl? Nobody ask this method, i just see getService().myMethod(callback), which should call the one of the GWTServiceAsync class.
  2. Who pass the string generated by GWTServiceImpls to public void onSuccess(Object result)?
  3. Why the getService() return GWTService and not the GWTServiceImpl? It should return a class, not an interface;

If someone can help me, would be really glad! cheers

+1  A: 

File MainEntryProject.java located in client package, so it's not servlet - it's java file which will be compiled by GWT to JavaScript. Resulted javascript embedded in your HTML file (welcomeGWT.html). So,

  • first loads welcomeGWT.html
  • then browser starts executing javascript generated by GWT, which after 1000ms calls server method myMethod
  • finally server return callback, client executing next code:

public void onFailure(Throwable arg0) {
quoteText.setText("Failed to get a quote");
}
public void onSuccess(Object result) {
quoteText.setText((String) result);
}

Answers:
1) Client calls that method.
2) Client
3) I could only guess, seems like it's just how RPC roll

Xo4yHaMope
Uhm...ok! I just find it bizzare hehe (in fact i don't know this framework at all i think hehe). So, call the "abstract" method of GWTServiceAsync will automatically call the implementation of that method written on GWTServiceImpl? After, i can manage what that method return using the instance "result"?
markzzz
Yes, if you call method from YourServiceAsync service it will result in invoking server method, from YourServiceImpl file. Think this article should explain everything else: http://code.google.com/intl/en/webtoolkit/doc/1.6/DevGuideServerCommunication.html#DevGuideRemoteProcedureCalls
Xo4yHaMope
And return type defined in YourService interface just as usual, YourServiceAsync in AsyncCallback argument like: "AsyncCallback<String> callback". And then server-side in YourServiceImpl method: "public String myMethod(String s){...}"
Xo4yHaMope
+2  A: 

To understand what's going on it's important that GWT uses Generators to create the actual client implementation of that service. With that technique it's possible to generate code which you would normally have to write by your own. The whole RPC calls are generated for you automatically.
interface GWTService: That's just your definition of what the service looks like
interface GWTServiceAsync: That's the interface which is implemented in the auto-generated client-part of your service.
class GWTServiceImpl: That's the code which runs on server side.

So when you call GWT.create(GWTService.class); you get an auto-generated class-instance. If you are really interested in what happens you have to look at the Generator implementation.
It's more or less what you would do manually:
- Serialize (google uses a non-standard method for this and it can change through different GWT versions)
- Setup the request with the serialized data
- Send the request and wait for response
- Deserialize respone and call return the result through the callback

Daniel
Yeah, that's happened to main Java application. But at least, there's a class that get and send value trought methods. On this framework i don't understand how this is possible :)
markzzz