GWT Sushi
Rolls of GWT, Java, Spring, Grails, Design Patterns and other pro web development goodies.
Sunday, November 13, 2011
Subjective thoughts on best practice with GWT applications.
If you have spent anytime with me you know I love GWT. But in my humble opinion there are ways to build web applications that still involve the gamut of javascript frameworks and bog-standard HTML5 and javascript. Through my vast and continued learning experience of GWT I am beginning to see it in its current guise as being great for building complex and large widgets embedded in a web environment that is built in a more traditional web application framework. Using the word tradition is kind of absurd in the web application design sphere because a tradition is established in a matter of months and then disposed for a new tradition within a couple of years. However we appear to be heading towards a path of convergence in how and the way we code. I recognise this as entirely subjective but for companies adopting GWT for the first time, experimenting with complex GWT widgets, then embedding them into their existing web applications is a great way to start on the GWT path.
Model-View-Controller (MVC) and Model-View-Presenter (MVP) are becoming the de-facto design patterns for building desktop, web and mobile applications. Developers pay attention, if these are not on your resume, get them on there as fast as possible. You should not leave home without it. Many frameworks in almost every language develop according to this pattern. So whether you are using Ruby on Rails, Grails, GWT, Spring MVC, Backbone.js they all design their frameworks around this convention. GWT is a little late to the game with regards to this and so two additional frameworks have been around for a while which in my opinion currently offer a lot more features than the "Activities and Places" inbuilt infrastructure. These two frameworks are GWT-Platform and MVP4G. They are both on Google Code and both have extensive user collaboration and input. Developing outside of GWT in the standard HTML-CSS-JS arena backbone.js offers a Javascript implementation of MVC. I haven't used it as of yet but from the brief tutorials I have read it appears to be very easy to use.
In a similar vein, Dependency Injection is also a must have. Design your code to interfaces and inject interfaces at runtime. This is achievable in GWT using Google GIN on the client and Google GUICE on the server. However my current overwhelming suggestion on the server is the Spring framework. If you are writing Java server code and not using Spring, you are probably writing lots of boilerplace bullshit. Stop it now!. My server side framework knowledge is limited so would love to hear from other developers on alternatives, but from what I have seen this is well adopted, supported and promoted in the media and job adverts. Spring is about more than Dependency Injection but this is at the core of the framework. If you want to develop modular, testable code then you need to use DI.
Using the Facebook web site as an example lets look at how you might construct this from scratch. Some GWT developers will suggest that the whole site should be built in GWT. I disagree but more on that later. However I believe that you will have a more flexible and productive if you develop the complex parts of your web site in GWT and embed them into the website. So when looking at your newsfeed the complex box that controls updating your status etc might be a small GWT application but it is embedded in an AJAX-controlled feed panel table. The reason I think this? Unless your whole team consists of ninja, ex-Google GWT developers that worked on the ad-sense or ad-words interface, then you are going to experience delays in your project as you migrate your developers to a new way or working. By concentrating complexity in small manageable chunks you reduce your exposure to delays in your project.
Tuesday, November 1, 2011
Single Sign On to Google Apps Marketplace with a Grails application
Hey, have you tried Grails? If you love Java and love Spring, you are going to adore Groovy on Grails (www.grails.org). Last week I decided to try out Groovy on Grails using the excellent free ebook located here: free ebook - yes please. The book took me two days to navigate through and if you have any experience in Ruby on Rails, you are going to love it.
Grails applications are typically called Groovy on Grails. Groovy is the language and Grails is the utility that uses convention over configuration to build easily, web applications. I won't go into too much detail here as the book says it better than I can but it is well worth checking out.
SSO - Google Apps Marketplace
As usual I always try to do something "complicated" in order to test the validity and maturity of any framework. My usual test case is to try Single Sign On with the Google Apps Marketplace. Again I am not going to go into too much details on what that actually means but if you are a Google Apps user and you have installed a third party application it is a way of authenticating the user without having to ask them for their credentials. Since I build apps for the Google Apps Marketplace I have to ensure I can do this otherwise the framework itself won't be a good choice. In addition because I am not an OpenID expert and prefer to stand on the shoulders of giants, the ease at which this can be implemented and understood is very important to me.
Since Groovy is a superset and dynamic language and can basically use Java and Java dependencies and since I had already built a SSO solution in a Java-GWT application for www.contactpa.com, I figured this should be fairly simple. On the whole it was my biggest problem was understanding how Dependency Injection works with Grails / Groovy and how to include dependencies in my project.
All code is available here on this github repository.
What did I learn?
Here are the pitfalls and problems I overcame whilst building this project:
Dependencies: I love/hate Maven, I have enough power to know how to do something and resolve issues but not a complete mastery, I am a perfectionist, to really understand. Anyhow I recognise the power of Maven and love it otherwise. So my first question was how to include dependencies. Now I tried messing around with the project by mavenizing but this left me with a whole host of other issues which I couldn't understand. Mainly due to my lack of experience in Grails. So I decided to use the standard approach. On conf/BuildConfig.groovy there are several sections to add dependencies. Anyone with maven experience will understand this coding convention:
dependencies {
// specify dependencies here under either 'build', 'compile', 'runtime', 'test' or 'provided' scopes eg.
// runtime 'mysql:mysql-connector-java:5.1.13'
runtime 'mysql:mysql-connector-java:5.1.13'
compile group:'org.openid4java', name:'openid4java-consumer', version:'0.9.6'
compile group:'com.google', name:'step2-common', version:'1-SNAPSHOT'
compile group:'com.google', name:'step2-consumer', version:'1-SNAPSHOT'
compile group:'com.google.inject', name:'guice', version:'3.0'
compile group:'javax.servlet', name:'jstl', version:'1.2'
compile group:'org.apache.httpcomponents', name:'httpclient', version:'4.1'
compile (group:'org.openxri', name:'openxri-client', version:'1.2.1') { excludes([ group: 'org.slf4j', name: 'slf4j-jcl']) }
compile group:'org.jdom', name:'jdom', version:'1.1'
compile group:'com.google.collections', name:'google-collections', version:'1.0'
}
Mapping the openid: I created a controller called GAMOpenIdController which stands for Google Apps Marketplace OpenID. Using convention this would have mapped to a url:/GAMOpenId/OpenID where for clarity I would prefer it to look like this: url:/openid. This url is the one Google redirects you to to check a user exists and then to authenticate the application. In order to do this I had to add an entry into the UrlMappings.groovy configuration file:
"/openid"(controller:"GAMOpenId", action:"openid")
Adding Java SSO Code: This is one of the reasons Grails is so awesome. You can embed Java code in with your Groovy code. Awesome. So I copied my SSO helper code from my other application. This is largely based on the marketplace sample application located here.
I have modified this code slightly and will include a full copy of the grails application at the end of this article.
Adding the Controller: This was so easy. See the code at the end.
Adding the service: Services in Grails control the business logic so I added all the servlet code from the marketplace application in here, but modified for Groovy. See file contactpa.GoogleOpenIdAuthService.groovy. This then called the Java SSO Code listed above. I didn't really have a problem here but the final stage of authentication was failing. I fixed this in the method getReceivingUrl(). It turns out when the server makes a call to another server, when the request is returned this is routed to a URL of the format: url:/grails/GAMOpenId/openid.dispatch whereas for the receivingURL to be authenticated correctly it should read url:/openid.
Don't edit applicationContext.xml: One trap, coming from a Spring background was that I needed to add some DI Beans in my Spring configuration for the Java SSO stuff above. Instead of following Grails convention I decided to edit the applicationContext.xml, which you would ordinaarily do in a standard Spring app. However this gave me a whole host of unusual errors until I read that beans should be configured in a file called resources.xml. So in conf/spring/resources.xml I added my beans:
<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"xmlns:util="http://www.springframework.org/schema/util" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:task="http://www.springframework.org/schema/task"xmlns:p="http://www.springframework.org/schema/p"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsdhttp://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsdhttp://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsdhttp://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.0.xsd"><bean name="consumerHelperFactory" class="contactpa.sso.ConsumerFactory" /><bean name="consumerHelper" class="com.google.step2.ConsumerHelper" factory-method="getConsumerHelper"factory-bean="consumerHelperFactory" /><bean name="httpFetcher" class="com.google.step2.http.DefaultHttpFetcher" /><bean name="googleHostedHostMetaFetcher"class="contactpa.sso.GoogleHostedHostMetaFetcher"><constructor-arg index="0" ref="httpFetcher" /></bean></beans>
Summary
This has turned to be a bit of a mind dump as I navigate a new area in Java development, for me anyhow. Grails is a great natural progression for Java developers looking to get into dynamic programming and using a framework for convention over configuration.
I have open sourced this project and it is available at git hub to analyse and comment on:
https://github.com/thinkjones/SSO-with-Google-Apps-Marketplace-with-Grails
Wednesday, October 26, 2011
Hey fools I am on twitter - @gwtsushi
With reference to the title of this article: After recently completing the Steve Jobs' biography I am convinced that the best way to succeed is to be a brutally honest ass hole. It won't last long, films and books tend to affect me. Anyway readers I am trying to spruce up my twitter feed and I need three things:
1. A good logo.
2. Brilliant followers
3. Good things to follow.
Feel free to help, suggest or get in contact: @gwtsushi .
1. A good logo.
2. Brilliant followers
3. Good things to follow.
Feel free to help, suggest or get in contact: @gwtsushi .
Tuesday, September 6, 2011
Spring Roo 1.2.0 with GWT and Google App Engine
I was first introduced to Spring Roo at Google IO 2010 and I was amazed with the product, it allowed a developer to prototype an application very quickly, building everything from the server, domain, and GWT client. It looked awesome.
When I got home I realised that we were shown a fixed demo in that many of the features didn't really work when building on Google App Engine and Google Web Toolkit. Not a problem as all developers know we are used to living on the cutting alpha-beta edge of software where great new features come with one huge caveat, they occasionally don't work.
That was then and this is now. Like Sushi which I try every 6 months just to confirm that I still am not a huge fan, it doesn't taste of anything right?, I try the latest version of Spring Roo.
The Upgrade Path
Let me just say that I love SpringSource they provide a lot of excellent tools for the Java developer and the Spring Roo documentation is no exception. The upgrade path is very easy, unpack the latest Spring Roo to a directory of your choosing, amend your $ROO_HOME variable in .profile (Mac OSx) and then re-establish the symbolic link to the roo command line. (sudo ln -s $ROO_HOME/bin/roo.sh /usr/bin/roo)
Done and done!
The Bleeding Edge
So I tried Spring Roo 1.1.5 and it was giving me lots of errors with trying a GWT-GAE project. It seemed as equally unreliable as I had tried with previous versions. Let me just add if you are using a standard database such as MySQL or any of the other persistence options, I believe Spring Roo works just fine. The problems I usually run into are related to the peculiarities of Google App Engine and how Roo handles those.
Since most of my current projects are currently in the GAE-GWT sphere and Roo advertises that it is suppose to work in this area, I decided to upgrade to the very latest Spring Roo, so I delved into the nightly builds and installed (1.2.0.BUILD-SNAPSHOT [rev 176e407]).
Go for 1.2.0 Its Much Better
After building a couple of projects with 1.2.0 I can honestly say this is the best version yet by far. Why? Well it appears to work this time for GWT-GAE projects. Most of my personal work is done on Google App Engine. This might change as I am not really liking the new billing restrictions but we will see how those actually plan out when implemented.
I typically build small projects that utilise some sort of reference between domain objects and then build a GWT project and then test it to see if it actually works. I will deal with deployment in a different post. What is great about Roo is that you can amend say the domain objects and the auto UI will get updated automatically. Simply add the line : private String userName; : to your domain object, boot up Roo and it auto creates the UI amendments needed. Pretty stunning. I haven't yet got to work out how you prevent it from doing this should you want to improve the UI, but I am sure that will come soon.
The project I have built it is that for a taxi company to take bookings. It includes three domain objects Contact, Booking and Journey. A booking can have one or more contacts, and one ore more journeys.
A Spring Roo GAE GWT project that works
Here is the contents of my Roo file, hopefully this will help you work with your project.
Next Steps
If you have used Roo or have done some interesting things with a Roo project please get in contact. I have yet to explore the AddOns or detailed more information on the workflow in a Roo project that goes from prototyping to real world application. Get in contact and lets document some Best Practices for this awesome product.
When I got home I realised that we were shown a fixed demo in that many of the features didn't really work when building on Google App Engine and Google Web Toolkit. Not a problem as all developers know we are used to living on the cutting alpha-beta edge of software where great new features come with one huge caveat, they occasionally don't work.
That was then and this is now. Like Sushi which I try every 6 months just to confirm that I still am not a huge fan, it doesn't taste of anything right?, I try the latest version of Spring Roo.
The Upgrade Path
Let me just say that I love SpringSource they provide a lot of excellent tools for the Java developer and the Spring Roo documentation is no exception. The upgrade path is very easy, unpack the latest Spring Roo to a directory of your choosing, amend your $ROO_HOME variable in .profile (Mac OSx) and then re-establish the symbolic link to the roo command line. (sudo ln -s $ROO_HOME/bin/roo.sh /usr/bin/roo)
Done and done!
The Bleeding Edge
So I tried Spring Roo 1.1.5 and it was giving me lots of errors with trying a GWT-GAE project. It seemed as equally unreliable as I had tried with previous versions. Let me just add if you are using a standard database such as MySQL or any of the other persistence options, I believe Spring Roo works just fine. The problems I usually run into are related to the peculiarities of Google App Engine and how Roo handles those.
Since most of my current projects are currently in the GAE-GWT sphere and Roo advertises that it is suppose to work in this area, I decided to upgrade to the very latest Spring Roo, so I delved into the nightly builds and installed (1.2.0.BUILD-SNAPSHOT [rev 176e407]).
Go for 1.2.0 Its Much Better
After building a couple of projects with 1.2.0 I can honestly say this is the best version yet by far. Why? Well it appears to work this time for GWT-GAE projects. Most of my personal work is done on Google App Engine. This might change as I am not really liking the new billing restrictions but we will see how those actually plan out when implemented.
I typically build small projects that utilise some sort of reference between domain objects and then build a GWT project and then test it to see if it actually works. I will deal with deployment in a different post. What is great about Roo is that you can amend say the domain objects and the auto UI will get updated automatically. Simply add the line : private String userName; : to your domain object, boot up Roo and it auto creates the UI amendments needed. Pretty stunning. I haven't yet got to work out how you prevent it from doing this should you want to improve the UI, but I am sure that will come soon.
The project I have built it is that for a taxi company to take bookings. It includes three domain objects Contact, Booking and Journey. A booking can have one or more contacts, and one ore more journeys.
A Spring Roo GAE GWT project that works
Here is the contents of my Roo file, hopefully this will help you work with your project.
project com.prestige.booking persistence setup --provider DATANUCLEUS --database GOOGLE_APP_ENGINE --applicationId PrestigeBooking enum type --class ~.shared.domain.ContactType enum constant --name Booking enum constant --name Billing enum constant --name Passenger entity --class ~.shared.domain.Contact --testAutomatically field string --fieldName fullName --notNull field string --fieldName email field string --fieldName phoneNumber field enum --fieldName contactType --type ~.shared.domain.ContactType entity --class ~.shared.domain.Booking --testAutomatically field reference --type ~.shared.domain.Contact passenger entity --class com.prestige.booking.shared.domain.Journey --testAutomatically field date --fieldName journeyDate --type java.util.Date field string --fieldName startAddress field string --fieldName endAddress field string --fieldName startTime field reference --fieldName booking --type com.prestige.booking.shared.domain.Booking loggin setup --level INFO web gwt setup
Next Steps
If you have used Roo or have done some interesting things with a Roo project please get in contact. I have yet to explore the AddOns or detailed more information on the workflow in a Roo project that goes from prototyping to real world application. Get in contact and lets document some Best Practices for this awesome product.
Labels:
GAE,
GWT,
Roo,
Spring Roo,
SpringRoo
Friday, September 2, 2011
Including external dependencies in your Maven GWT project
There are many variations on this problem but lets relate it to a concrete example. Say perhaps you have a series of domain objects that exist in a dependency jar, but you want to be able to serialize them and send them to the GWT client. How do you serialize an object that doesn't already exist in your core GWT project?
There are several steps required so lets take them in a logical order.
Step 1 : Ensure your objects are serializable
Two things required here:
There are several steps required so lets take them in a logical order.
Step 1 : Ensure your objects are serializable
Two things required here:
- Ensure your objects are implementing serializable.
- Ensure you have at least a no-argument private constructor.
If you don't do these things your objects cannot be serialized and sent to the client.
Step 2 : Add a GWT Module XML File
In order to indicate to the GWT Compiler that this dependency is a GWT Compilable you need to tell it so. Therefore you will need to add the <ModuleName>.gwt.xml file in the /src/main/resources folder of the external dependency.
<?xml version="1.0" encoding="UTF-8"?><module rename-to="DependencyApi"><inherits name="com.google.gwt.user.User"/><source path="domainobjects" /></module>
In the above example "domainobjects" is the root package that you want serialized. Similar to how a lot of GWT projects are constructed where you see a client and shared entry.
Step 3 : Export the dependency source
In order for the GWT-Compiler to compile to javascript it needs access to the source files, therefore as part of the dependencies build process you need to tell it to export the source. An entry similar to the one below in your pom file should do it.
Step 4 : Tell the GWT Compiler to add this dependency to the GWT Compile process<build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-source-plugin</artifactId><version>2.1.2</version><executions><execution><id>attach-sources</id><goals><goal>jar</goal></goals></execution></executions></plugin></plugins></build>
In the main GWT Project's pom file you need to tell it to now use this dependency and combine its source into the compilation process. This is achieved using the GWT-Maven-Plugin's configuration section.
<configuration><compileSourcesArtifacts><artifact><group id>:<artifactid></artifact></compileSourcesArtifacts></configuration>
Step 5: Include reference in the main Web Application Module.gwt.xml
Ensure you have a reference to the dependency in your main GWT Application config file.
<!-- Dependency API --><inherits name='com.acme.com.DependencyApi' />
Summary
Et Voila. That is it complete. A logical but not completely obvious solution to intermediate Maven users like myself. I would love to hear from the community how they might have solved this problem.
Labels:
Dependencies,
Domain Objects,
Maven,
POM
Location:
Seattle, WA, USA
Monday, July 25, 2011
Do you need a Java GWT developer?
This is an open post to anyone that may require a GWT / Java Developer. I am the author of this blog and am currently looking for work either in a telecommute role or based in my hometown of the sunny Seattle, Washington.
I have over 10 years development experience and have worked for a wide variety of institutions large and small. I enjoy working in Agile teams and adopting a test driven methodology. Having said that I am an expert at fitting into any team and have great references.
If you know of anyone that needs a GWT developer, please get in touch.
Regards
Gene
I have over 10 years development experience and have worked for a wide variety of institutions large and small. I enjoy working in Agile teams and adopting a test driven methodology. Having said that I am an expert at fitting into any team and have great references.
If you know of anyone that needs a GWT developer, please get in touch.
Regards
Gene
Friday, May 13, 2011
XML to POJO Mapper for GWT using a GDATA Example with Google Contacts (ContactEntry).
If your like me I dislike cowboy coding. You are hacking away at something to get the job done, but the nagging thought at the back of your head is telling you "You kow you shouldn't be doing this". The best path maybe unavailable because a lack of experience, or perhaps we are unaware of suitable boilerplate-removing framework. We've all been there time is in the essence, deadlines are pressing and your new TPS Reports Engine needs to be delivered yesterday. Well I found myself in such a quandry recently and found a tool which will solve a common problem for many GWT developers. So instead of waffling what actually is the problem?
Imagine an application that communicates with Google Contacts. Server-side you receive a an atom-rss feed representation of a contact in the form of a ContactEntry object. Google kindly provides you with GData POJOs which are already populated with the information you require. On the server this is beautiful, Google has done all the hard work and the POJO is populated with data. If you were using the wonderful Spring MVC you could render the contact information very easily. However you are a profound, if not magical developer that has the GWT Swiss army knife in their toolkit, and you want to send this POJO to the client. In the words of Mr. J. Carrey you reach the Alrighty Then brick wall of stoppage. The ContactEntry POJO is not serializable to the client. Or is it?
One giant caveat is that I maybe encountering a newbie problem and someone may have created an easy way to make GData objects serializable for sending over GWT-RPC, but at present the only way I have found to do it, is manually, i.e. boilerplatery. Create my own ContactEntry objects on the server and populate them. This obviously involves copious amounts of repetition. It can be done this way, and is the way I have done it in the past, before I knew better, but it isn't efficient.
Lets recap: We want a solution to send a GData ContactEntry object to the GWT client that we can use in a POJO, without becoming America's best plumber to create all the additional boilerplate code.
My proposed solution: Send the XML as a String to the client and use a fancy GWT plugin, Piriti, XPath to auto populate a client side POJO. Quick, efficient and maintainable. So how do we do this?
Caveat: If someone has a better way of doing this please let me know. I am all ears. This may not be the best solution and I would love to know how anyone else has tackled this issue.
Step 1: Extract XML
Lets assume you know how to get the ContactEntry from Google using their GData library but now you want to convert that into XML to transport to the GWT Client:
I am assuming you know how to write GWT applications and communicate back and forther between the server and client. There are man built in libraries to do this, GWT RPC, Request Factory, and may external third party modules; net.customware.gwt.dispatch, GWTP etc.
Step 3: Create POJO
The key here is reaally the library we are going to use. After looking at many examples I am using Piriti's library. It appears to be well used and has good documentation: http://code.google.com/p/piriti/
Step 4 : Map atom:title to an instance member
Let's start easy lets map the atom:title entry of the ContactEntry XML. First it is probably worth taking a look a the XML:
Step 5 : Load the Pojo
All we need to do now is load the POJO with information to do this see the below:
Step 6 : A more complex example please sir.
As you can see I have chosen the easiest node to map and as all articles which only go into the most basic of examples infuriate me, I shan't do the same here. Let's take a look at an example where we need to map to another POJO. Take the StructuredPostalAddress component of the ContactEntry class.
The XML in ContactEntry:
I would love to hear how other people are doing this as this seems like a good solution but I am sure there are many others.
Imagine an application that communicates with Google Contacts. Server-side you receive a an atom-rss feed representation of a contact in the form of a ContactEntry object. Google kindly provides you with GData POJOs which are already populated with the information you require. On the server this is beautiful, Google has done all the hard work and the POJO is populated with data. If you were using the wonderful Spring MVC you could render the contact information very easily. However you are a profound, if not magical developer that has the GWT Swiss army knife in their toolkit, and you want to send this POJO to the client. In the words of Mr. J. Carrey you reach the Alrighty Then brick wall of stoppage. The ContactEntry POJO is not serializable to the client. Or is it?
One giant caveat is that I maybe encountering a newbie problem and someone may have created an easy way to make GData objects serializable for sending over GWT-RPC, but at present the only way I have found to do it, is manually, i.e. boilerplatery. Create my own ContactEntry objects on the server and populate them. This obviously involves copious amounts of repetition. It can be done this way, and is the way I have done it in the past, before I knew better, but it isn't efficient.
Lets recap: We want a solution to send a GData ContactEntry object to the GWT client that we can use in a POJO, without becoming America's best plumber to create all the additional boilerplate code.
My proposed solution: Send the XML as a String to the client and use a fancy GWT plugin, Piriti, XPath to auto populate a client side POJO. Quick, efficient and maintainable. So how do we do this?
Caveat: If someone has a better way of doing this please let me know. I am all ears. This may not be the best solution and I would love to know how anyone else has tackled this issue.
Step 1: Extract XML
Lets assume you know how to get the ContactEntry from Google using their GData library but now you want to convert that into XML to transport to the GWT Client:
public String getContactEntryXml(ContactEntry entry) {
StringWriter sw = new StringWriter();
String entryXml = "";
try {
XmlWriter xw = new XmlWriter(sw);
entry.generate(xw, contactServiceFactory.getBasicContactsService().getExtensionProfile());
entryXml = sw.toString();
} catch (IOException e) {
e.printStackTrace();
}
return entryXml; // sw.toString();
}
Step 2: Transfer to ClientI am assuming you know how to write GWT applications and communicate back and forther between the server and client. There are man built in libraries to do this, GWT RPC, Request Factory, and may external third party modules; net.customware.gwt.dispatch, GWTP etc.
Step 3: Create POJO
The key here is reaally the library we are going to use. After looking at many examples I am using Piriti's library. It appears to be well used and has good documentation: http://code.google.com/p/piriti/
Piriti (Maori for "bridge") is a JSON and XML mapper for GWT based on annotations and deferred binding. The following code snippets show the basic idea behind Piriti.So create a POJO and add these lines to the top of your POJO class:
public class ContactEntrySoho {
public static interface ContactEntrySohoReader extends XmlReader { }
public static final ContactEntrySohoReader XML = GWT.create(ContactEntrySohoReader.class);
These lines are used when mapping the POJO members to their XML nodes.Step 4 : Map atom:title to an instance member
Let's start easy lets map the atom:title entry of the ContactEntry XML. First it is probably worth taking a look a the XML:
<atom:title type='text'>Alan UserA1</atom:title>Now lets look at how we would map this using XPath in the Pojo:
@Path("atom:title") private String title;
For a more in-depth view of XPath look online for various cheat-sheets and tutorials it is very powerful and very useful.Step 5 : Load the Pojo
All we need to do now is load the POJO with information to do this see the below:
@Override
public ContactEntrySoho parse(String xml) {
try {
Map<String, String> namespaces = new HashMap<String, String>();
namespaces.put("atom", "http://www.w3.org/2005/Atom");
namespaces.put("gContact", "http://schemas.google.com/contact/2008");
namespaces.put("batch", "http://schemas.google.com/gdata/batch");
namespaces.put("gd", "http://schemas.google.com/g/2005");
Document doc = new XmlParser().parse(xml, namespaces);
//Document doc = new XmlParser().parse(xml, NAMESPACES);
ContactEntrySoho sContactEntry = ContactEntrySoho.XML.read(doc);
return sContactEntry;
} catch (Exception e) {
return null;
}
}
The namespaces tell the parser what the tag mean and correspond to the root note elements of the ContactEntry XML:<atom:entry xmlns:atom='http://www.w3.org/2005/Atom' xmlns:gContact='http://schemas.google.com/contact/2008' xmlns:batch='http://schemas.google.com/gdata/batch' xmlns:gd='http://schemas.google.com/g/2005'>Remember those additions we added to the POJO we simply call those (XML.read) to parse the xml Document. Et Voila! You have your own POJO created with hatever components from the XML you require.
Step 6 : A more complex example please sir.
As you can see I have chosen the easiest node to map and as all articles which only go into the most basic of examples infuriate me, I shan't do the same here. Let's take a look at an example where we need to map to another POJO. Take the StructuredPostalAddress component of the ContactEntry class.
The XML in ContactEntry:
<gd:structuredPostalAddress primary='false' rel='http://schemas.google.com/g/2005#home'> <gd:formattedAddress>6217 Woodlawn Ave N, Seattle, WA. 98103</gd:formattedAddress> <gd:street>1234 Acme Ave N</gd:street> <gd:postcode>11111</gd:postcode> <gd:city>Seattle</gd:city> <gd:region>WA.</gd:region> </gd:structuredPostalAddress>The data in our parent ContactEntrySoho class:
@Path("//gd:structuredPostalAddress") private List<GDStructuredPostalAddress> gdStructuredPostalAddresses;
Wait what is GDStructuredPostalAddress? This is another POJO with the headers defined in Step 3.public class GDStructuredPostalAddress extends ABaseElement{
public interface GDStructuredPostalAddressXmlReader extends XmlReader<GDStructuredPostalAddress> {}
public static final GDStructuredPostalAddressXmlReader XML = GWT.create(GDStructuredPostalAddressXmlReader.class);
@Path("gd:formattedAddress") private String formattedAddress;
@Path("gd:street") private String street;
@Path("gd:postcode") private String postcode;
@Path("gd:city") private String city;
@Path("gd:region") private String region;
Et Voila! I found when using this that the POJO members sometimes had to be public otherwise they wouldn't populate but this problem was intermittent, so I am unsure whether this is an issue with Piriti's excellent XML->POJO Mapper or my inept code ;).I would love to hear how other people are doing this as this seems like a good solution but I am sure there are many others.
Subscribe to:
Posts (Atom)


