Comparison of AJAX Frameworks: Prototype, GWT, DWR and Thinware

May 25, 2007

AJAX, Web Frameworks

«»

GWT

For our sample application,

you can develop a GWT application without using an IDE, but is much

easier the other way around. I prefer to use Googleipse which is an

Eclipse plugin that supports GWT. Before using Eclipse, we got to create

a GWT project compatible with Eclipse. We can do that executing the

following commands:

projectCreator -eclipse

gwtTable -out gwtTable

Created directory gwtTable\src

Created file gwtTable\.project

This creates the gwtTable

project into the gwtTable folder. After that, we got to create

an application in the following way:

applicationCreator -eclipse

gwtTable -out gwtTable javabeat.net.example.client.TableExample

Created directory gwtTable\src\javabeat\net\example

Created directory gwtTable\src\javabeat\net\example\public

Created file gwtTable\src\javabeat\net\example\public\TableExample.html

Created file gwtTable\TableExample.launch

Created file gwtTable\TableExample-compile.cmd

One of the main benefits of

developing a GWT application within an IDE environment is the debugging

capabilities that it provides (step next, step into, etc.). To take

advantage of it we got to define a Debug launcher configuration

in Eclipse for this project. Look at the Debug windows of Eclipse

under Java Application tree. As it is shown in Figure 4, the

Debug launcherconfiguration for the project called gwtTable

has already been created for us, and it is ready to run!

 

Es posible que tu navegador no permita visualizar esta imagen.

 

To implement the asynchronic

call, that we need to retrieve the data from the server, we implement

a JavaBean that encapsulates the generated data. In this example we

implement the class TableData in the following way:

	 package javabeat.net.example.client; import com.google.gwt.user.client.rpc.IsSerializable; public class TableData implements IsSerializable { private static String[] columns= { "Fruit", "Price", "Stock", "Descrption" }; private static String[][] data = { {"Lemon", "23.4", "25", "Lemon fruit"}, {"Apple", "34.4", "5", "Apple fruit"}, {"Banana", "10.4", "10", "Banana fruit"}, {"Melon", "17.8", "7", "Melon fruit"}, {"Pear", "20.6", "8", "Pear fruit"}, {"India Berry", "18.5", "15", "India Berry"} }; public String[][] mydata=null; public TableData() { mydata = data; } } 

You also have to define an

interface that the client, or the eventual downloaded JavaScript code,

will use to call this service method. The GWT uses a callback design

pattern, with this in mind we have to develop the following code:

	 package javabeat.net.example.client; import com.google.gwt.user.client.rpc.AsyncCallback; public interface TableServiceAsync { void getData(AsyncCallback callback); } 

This class must extend RemoteServiceServlet. In other words, this class and the

interface it implements has to be deployed in your servlet container.

Configuration files

What is more interesting of

this technology is that the client code (that runs on the browser of

the client) is implemented in the server side as Java code! GWT compiler

is the piece of the puzzle that does all the magic when it translates

the Java code into Javascript code for us. With this design in mind,

we define a Java class for building the main page of the web application,

in this case TableExample.java (which already has a vanilla implementation generated by the command

line executed above).

 package javabeat.net.example.client; import com.google.gwt.core.client.EntryPoint; import com.google.gwt.core.client.GWT; import com.google.gwt.user.client.Window; import com.google.gwt.user.client.rpc.AsyncCallback; import com.google.gwt.user.client.rpc.ServiceDefTarget; import com.google.gwt.user.client.ui.Button; import com.google.gwt.user.client.ui.ClickListener; import com.google.gwt.user.client.ui.Label; import com.google.gwt.user.client.ui.RootPanel; import com.google.gwt.user.client.ui.Widget; import com.google.gwt.user.client.ui.FlexTable; /** * Entry point classes define <code>onModuleLoad()</code>. */ public class TableExample implements EntryPoint { TableServiceAsync service = (TableServiceAsync) GWT.create(TableService.class); ServiceDefTarget endpoint = (ServiceDefTarget) service; /** * This is the entry point method. */ public void onModuleLoad() { final Button button = new Button("Load data!"); final FlexTable table = new FlexTable(); endpoint.setServiceEntryPoint(GWT.getModuleBaseURL() + "/javabeatservice"); button.addClickListener(new ClickListener() { public void onClick(Widget sender) { service.getData( new AsyncCallback() { // what to do if it works public void onSuccess(Object result) { TableData td = (TableData)result; for (int i=0; i<td.mydata.length;i++) { for (int j=0; j<td.mydata[i].length;j++) { table.setHTML(i, j, td.mydata[i][j]); } } } // what to do if it fails public void onFailure(final Throwable caught) { Window.alert("failure - \n" + caught.getMessage()); } }); } }); RootPanel.get("slot1").add(button); RootPanel.get("slot2").add(table); } } 

Then, we can see the final

results using the Debug launcher defined previously in Eclipse

(Figure 5).

Es posible que tu navegador no permita visualizar esta imagen.

Figure 5.

DWR

DWR has a different conception

than the other frameworks (because of its design and the way it has

to be used), for this and for its popularity it seemed important to

us to mention it in the article.

As it is illustrated in Figure

6, DWR allow us to work in a RPC’s classic environment, in which you

get the freedom to handle the asynchrony communication in an explicit

way. It is important to notice that DWR doesn’t provide the user’s

interfaces that can be plugged within our web applications, which is

an important drawback compared with GWT and Thinware.

http://getahead.org/dwr/examples/tableAs you can tell from the example,

DWR is a very useful approach if you have good Javascript skills because

you got to update the GUI by means of Javascript code and DOM manipulation

(data-centric approach).

ThinWire

Why you should used Thinware

instead of GWT? Thinware published an article [4], which identifies

many reasons why you may use it instead of GWT, in our opinion, the

more representative are the following:

  • Full JavaAPI Access. GWT puts some restrictions on the Java code thatit can translate to Javascript. Thinware doesn’t have this limitation

    because the GUI is fully developed in Java code.

  • Linear Flowof Logic.As all the logic is implemented in the server, asopposed to GWT, it is easier to develop applications that contain server

    calls because we don’t have to trace the values from one language

    into another.

  • Richer Setof Dynamic Component Widgets. You can compare both widget capabilitiesfrom the demo application distributed by both frameworks and make your

    own judgment. Saying so, we agree with the Thinware’s team at this

    point. We consider that Thinware’s widgets are powerful than those

    provided by GWT.

  • Full ScaleDebugging.Easier to debug than GWT, because you develop usinga single language.

ThinWire

framework consists of the set of three JAR files shown in ,

plus a set of javadocs and a template of a file named

web.xml.

22,379

commons-fileupload.jar

313,731

thinwire.jar

To code our application, we

just need to implement a main class like the following:

	 package javabeat.net.thinware.example; import thinwire.ui.Application; import thinwire.ui.Button; import thinwire.ui.Frame; import thinwire.ui.GridBox; import thinwire.ui.Label; import thinwire.ui.Panel; import thinwire.ui.TabFolder; import thinwire.ui.event.ActionEvent; import thinwire.ui.event.ActionListener; import thinwire.ui.layout.TableLayout; public class Main { private static String[] columns= { "Fruit", "Price", "Stock", "Descrption" }; private static String[][] data = { {"Lemon", "23.4", "25", "Lemon fruit"}, {"Apple", "34.4", "5", "Apple fruit"}, {"Banana", "10.4", "10", "Banana fruit"}, {"Melon", "17.8", "7", "Melon fruit"}, {"Pear", "20.6", "8", "Pear fruit"}, {"India Berry", "18.5", "15", "India Berry"} }; private static GridBox comp = null; private static void loadData() { //insert the data for (int i = 0; i < data.length; i++) { comp.getRows().add(new GridBox.Row(data[i])); } } /** * @param args */ public static void main(String[] args) { Frame frame = Application.current().getFrame(); frame.setTitle("ThinWare: Simple Table Example."); frame.setVisible(true); comp = new GridBox(); comp.setBounds(255, 70, 250, 150); comp.setVisibleHeader(true); Button button = new Button("Load data!"); button.setBounds(255, 270, 70, 30); button.addActionListener(Button.ACTION_CLICK, new ActionListener(){ public void actionPerformed(ActionEvent e){ loadData(); }//end actionPerformed }//end ActionListener constructor );//end addActionListener GridBox.Column col; Panel panel = new Panel(); panel.setBounds(0, 0, frame.getWidth(), frame.getHeight()); panel.setVisible(true); //insert the header data for (int i = 0; i < columns.length; i++) { comp.getColumns().add(col = new GridBox.Column()); col.setName(columns[i]); } panel.getChildren().add(comp); panel.getChildren().add(button); frame.getChildren().add(panel); } } 

As you can see, all the client

and server interaction is handled by the framework and you don’t have

to mess with the plumbing related with the asynchronic communication.

The output generated with this example would be similar to the snapshot

illustrated in Figure 7.

Es posible que tu navegador no permita visualizar esta imagen.

Figure 7.

Conclusion

 

As we have been seeing the web is changing and maturing into something different, something more dynamic and interactive. To become part of it we got to use the best tools available to accomplish this kind of new interaction. We presented four of the best tools for that matter, each one of those has its own benefits and drawbacks. Although, the functionality of each is important, you have to take into account which one you estimate will fulfill your needs thinking about the future, because every tool of this kind is growing and making the difference every day. Saying so, Prototype (because
of its flexibility and clarity) and GWT (because it is support by Google) are the ones that we think are most valuable.

email

«»

Comments

comments