GWT
From Shiftyjelly
Contents |
Tutorials
How to set up a Netbeans Project, using EJB3 and GWT:
Ejb3_and_gwt
Tips
Speed up Page Loading, by pre-serializing your GWT calls
If every time a page/widget loads you make the same RPC calls, then you would benefit from loading that data server side, and putting it into the javascript on the page. This saves the time taken for a HTTP AJAX request, and can make a large difference to you page loading times.
Here's an example, it involves loading a List<String>, but you can load any kind of object that you would normally over RPC. (Note that as at the time of writing this example you have to add IsSerializable to any custom objects even if they already implement java.io.Serializable, as you will get security exceptions if you don't):
On your JSP Page:
<script><%=au.com.shiftyjelly.web.helper.GwtPreserializerHelper.getQuoteFormData()%></script>
The method in the GWTPreserializerHelper class:
public static String getQuoteFormData(){
try{
//pre prepare the quote form data, so that we don't have to make an ajax request for it
YourServiceImpl service = new YourServiceImpl();
List<String> codes = service.getMyFdCodes();
//put the encoded RPC call into a string
StringBuilder data = new StringBuilder();
data.append("window.codes = '");
data.append(RPC.encodeResponseForSuccess(YourServiceImpl.class.getMethod("getCodes"), codes));
data.append("';\n");
return data.toString();
}
catch (Exception e){
LOG.log(Level.WARNING, "Unable to pre-serialize fd codes", e);
return "";
}
}
How to use this in your GWT code:
....
//load the fd codes off the page
String storedCodes = getPrePreparedCodes();
if (storedCodes.length() > 0){
try {
SerializationStreamFactory streamFactory = GWT.create(YourService.class);
List<String> codes = (List<String>) streamFactory.createStreamReader(storedCodes).readObject();
//...do something interesting with the data, which has now been de-serialized
}
catch (Exception ex) {}
}
....
private native String getPrePreparedCodes() /*-{
try{
return (typeof($wnd.codes) == 'undefined')? "" : $wnd.codes;
}catch(e){}
}-*/;
N.B. If you expect your GWT data to have characters like single quotes in it, you will have to escape them, because the GWT RPC doesn't do it for you:
//do our best to remove characters that are going to break javascript string and GWT
quoteData.append(successString.replaceAll("'", "\\\\'").replaceAll("\\\\r", "").replaceAll("\\\\n", Matcher.quoteReplacement("\\\\n")));
Speed up Compile Time
Compile Only For One Browser
By default GWT compiles 5 versions of your code: opera, safari, ie6, gecko & gecko1_8. To speed up compile time, say if you use firefox 2 or 3, you could just tell it to compile that one (in your .gwt.xml file):
<set-property name="user.agent" value="gecko1_8" />
Use The Power of Ant to Build Changes Only
Modify your build-gwt.xml file (assuming you're using Netbeans and have used the gwt4nb plugin to generate one) by adding a task to check if your GWT code has been changed:
<target name="check-dashboard-update">
<echo>Checking ${gwt.module.dashboard}</echo>
<uptodate targetfile="${build.gwt.dir}/.flagfile-${gwt.module.dashboard}" property="dashboard.uptodate">
<srcfiles dir="${src.dir}" includes="**/gwt/**/*" />
</uptodate>
<echo message="dashboard.uptodate: ${dashboard.uptodate}" />
</target>
Then make your compile depend on that task:
<target name="compile-dashboard" depends="check-dashboard-update" unless="dashboard.uptodate">
And finally do the following inside your compile to update the touch file:
<touch file="${build.gwt.dir}/.flagfile-${gwt.module.dashboard}" verbose="true"/>
Code Samples
GWT RPC Paged Table
A native GWT paged table that is still a bit rough around the edges, but allows paging/sorting/etc all using generics and supports GWT RPC. I made it because the GWT-Ext one was just too clunky to use with RPC. To use it:
new PagedTable(new YourTableSourceImpl(), new YourTableRendererImpl(), 30);
Where YourTableSourceImpl() is a class that implements the TableSource interface and YourTableRendererImpl is a class that implements the TableRenderer interface:
public interface TableSource<T> {
public void loadDataForPage(PagingDetails pagingInfo, DataLoadCallback<T> callback);
}
public interface TableRenderer<T> {
public void displayRow(int row, FlexTable table, T obj);
public ColumnInfo[] getColumnInfo();
public void setRefreshHandler(RefreshCallback callback);
}
You may use this code freely in any way shape or form, and don't even have to acknowledge me as the original author if you choose not to.
Download it here: Media:paged_table_source.zip