Web Toolkit Blog
The official source of information about GWT.
Building Enterprise web apps in the cloud
Thursday, October 08, 2009
An important decision to make when building a web application is how to coordinate state between client and server. This includes how to create appropriate representations of your data to
send over the wire
.
There are many possible approaches. I'd like to present a straightforward one from Jerome Breche, CEO of TimZon, who was kind enough to share it with us today.
When we started our first GWT project (
TimZon.com
), we found out that one of the major benefits of using GWT is its ability to transfer complex object data structure between client and server through the
RPC mechanism
. So when we initiated our second project (
SnapABug.com
) combining GWT and
Google App Engine
, we were very excited by the prospect of passing datastore objects directly though RPC.
We quickly realized that this is not very practical. First one of our
JDO
objects includes images binary representation that we wouldn’t want to communicate through RPC. And then while making the JDO class serializable for GWT RPC may seem like a simple task, it created all kind of new problems since the JDO class will have to be configured as transient (using
detachable = "false"
) and we would still need to copy the object when passing it through the RPC. Instead we decided to simply create intermediary classes for the data objects used only for RPC communication. This way we can exactly control and optimize the data payload used by the RPC both for size and speed. On the JDO side, we simply created a getter and setter function to translate the JDO data into an RPC data format.
Here is an example of how this works in client side code.
1.
Employee
class: contains JDO objects definition and getter and setter to translate them to GWT RPC serializable format
@PersistenceCapable(identityType = IdentityType.APPLICATION) public class Employee {
@PrimaryKey @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY) private Long id; @Persistent private String name; @Persistent private String email; @Persistent private Blob image; /**
* Constructor * @param name * @param email */ public Employee(String name, String email) { this.name = name; this.email = email; } /** * Set Employee from RPCDataEmployee */ public void setRPCDataEmployee(RPCDataEmployee employee) { name = employee.name; email = employee.email; } /** * @return Employee data in RPC format */ public RPCDataEmployee getRPCDataEmployee() { RPCDataEmployee employee = new RPCDataEmployee(); employee.name = name; employee.email = email; return employee; } }
2.
RPCDataEmployee
class used by GWT RPC calls
public class RPCDataEmployee implements IsSerializable {
public String name; public String email; // Note: image Blob not included in RPC payload }
Here is an example of how this works in the server
3.
RPCDataEmployee
server service implementation
public RPCDataEmployee getEmployee(String email){ RPCDataEmployee employee = new RPCDataEmployee(); // create data store connection PersistenceManager pm = PMF.get().getPersistenceManager(); // query datastore to get emmployee data String query = "select from "
+ Employee.class.getName()
+ " where email == "
+ email;
List
employees =
(List
) pm.newQuery(query).execute();
if (employees.size() == 1) { // record found employee = employees.get(0).getRPCDataEmployee(); } else { // do something else... }
pm.close();
return employee; }
While I am sure there are many other ways to achieve a similar result, maybe even avoiding duplicating the data classes, this solution was the easiest for us to get going quickly, keep our code very maintainable and control the amount of data exchanged between client and server.
There is also a very interesting
discussion
about this subject on the GWT Google Group.
-- Jerome Breche, CEO & Founder of TIMZON, LLC
If you would like to share your experiences with GWT and Google App Engine, either privately or on this blog, I'd like to
hear from you
.
Labels
accessibility
1
crash
1
dev mode
2
English
172
googlenew
1
gwt
1
IE
1
internet explorer
1
Web Toolkit Blog
172
Archive
2016
Oct
2014
Dec
Nov
Sep
May
Jan
2013
Nov
Oct
Jul
Mar
Feb
2012
Dec
Oct
Sep
Jul
Jun
Jan
2011
Nov
Sep
Aug
Jul
Jun
May
Apr
Mar
Feb
Jan
2010
Dec
Oct
Sep
Aug
Jul
Jun
May
Apr
Mar
Feb
Jan
2009
Dec
Nov
Oct
Sep
Aug
Jul
Jun
May
Apr
Mar
Feb
Jan
2008
Dec
Nov
Oct
Sep
Aug
Jul
Jun
May
Apr
Feb
Jan
2007
Dec
Nov
Oct
Sep
Aug
Jul
Jun
May
Apr
Mar
Feb
Jan
2006
Dec
Nov
Oct
Sep
Aug
Jul
Jun
May
Feed