| By Andrew Zuercher | Article Rating: |
|
| February 19, 2008 07:00 AM EST | Reads: |
21,663 |
The issue of serializing/transforming model objects is not new, heck I’ve been doing this for quite some time:
- RMI (ejb/corba)
- XML (jms, soap, etc..)
- JSON
When you define your Model classes, there are some very simple things to keep in mind:
- annotate your attributes with @MessageAttr
- have your class implement IModelObject
Here is a simple example:
<public class User implements IModelObject, Serializable {
private static final long serialVersionUID = 1L;
@MessageAttr
public String name;
public void setUsername(String username) {
this.username = username;
}
public void setPassword(String password) {
this.password = password;
}
...
}
Unit test it
Now to test the rendering of our object to JSON with a simple junit test…. As you can see, we leverage the Appcelerator framework to serialize our objects to JSON
public class ForumTest extends TestCase {
public void testSimple() {
User user = createUser();
Message message = new Message();
JSONMessageDataObject data = new JSONMessageDataObject();
message.setData(data);
message.getData().put("user", user);
message.getData().put("count", 1);
String messagestr = data.toDataString();
assertEquals(messagestr,"\"user\":{\"password\":
\"pwd\",\"threads\":0,\"fullName\"
:\"antewew\",\"username\":\"azuercher\",\"state\":
\"mystate\",\"email\":\"email\",
\"posts\":0,\"id\":0},\"count\":1}");
}
private User createUser() {
User user = new User();
user.setEmail("email");
user.setFullName("ante wew");
user.setId(new Long(0));
user.setPassword("pwd");
user.setPosts(new Long(0));
user.setState("mystate");
user.setThreads(new Long(0));
user.setUsername("azuercher");
return user;
}
}
Dealing with recursion
Whats always a bit of a tangle is understanding how to deal with the recursive/circular relationship.
If you take a look at JSONObject you will see 2 overridden methods for createBean
public static JSONObject createBean(IModelObject object,MessageAttr
parentAtt, String context,String[] parentSuppres,int level, int maxlevels)
public static JSONObject createBean(IModelObject object)
The latter is obviously a bit more simple, but the former is where the power is. In the MessageAttr annotation, you can provide the suppress attribute which is a comma separated list of aggregates (using bean.name notation to not serialize). This is used for attributes in your IModelObject implementation where the association is with another IModelObject. The following model is for a forum object model where the following aggregate hierarchy exists:
* Forum
** ForumThread
*** Post
In the snippet below, I’ve omitted the getter/setter methods for the aggregates for simplicity.
public class User implements IModelObject, Serializable {
@MessageAttr (suppress="user,thread.lastPost")
public Post lastPost;
}
public class Post implements IModelObject, Serializable {
@MessageAttr(suppress="lastPost,forum.lastPost")
public Forumthread thread;
@MessageAttr (suppress="lastPost")
public User user;
}
public class Forumthread implements IModelObject, Serializable {
@MessageAttr (suppress="lastPost")
public Forum forum;
@MessageAttr (suppress="thread,user.lastPost")
public Post lastPost;
}
public class Forum implements IModelObject, Serializable {
@MessageAttr (suppress="thread.forum,thread.lastPost,user.lastPost")
public Post lastPost;
}
Rolling your own serialization
Assuming you know what your JSON string is going to look like, you can use our RawMessageDataList and RawMessageDataObject to serialze your objects. This is pretty useful if you already are rendering JSON in an existing framework and don’t want to have to transform to and back again. The snippet below shows with static strings just so that you get the idea:
IMessageDataList people = new
RawMessageDataList(
"[{'name':'joe','age':22},{'name':'jane','age':33}]");
IMessageDataList dog = new RawMessageDataObject("{'breed':'doberman','weight':78}");
Message message = new Message();
message.setData(new JSONMessageDataObject());
message.getData().put("people", people);
message.getData().put("dog", dog);
Using Coarse Grained objects
This is probably the simplest/prettiest way to implement your services assuming that you aren’t interested in using fine grained classes that are associated with most of today’s persistence frameworks. Here is how you would create a single compound JSON object:
IMessageDataObject dog =
MessageUtils.createMessageDataObject();
obj.put("breed","doberman");
obj.put("wieght",78);Message message = new Message();
message.setData(new JSONMessageDataObject());
message.getData().put("dog", dog);
and now with a collection:
IMessageDataList<IMessageDataObject> people=
MessageUtils.createMessageDataObjectList();
IMessageDataObject joe =
MessageUtils.createMessageDataObject();
joe.put("name","joe");
joe.put("age",22);
IMessageDataObject jane =
MessageUtils.createMessageDataObject();
joe.put("name","jane");
joe.put("age",33);
people.put(joe);
people.put(jane);
Message message = new Message();
message.setData(new JSONMessageDataObject());
message.getData().put("people", people);
Summary
As you can see there are quite a bit of alternatives for you based on what your needs are to accommodate your service implementations. I’ve personally used all of the above as I’ve implemented:
- Model Objects: using Hibernate for persistence
- Custom Serialization: for integrating with pre-rendered objects (commons-monitoring)
- Coarse Grained: in implementing a dashboard/event driven solution
Published February 19, 2008 Reads 21,663
Copyright © 2008 SYS-CON Media, Inc. — All Rights Reserved.
Syndicated stories and blog feeds, all rights reserved by the author.
More Stories By Andrew Zuercher
Andrew Zuercher is an Enterprise Architect at Appcelerator, advocating the implementation of RIA with agile methodologies.
![]() |
Duty Editor 02/18/08 12:10:16 PM EST | |||
No problem Andrew, we've taken cxare of it. |
||||
![]() |
andrew zuercher 02/18/08 11:04:17 AM EST | |||
to dove tail on the feedback that i left last friday, i was wondering if you could corect the reference to http://zuerchtech.com instead of http://zuerchertech.com which is not associated with me whatsoever. much thanks, -andrew zuercher |
||||
![]() |
Andrew Zuercher 02/15/08 07:21:51 PM EST | |||
Thanks for publishing this article which is also cross posted at: Please note, that although I ran Zuercher Technologies based out of Atlanta, GA I have since dissolved it and now am employed at Appcelerator (http://appcelerator.com) as an Enterprise Architect advocating the implementation of RIA with agile methodologies. |
||||
- Acquia Announces Two New Board Members
- CollabNet Adds Board Member and Senior Executives to Fuel Continued Growth in Agile ALM and Enterprise Cloud Development
- Learn Open Source Database Tools from Stanford for Free
- Research and Markets: Global Mobile Device Management Enterprise Software Market 2010-2014 Includes a Discussion of the Key Vendors Operating in This Market
- Alternative Search Engines for the Contemporary User
- FORTUNE Magazine Names Rackspace Among “100 Best Companies to Work For”
- New York City : Blueprint for Cloud-enabled economic transformation
- EnterpriseDB Announces Availability of Postgres Plus Cloud Database
- Connectria Hosting Achieves "Off the Chart" Operational Efficiency With Cloud-Based Storage Solution From Nexsan and CommVault
- ICOS and Joyent Announce Strategic Partnership to Deliver Joyent's Cloud Infrastructure Solution to Channel Partners and Service Providers
- eXo Platform 3.5 Now Available: First Cloud-Ready Enterprise Portal and User Experience Platform-as-a-Service (UXPaaS)
- Research and Markets: WordPress 24-Hour Trainer, 2nd Edition
- Five Years Waiting for JRE 7: Is It Justified? (Part 1)
- Book Review: The CERT Oracle Secure Coding Standard for Java
- Acquia Announces Two New Board Members
- CollabNet Adds Board Member and Senior Executives to Fuel Continued Growth in Agile ALM and Enterprise Cloud Development
- Learn Open Source Database Tools from Stanford for Free
- Research and Markets: Global Mobile Device Management Enterprise Software Market 2010-2014 Includes a Discussion of the Key Vendors Operating in This Market
- Government Big Data Solutions Award Nominee: Wayne Wheeles (Sherpa Surfing)
- Alternative Search Engines for the Contemporary User
- FORTUNE Magazine Names Rackspace Among “100 Best Companies to Work For”
- New York City : Blueprint for Cloud-enabled economic transformation
- EnterpriseDB Announces Availability of Postgres Plus Cloud Database
- Load testing the post office
- Java Developer's Journal Exclusive: 2006 "JDJ Editors' Choice" Awards
- The i-Technology Right Stuff
- Creating Web Applications with the Eclipse Web Tools Project
- Eclipse Special: Remote Debugging Tomcat & JBoss Apps with Eclipse
- The Next Programming Models, RIAs and Composite Applications
- Where Are RIA Technologies Headed in 2008?
- SYS-CON Webcast: Eclipse IDE for Students, Useful Eclipse Tips & Tricks
- How to Bring Eclipse 3.1, J2SE 5.0, and Tomcat 5.0 Together
- Eclipse: The Story of Web Tools Platform 0.7
- "Eclipse 3.0 is a Great Leap Forward," Says JDJ's Dudney
- The Top 250 Players in the Cloud Computing Ecosystem
- Developing an Eclipse BIRT Report Item Extension

























