5

I am trying to follow this tutorial on how to connect to a database in GWT, but instead of creating a login program, I am trying to retrieve a GWT Visulation DataTable from my DB so that I can then create a Annotated TimeLine. I have gotten very far, but I hit the final wall I can't figure out. Unlike the tut, I am not returning a simple User class from the RPC, but a complex DataTable. The problem is that this DataTable must be serializable by GWT standards. Is there any easy way for accomplish this?

I am using a RPC, instead of a Query system for security reasons. I don't want people to by able to look at my javascript and see my queries and such.

Thank you.

UPDATE: After going back to the problem I have found that DataTable is a JavaScriptObject and was probably never meant to be made on the server side. So new question, What is the best way to manually make DataTable into something serlizable and then what is the best way to remake it client side. Thanks Again!

Robert Munteanu
  • 67,031
  • 36
  • 206
  • 278
Eric Koslow
  • 2,004
  • 2
  • 21
  • 33

3 Answers3

4

Ok so I figured it out myself (sorta) so I thought I would post the answer here in case someone else happens to have the same problem later.

The answer in short that is impossible. DataTable is a JSO object, and in GWT current release (1.6something) it can not serialize those types of objects. What I had to do was break down my data into a series of ArrayLists and hold those in a temperay Object. That object can then be serialized and sent to the client side. The problem with this is that you must then construct the DataTable object on the client side.

If anyone else happens to come up with a better idea I would still be interested on finding out.

Thanks.

-Eric

Eric Koslow
  • 2,004
  • 2
  • 21
  • 33
1

The Google API Libraries for Google Web Toolkit (such as gwt-visualization.jar) are only meant for use on the client side (for generating javascript). Fortunately Google also provides the server-side java code for publishing DataTables in their Google Visualization Data Source Library.

Here is the setup that allowed me to generate DataTables on the server in a remote procedure call, pass them back to the client as a JSON string, and use Google Visualizations for Google Web Toolkit to display a nice Google Plot on the client web page. I am using Eclipse Indigo with Google Web Toolkit 2.4.0.

  • Add the gwt-visualization.jar GWT API binding client library to your project's build path, and as an inherited module in your own module's description:

In src/com.package.name/project-name.xml :

<inherits name='com.google.gwt.visualization.Visualization'/>
  • Add the jar for the Google Visualization Data Source Library and all the included dependency jars to PROJECT/war/WEB-INF/lib for the server code to use
  • Define a remote procedure interface that returns a String:

In client/TableService.java :

package com.clark.demos.client;

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

@RemoteServiceRelativePath("table")
public interface TableService extends RemoteService {
    String getTable(); 
}

In client/TableServiceAsync.java :

package com.clark.demos.client;

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

public interface TableServiceAsync {
    void getTable( AsyncCallback<String> callback );
}

In war/WEB-INF/web.xml :

  <servlet>
    <servlet-name>tableServlet</servlet-name>
    <servlet-class>com.clark.demos.server.TableServiceImpl</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>tableServlet</servlet-name>
    <url-pattern>/google_visualization___gwt/table</url-pattern>
  </servlet-mapping>
  • Implement the "table" service on the server:

In server/TableServiceImpl.java :

package com.clark.demos.server;

import com.google.visualization.datasource.datatable.ColumnDescription;
import com.google.visualization.datasource.datatable.DataTable;
import com.google.visualization.datasource.datatable.value.ValueType;
import com.google.visualization.datasource.render.JsonRenderer;

@SuppressWarnings("serial")
public class TableServiceImpl extends RemoteServiceServlet implements
        TableService {

    @Override
    public String getTable() {      
        DataTable data = new DataTable();
        data.addColumn( new ColumnDescription("Task", ValueType.TEXT, "Task") );
        data.addColumn( new ColumnDescription("Stemming", ValueType.NUMBER, "Stemming") );
        data.addColumn( new ColumnDescription("NoStemming", ValueType.NUMBER, "No Stemming") );
        data.addRowFromValues( "Fire", 1.0, 0.8 );
        data.addRowFromValues( "Flood", 0.5, 0.65 );            
        return JsonRenderer.renderDataTable(data, true, false, false).toString();
        }

}
  • Have client code call the "table" service and construct a DataTable from the returned JSON string:

In client/gwt-visualization-demo.java :

/**
 * Create a remote service proxy to talk to the server-side Table service.
 */
private final TableServiceAsync tableService = GWT
        .create(TableService.class);  

public static native DataTable toDataTable(String json) /*-{
  return new $wnd.google.visualization.DataTable(eval("(" + json + ")"));
}-*/;   

public void onModuleLoad() {

// Create a callback to be called when the visualization API
// has been loaded.
Runnable onLoadCallback = new Runnable() {
    public void run() {
        final Panel panel = RootPanel.get();

        tableService.getTable(new AsyncCallback<String>() {

            @Override
            public void onSuccess(String result) {                  
                AbstractDataTable data = toDataTable(result);
                BarChart pie = new BarChart(data, createOptions());

                pie.addSelectHandler(createSelectHandler(pie));
                panel.add(pie);             
            }

            @Override
            public void onFailure(Throwable caught) {               
            }
        });
      }
    };

// Load the visualization api, passing the onLoadCallback to be called
// when loading is done.
VisualizationUtils.loadVisualizationApi(onLoadCallback, BarChart.PACKAGE);

}

Example code found at https://github.com/RichDickClark/gwt-google-charts-demo.git

Clark
  • 890
  • 8
  • 20
1

I think you can do it

on server side

String json = JsonRenderer.renderDataTable(yourDataTable, true, true);

and on client side use some thing like

public static native DataTable toDataTable(String json) /*-{
  return new $wnd.google.visualization.DataTable(eval("(" + json + ")"));
}-*/;

I think it should work

hassan
  • 11
  • 1
  • I get "com.google.gwt.core.client.JavaScriptException: (TypeError): $wnd.google.visualization is undefined" ... do I have and if yes, where do I have to load libraries or APIs? I would like to use this in GWT Widget on the client side... – zero_r Mar 21 '11 at 14:46