Question

I'm a bit new to use JSON format manipulation and not very experimented in JAXB either. What I try to do is building a small client to launch search on Twitter. My starting framework is JBoss RESTEasy (JAX-RS implementation) that provides an elegant way to consume Rest services JSON services by mapping JSON to JAXB thru Jettison framework (it works also in the other way if you want to provide REST service and produce JSON from JAXB).

So I launch a simple request to Twitter :

http://search.twitter.com/search.json?q=java

And the answer comes in the following JSON format

{
"results":
[
  {"from_user_id_str":"67875385",
  "profile_image_url":"http://a2.twimg.com/axt_normal.png",
  "created_at":"Sun, 28 Nov 2010 22:38:39 +0000",
  "from_user":"extant",
  "id_str":"9013327095136256",
  "metadata":{"result_type":"recent"},
  "to_user_id":null,
  "text": "New blog post: No fancy swap in java",
  "id":9013327095136256,
  "from_user_id":67875385,
  "geo":null,
  "iso_language_code":"en",
  "to_user_id_str":null,
  "source":"wordpress"
  }, 
  <more tweets...>
],
"max_id":9013327095136256,
"since_id":0,
"refresh_url":"?since_id=9013327095136256&q=java",
"next_page":"?page=2&max_id=9013327095136256&q=java",
"results_per_page":15,
"page":1,"completed_in":0.020154,
"since_id_str":"0",
"max_id_str":"9013327095136256",
"query":"java"
} 

So I created two classes to map this answer

@BadgerFish
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class SearchResults { 
 @XmlElement
 public List<Tweet> results;
 @XmlElement(name = "max_id")
 public long maxId;
 @XmlElement(name = "since_id")
 public long sinceId;
}

and

@BadgerFish
@XmlRootElement(name="tweet")
public class Tweet {

 @XmlElement(name = "id")
 public long id;

 @XmlElement(name = "text")
 public String text;

 @XmlElement(name = "created_at")
 public Date createdAt;

 @XmlElement(name = "from_user")
 public String fromUser;

 @XmlElement(name = "profile_image_url")
 public String profileImageUrl;

 @XmlElement(name = "to_user_id")
 public Long toUserId;

 @XmlElement(name = "from_user_id")
 public long fromUserId;

 @XmlElement(name = "language_code")
 public String languageCode;

 @XmlElement(name = "source")
 public String source;

}

My Twitter RESTEasy client is a simple interface

public interface TwitterResource {
 @Path("/search.json")
 @Consumes("application/*+json")
 @GET
 SearchResults search(@QueryParam("q")String query); 
}

Which is exploited with the following RESTEasy code :

...
TwitterResource tr = ProxyFactory.create(TwitterResource.class, "http://search.twitter.com");
SearchResults sr = tr.search("java");
...

This code give the following Exception :

Exception in thread "main" org.jboss.resteasy.plugins.providers.jaxb.JAXBUnmarshalException: javax.xml.bind.JAXBException
 - with linked exception:
[org.codehaus.jettison.json.JSONException: JSONObject["results"] is not a JSONObject.]
 at org.jboss.resteasy.plugins.providers.jaxb.AbstractJAXBProvider.readFrom(AbstractJAXBProvider.java:86)

I assume it comes from a wrong JAXB mapping on SearchResults class but can't figure how to correct it (and it's complicated with the JSON translation to XML). Any clue to correct it would be great.

Thanks in advance

Was it helpful?

Solution

Ok, no solution found with Jettison (I'm convinced it's a bug) and JAXB mapping for JSON. But as RESTEasy support also the Jackson Framework, I switched to Jackson and everything thing is ok now.

In fact I find more clean to avoid this JSON to JAXB translation my first solution was using.

Thanks myself ;-)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top