Skip to main content

Notice: this Wiki will be going read only early in 2024 and edits will no longer be possible. Please see: https://gitlab.eclipse.org/eclipsefdn/helpdesk/-/wikis/Wiki-shutdown-plan for the plan.

Jump to: navigation, search

Difference between revisions of "EclipseLink/Examples/MOXy/JSON Twitter"

 
(9 intermediate revisions by the same user not shown)
Line 1: Line 1:
 
<div style="margin:5px;float:right;border:1px solid #000000;padding:5px">__TOC__</div>  
 
<div style="margin:5px;float:right;border:1px solid #000000;padding:5px">__TOC__</div>  
  
=JSON Binding and Twitter=
+
=JSON Binding: Twitter Example=
 +
 
 +
This example will demonstrate using MOXy to read and write JSON.  In this example our JSON corresponds to the results of a query to get recent tweets about JAXB.  We will use the [https://dev.twitter.com/docs/api/1/get/search Twitter Search API] for this.
  
In this example our JSON corresponds to the results of a query to get recent tweets about JAXB.  We will use the [https://dev.twitter.com/docs/api/1/get/search Twitter Search API] for this.
 
  
 
==Twitter Query==
 
==Twitter Query==
Line 10: Line 11:
  
 
http://search.twitter.com/search.json?q=jaxb
 
http://search.twitter.com/search.json?q=jaxb
 +
  
 
==JSON Result==
 
==JSON Result==
Line 65: Line 67:
 
</source>
 
</source>
 
</div>
 
</div>
 +
 +
 +
==Domain Model==
 +
 +
MOXy leverages the same annotations used to map objects to/from XML for its JSON binding.
 +
 +
 +
'''SearchResults'''
 +
<div style="width:850px">
 +
<source lang="java">
 +
package org.example;
 +
 +
import java.util.List;
 +
 +
import javax.xml.bind.annotation.XmlElement;
 +
 +
public class SearchResults {
 +
 +
    private String query;
 +
    private float completedIn;
 +
    List<Result> results;
 +
 +
    public String getQuery() {
 +
        return query;
 +
    }
 +
 +
    public void setQuery(String query) {
 +
        this.query = query;
 +
    }
 +
 +
    @XmlElement(name="completed_in")
 +
    public float getCompletedIn() {
 +
        return completedIn;
 +
    }
 +
 +
    public void setCompletedIn(float completedIn) {
 +
        this.completedIn = completedIn;
 +
    }
 +
 +
    public List<Result> getResults() {
 +
        return results;
 +
    }
 +
 +
    public void setResults(List<Result> results) {
 +
        this.results = results;
 +
    }
 +
 +
}
 +
</source>
 +
</div>
 +
 +
 +
'''Result'''
 +
<div style="width:850px">
 +
<source lang="java">
 +
package blog.json.twitter;
 +
 +
import java.util.Date;
 +
 +
import javax.xml.bind.annotation.XmlElement;
 +
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
 +
 +
public class Result {
 +
 +
    private Date createdAt;
 +
    private String fromUser;
 +
    private String text;
 +
 +
    @XmlElement(name="created_at")
 +
    @XmlJavaTypeAdapter(DateAdapter.class)
 +
    public Date getCreatedAt() {
 +
        return createdAt;
 +
    }
 +
 +
    public void setCreatedAt(Date createdAt) {
 +
        this.createdAt = createdAt;
 +
    }
 +
 +
    @XmlElement(name="from_user")
 +
    public String getFromUser() {
 +
        return fromUser;
 +
    }
 +
 +
    public void setFromUser(String fromUser) {
 +
        this.fromUser = fromUser;
 +
    }
 +
 +
    public String getText() {
 +
        return text;
 +
    }
 +
 +
    public void setText(String text) {
 +
        this.text = text;
 +
    }
 +
 +
}
 +
</source>
 +
</div>
 +
 +
 +
'''DateAdapter'''
 +
<div style="width:850px">
 +
<source lang="java">
 +
package org.example;
 +
 +
import java.text.SimpleDateFormat;
 +
import java.util.Date;
 +
 +
import javax.xml.bind.annotation.adapters.XmlAdapter;
 +
 +
public class DateAdapter extends XmlAdapter<String, Date> {
 +
 +
    private SimpleDateFormat dateFormat = new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss Z");
 +
 +
    @Override
 +
    public String marshal(Date date) throws Exception {
 +
        return dateFormat.format(date);
 +
    }
 +
 +
    @Override
 +
    public Date unmarshal(String string) throws Exception {
 +
        return dateFormat.parse(string);
 +
    }
 +
 +
}
 +
</source>
 +
</div>
 +
  
 
==Demo==
 
==Demo==
Line 103: Line 233:
 
    
 
    
 
}
 
}
 +
</source>
 +
</div>
 +
 +
 +
In order to use this feature, you must use MOXy as your JAXB provider.  To enable MOXy, simply add a file named '''jaxb.properties''' in the same package as your domain classes with the following entry:
 +
 +
<div style="width:850px">
 +
<source lang="text">
 +
javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory
 +
</source>
 +
</div>
 +
 +
 +
==Output==
 +
 +
Below is an excerpt of the output from the Demo:
 +
 +
<div style="width:850px">
 +
<source lang="text">
 +
{
 +
  "completed_in" : 0.153,
 +
  "query" : "jaxb",
 +
  "results" : [ {
 +
      "created_at" : "Fri, 12 Aug 2011 01:14:57 +0000",
 +
      "from_user" : "stackfeed",
 +
      "text" : "How do you customise the XML output of Jersey JAXB serialization?"
 +
  }, {
 +
      "created_at" : "Fri, 12 Aug 2011 09:00:26 +0000",
 +
      "from_user" : "44aki110",
 +
      "text" : "How do you pronounce JAXB?: You know, URL is earl..."
 +
  }, {
 +
  ...
 +
  }, {
 +
      "created_at" : "Wed, 28 Mar 2012 15:56:55 -0400",
 +
      "from_user" : "bsmith",
 +
      "text" : "You can now use EclipseLink JAXB (MOXy) with JSON :)"
 +
  } ]
 
</source>
 
</source>
 
</div>
 
</div>

Latest revision as of 13:54, 18 June 2012

JSON Binding: Twitter Example

This example will demonstrate using MOXy to read and write JSON. In this example our JSON corresponds to the results of a query to get recent tweets about JAXB. We will use the Twitter Search API for this.


Twitter Query

Below is the URL corresponding to the search. We are looking for posts containing the word "jaxb", and want the result returned as JSON:

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


JSON Result

Below is an example excerpt of the JSON returned from Twitter:

{
   "completed_in":0.153,
   "max_id":101941099769245696,
   "max_id_str":"101941099769245696",
   "next_page":"?page=2&max_id=101941099769245696&q=jaxb",
   "page":1,
   "query":"jaxb",
   "refresh_url":"?since_id=101941099769245696&q=jaxb",
   "results":[
      {
         "created_at":"Fri, 12 Aug 2011 09:00:26 +0000",
         "from_user":"44aki110",
         "from_user_id":92669210,
         "from_user_id_str":"92669210",
         "geo":null,
         "id":101941099769245696,
         "id_str":"101941099769245696",
         "iso_language_code":"ja",
         "metadata":{
            "result_type":"recent"
         },
         "profile_image_url":"http://a2.twimg.com/profile_images/1301749249/44aki110_normal.jpg",
         "source":"<a href="http://www.soicha.com" rel="nofollow">SOICHA</a>",
         "text":"How do you pronounce JAXB?: You know, URL is earl...",
         "to_user_id":null,
         "to_user_id_str":null
      },
      {
         "created_at":"Fri, 12 Aug 2011 01:14:57 +0000",
         "from_user":"stackfeed",
         "from_user_id":212341639,
         "from_user_id_str":"212341639",
         "geo":null,
         "id":101823955765170176,
         "id_str":"101823955765170176",
         "iso_language_code":"en",
         "metadata":{
            "result_type":"recent"
         },
         "profile_image_url":"http://a2.twimg.com/sticky/default_profile_images/default.png",
         "source":"<a href="http://twitterfeed.com" rel="nofollow">twitterfeed</a>",
         "text":"How do you customise the XML output of Jersey JAXB serialization?",
         "to_user_id":null,
         "to_user_id_str":null
      },
      ...


Domain Model

MOXy leverages the same annotations used to map objects to/from XML for its JSON binding.


SearchResults

package org.example;
 
import java.util.List;
 
import javax.xml.bind.annotation.XmlElement;
 
public class SearchResults {
 
    private String query;
    private float completedIn;
    List<Result> results;
 
    public String getQuery() {
        return query;
    }
 
    public void setQuery(String query) {
        this.query = query;
    }
 
    @XmlElement(name="completed_in")
    public float getCompletedIn() {
        return completedIn;
    }
 
    public void setCompletedIn(float completedIn) {
        this.completedIn = completedIn;
    }
 
    public List<Result> getResults() {
        return results;
    }
 
    public void setResults(List<Result> results) {
        this.results = results;
    }
 
}


Result

package blog.json.twitter;
 
import java.util.Date;
 
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
 
public class Result {
 
    private Date createdAt;
    private String fromUser;
    private String text;
 
    @XmlElement(name="created_at")
    @XmlJavaTypeAdapter(DateAdapter.class)
    public Date getCreatedAt() {
        return createdAt;
    }
 
    public void setCreatedAt(Date createdAt) {
        this.createdAt = createdAt;
    }
 
    @XmlElement(name="from_user")
    public String getFromUser() {
        return fromUser;
    }
 
    public void setFromUser(String fromUser) {
        this.fromUser = fromUser;
    }
 
    public String getText() {
        return text;
    }
 
    public void setText(String text) {
        this.text = text;
    }
 
}


DateAdapter

package org.example;
 
import java.text.SimpleDateFormat;
import java.util.Date;
 
import javax.xml.bind.annotation.adapters.XmlAdapter;
 
public class DateAdapter extends XmlAdapter<String, Date> {
 
    private SimpleDateFormat dateFormat = new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss Z");
 
    @Override
    public String marshal(Date date) throws Exception {
        return dateFormat.format(date);
    }
 
    @Override
    public Date unmarshal(String string) throws Exception {
        return dateFormat.parse(string);
    }
 
}


Demo

The standard JAXB APIs are used the process the JSON message. Only two properties need to be set: eclipselink.media.type to specify application/json, and eclipselink.json.include-root to indicate there is no root node. These properties are set on the Marshaller and Unmarshaller. Since the JSON message does not contain a root node that can be used to determine the corresponding object type, we will leverage one of the Unmarshaller methods that lets us specify it.

package org.example;
 
import java.util.Date; 
import javax.xml.bind.*;
import javax.xml.transform.stream.StreamSource;
 
public class Demo {
 
    public static void main(String[] args) throws Exception {
        JAXBContext jc = JAXBContext.newInstance(SearchResults.class);
 
        Unmarshaller unmarshaller = jc.createUnmarshaller();
        unmarshaller.setProperty("eclipselink.media-type", "application/json");
        unmarshaller.setProperty("eclipselink.json.include-root", false);
        StreamSource source = new StreamSource("http://search.twitter.com/search.json?q=jaxb");
        JAXBElement<SearchResults> jaxbElement = unmarshaller.unmarshal(source, SearchResults.class);
 
        Result result = new Result();
        result.setCreatedAt(new Date());
        result.setFromUser("bsmith");
        result.setText("You can now use EclipseLink JAXB (MOXy) with JSON :)");
        jaxbElement.getValue().getResults().add(result);
 
        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.setProperty("eclipselink.media-type", "application/json");
        marshaller.setProperty("eclipselink.json.include-root", false);
        marshaller.marshal(jaxbElement, System.out);
    }
 
}


In order to use this feature, you must use MOXy as your JAXB provider. To enable MOXy, simply add a file named jaxb.properties in the same package as your domain classes with the following entry:

javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory


Output

Below is an excerpt of the output from the Demo:

{
   "completed_in" : 0.153,
   "query" : "jaxb",
   "results" : [ {
      "created_at" : "Fri, 12 Aug 2011 01:14:57 +0000",
      "from_user" : "stackfeed",
      "text" : "How do you customise the XML output of Jersey JAXB serialization?"
   }, {
      "created_at" : "Fri, 12 Aug 2011 09:00:26 +0000",
      "from_user" : "44aki110",
      "text" : "How do you pronounce JAXB?: You know, URL is earl..."
   }, {
   ...
   }, {
      "created_at" : "Wed, 28 Mar 2012 15:56:55 -0400",
      "from_user" : "bsmith",
      "text" : "You can now use EclipseLink JAXB (MOXy) with JSON :)"
   } ]

Copyright © Eclipse Foundation, Inc. All Rights Reserved.