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 Geocode"

 
(8 intermediate revisions by the same user not shown)
Line 3: Line 3:
 
=JSON Binding: Google Geocode Example=
 
=JSON Binding: Google Geocode Example=
  
This example will demonstrate mapping a single object model to both XML and JSON using the same set of metadata.  Google Maps Geocoding API V2 will be used to provide the XML and JSON inputs for this example.
+
This example will demonstrate mapping a single object model to both XML and JSON using the same set of metadata.  [http://code.google.com/apis/maps/documentation/geocoding/v2/ Google Maps Geocoding API V2] will be used to provide the XML and JSON inputs for this example.
  
  
Line 10: Line 10:
 
Below is the link we will use to get the data as XML.  This is specified in the output parameter.  Note the '''output=xml''' in the URL:
 
Below is the link we will use to get the data as XML.  This is specified in the output parameter.  Note the '''output=xml''' in the URL:
  
http://maps.google.com/maps/geo?q=1600+Amphitheatre+Parkway,+Mountain+View,+CA&output=xml&sensor=false&key=YOUR_KEY_HERE
+
http://maps.google.com/maps/geo?q=1600+Amphitheatre+Parkway,+Mountain+View,+CA&output=xml&sensor=false
  
  
Line 30: Line 30:
 
   <address>1600 Amphitheatre Pkwy, Mountain View, CA 94043, USA
 
   <address>1600 Amphitheatre Pkwy, Mountain View, CA 94043, USA
 
   </address>
 
   </address>
   <AddressDetails Accuracy="8"
+
   <AddressDetails Accuracy="8" xmlns="urn:oasis:names:tc:ciq:xsdschema:xAL:2.0">
    xmlns="urn:oasis:names:tc:ciq:xsdschema:xAL:2.0">
+
 
     <Country>
 
     <Country>
 
     <CountryNameCode>US</CountryNameCode>
 
     <CountryNameCode>US</CountryNameCode>
Line 50: Line 49:
 
   </AddressDetails>
 
   </AddressDetails>
 
   <ExtendedData>
 
   <ExtendedData>
     <LatLonBox north="37.4227454" south="37.4200474" east="-122.0843863"
+
     <LatLonBox north="37.4227454" south="37.4200474" east="-122.0843863" west="-122.0870843" />
    west="-122.0870843" />
+
 
   </ExtendedData>
 
   </ExtendedData>
 
   <Point>
 
   <Point>
Line 67: Line 65:
 
Below is the link we will use to get the data as JSON.  This is specified in the output parameter.  Note the '''output=json''' in the URL:
 
Below is the link we will use to get the data as JSON.  This is specified in the output parameter.  Note the '''output=json''' in the URL:
  
http://maps.google.com/maps/geo?q=1600+Amphitheatre+Parkway,+Mountain+View,+CA&output=json&sensor=false&key=YOUR_KEY_HERE
+
http://maps.google.com/maps/geo?q=1600+Amphitheatre+Parkway,+Mountain+View,+CA&output=json&sensor=false
  
  
 
==JSON Result==
 
==JSON Result==
  
<div style="width:850px">
 
<source lang="text">
 
 
Below is an example of the XML returned from Google Maps:
 
Below is an example of the XML returned from Google Maps:
  
 +
<div style="width:850px">
 +
<source lang="text">
 
{
 
{
 
   "name": "1600 Amphitheatre Parkway, Mountain View, CA",
 
   "name": "1600 Amphitheatre Parkway, Mountain View, CA",
Line 86: Line 84:
 
     "address": "1600 Amphitheatre Pkwy, Mountain View, CA 94043, USA",
 
     "address": "1600 Amphitheatre Pkwy, Mountain View, CA 94043, USA",
 
     "AddressDetails": {
 
     "AddressDetails": {
  "Accuracy" : 8,
+
      "Accuracy" : 8,
  "Country" : {
+
      "Country" : {
      "AdministrativeArea" : {
+
        "AdministrativeArea" : {
        "AdministrativeAreaName" : "CA",
+
          "AdministrativeAreaName" : "CA",
        "Locality" : {
+
          "Locality" : {
 
             "LocalityName" : "Mountain View",
 
             "LocalityName" : "Mountain View",
 
             "PostalCode" : {
 
             "PostalCode" : {
Line 188: Line 186:
 
* A StAX parser is used to navigate to a local root that is comparable with the JSON structure.
 
* A StAX parser is used to navigate to a local root that is comparable with the JSON structure.
  
<div style="width:850px">
+
<div style="width:1000px">
 
<source lang="java">
 
<source lang="java">
 
package package org.example.geocode.json;
 
package package org.example.geocode.json;
Line 197: Line 195:
 
    
 
    
 
public class Demo {
 
public class Demo {
+
 
 +
    private final String xmlURL =
 +
        "http://maps.google.com/maps/geo?q=1600+Amphitheatre+Parkway,+Mountain+View,+CA&output=xml&sensor=false";
 +
 
 +
    private final String jsonURL =
 +
        "http://maps.google.com/maps/geo?q=1600+Amphitheatre+Parkway,+Mountain+View,+CA&output=json&sensor=false";
 +
 
 
     public static void main(String[] args) throws Exception {
 
     public static void main(String[] args) throws Exception {
 
         JAXBContext jc = JAXBContext.newInstance(Address.class);
 
         JAXBContext jc = JAXBContext.newInstance(Address.class);
Line 206: Line 210:
 
         // XML
 
         // XML
 
         XMLInputFactory xif = XMLInputFactory.newInstance();
 
         XMLInputFactory xif = XMLInputFactory.newInstance();
         StreamSource xml = new StreamSource("http://maps.google.com/maps/geo?q=1600+Amphitheatre+Parkway,+Mountain+View,+CA&output=xml&sensor=false&key=YOUR_KEY_HERE");
+
         StreamSource xml = new StreamSource(xmlURL);
 
         XMLStreamReader xsr = xif.createXMLStreamReader(xml);
 
         XMLStreamReader xsr = xif.createXMLStreamReader(xml);
 
         xsr.nextTag(); // Advance to kml tag
 
         xsr.nextTag(); // Advance to kml tag
Line 216: Line 220:
 
         unmarshaller.setProperty("eclipselink.media-type", "application/json");
 
         unmarshaller.setProperty("eclipselink.media-type", "application/json");
 
         unmarshaller.setProperty("eclipselink.json.include-root", false);
 
         unmarshaller.setProperty("eclipselink.json.include-root", false);
         StreamSource json = new StreamSource("http://maps.google.com/maps/geo?q=1600+Amphitheatre+Parkway,+Mountain+View,+CA&output=json&sensor=false&key=YOUR_KEY_HERE");
+
         StreamSource json = new StreamSource(jsonURL);
 
         JAXBElement<Address> addressFromJSON = unmarshaller.unmarshal(json, Address.class);
 
         JAXBElement<Address> addressFromJSON = unmarshaller.unmarshal(json, Address.class);
 
         marshaller.setProperty("eclipselink.media-type", "application/json");
 
         marshaller.setProperty("eclipselink.media-type", "application/json");
Line 223: Line 227:
 
     }
 
     }
 
   
 
   
 +
}
 +
</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>
 +
 +
 +
'''XML Output'''
 +
<div style="width:1000px">
 +
<source lang="xml">
 +
<?xml version="1.0" encoding="UTF-8"?>
 +
<Response xmlns="http://earth.google.com/kml/2.0" xmlns:ns="urn:oasis:names:tc:ciq:xsdschema:xAL:2.0">
 +
  <Placemark>
 +
      <ns:AddressDetails>
 +
        <ns:Country>
 +
            <ns:CountryNameCode>US</ns:CountryNameCode>
 +
            <ns:AdministrativeArea>
 +
              <ns:AdministrativeAreaName>CA</ns:AdministrativeAreaName>
 +
              <ns:Locality>
 +
                  <ns:LocalityName>Mountain View</ns:LocalityName>
 +
                  <ns:Thoroughfare>
 +
                    <ns:ThoroughfareName>1600 Amphitheatre Pkwy</ns:ThoroughfareName>
 +
                  </ns:Thoroughfare>
 +
                  <ns:PostalCode>
 +
                    <ns:PostalCodeNumber>94043</ns:PostalCodeNumber>
 +
                  </ns:PostalCode>
 +
              </ns:Locality>
 +
            </ns:AdministrativeArea>
 +
        </ns:Country>
 +
      </ns:AddressDetails>
 +
  </Placemark>
 +
</Response>
 +
</source>
 +
</div>
 +
 +
 +
'''JSON Output'''
 +
<div style="width:1000px">
 +
<source lang="text">
 +
{
 +
  "Placemark" : {
 +
      "AddressDetails" : {
 +
        "Country" : {
 +
            "CountryNameCode" : "US",
 +
            "AdministrativeArea" : {
 +
              "AdministrativeAreaName" : "CA",
 +
              "Locality" : {
 +
                  "LocalityName" : "Mountain View",
 +
                  "Thoroughfare" : {
 +
                    "ThoroughfareName" : "1600 Amphitheatre Pkwy"
 +
                  },
 +
                  "PostalCode" : {
 +
                    "PostalCodeNumber" : "94043"
 +
                  }
 +
              }
 +
            }
 +
        }
 +
      }
 +
  }
 
}
 
}
 
</source>
 
</source>
 
</div>
 
</div>

Latest revision as of 13:46, 18 June 2012

JSON Binding: Google Geocode Example

This example will demonstrate mapping a single object model to both XML and JSON using the same set of metadata. Google Maps Geocoding API V2 will be used to provide the XML and JSON inputs for this example.


XML Input

Below is the link we will use to get the data as XML. This is specified in the output parameter. Note the output=xml in the URL:

http://maps.google.com/maps/geo?q=1600+Amphitheatre+Parkway,+Mountain+View,+CA&output=xml&sensor=false


XML Result

Below is an example of the XML returned from Google Maps:

<?xml version="1.0" encoding="UTF-8" ?>
<kml xmlns="http://earth.google.com/kml/2.0">
 <Response>
  <name>1600 Amphitheatre Parkway, Mountain View, CA</name>
  <Status>
   <code>200</code>
   <request>geocode</request>
  </Status>
  <Placemark id="p1">
   <address>1600 Amphitheatre Pkwy, Mountain View, CA 94043, USA
   </address>
   <AddressDetails Accuracy="8" xmlns="urn:oasis:names:tc:ciq:xsdschema:xAL:2.0">
    <Country>
     <CountryNameCode>US</CountryNameCode>
     <CountryName>USA</CountryName>
     <AdministrativeArea>
      <AdministrativeAreaName>CA</AdministrativeAreaName>
      <Locality>
       <LocalityName>Mountain View</LocalityName>
       <Thoroughfare>
        <ThoroughfareName>1600 Amphitheatre Pkwy</ThoroughfareName>
       </Thoroughfare>
       <PostalCode>
        <PostalCodeNumber>94043</PostalCodeNumber>
       </PostalCode>
      </Locality>
     </AdministrativeArea>
    </Country>
   </AddressDetails>
   <ExtendedData>
    <LatLonBox north="37.4227454" south="37.4200474" east="-122.0843863" west="-122.0870843" />
   </ExtendedData>
   <Point>
    <coordinates>-122.0857353,37.4213964,0</coordinates>
   </Point>
  </Placemark>
 </Response>
</kml>


JSON Input

Below is the link we will use to get the data as JSON. This is specified in the output parameter. Note the output=json in the URL:

http://maps.google.com/maps/geo?q=1600+Amphitheatre+Parkway,+Mountain+View,+CA&output=json&sensor=false


JSON Result

Below is an example of the XML returned from Google Maps:

{
  "name": "1600 Amphitheatre Parkway, Mountain View, CA",
  "Status": {
    "code": 200,
    "request": "geocode"
  },
  "Placemark": [ {
    "id": "p1",
    "address": "1600 Amphitheatre Pkwy, Mountain View, CA 94043, USA",
    "AddressDetails": {
      "Accuracy" : 8,
      "Country" : {
        "AdministrativeArea" : {
          "AdministrativeAreaName" : "CA",
          "Locality" : {
            "LocalityName" : "Mountain View",
            "PostalCode" : {
               "PostalCodeNumber" : "94043"
            },
            "Thoroughfare" : {
               "ThoroughfareName" : "1600 Amphitheatre Pkwy"
            }
         }
      },
      "CountryName" : "USA",
      "CountryNameCode" : "US"
   }
},
    "ExtendedData": {
      "LatLonBox": {
        "north": 37.4227454,
        "south": 37.4200474,
        "east": -122.0843863,
        "west": -122.0870843
      }
    },
    "Point": {
      "coordinates": [ -122.0857353, 37.4213964, 0 ]
    }
  } ]
}


Domain Model

The following domain model will be used for this example. Note that the exact same class with the exact same metadata will be used for both the XML and JSON bindings.


Address

package org.example.geocode.json;
 
import javax.xml.bind.annotation.XmlType;
import org.eclipse.persistence.oxm.annotations.XmlPath;
 
@XmlType(propOrder={"country", "state", "city", "street", "postalCode"})
public class Address {
 
  @XmlPath("Placemark/ns:AddressDetails/ns:Country/ns:AdministrativeArea/ns:Locality/ns:Thoroughfare/ns:ThoroughfareName/text()")
  private String street;
 
  @XmlPath("Placemark/ns:AddressDetails/ns:Country/ns:AdministrativeArea/ns:Locality/ns:LocalityName/text()")
  private String city;
 
  @XmlPath("Placemark/ns:AddressDetails/ns:Country/ns:AdministrativeArea/ns:AdministrativeAreaName/text()")
  private String state;
 
  @XmlPath("Placemark/ns:AddressDetails/ns:Country/ns:CountryNameCode/text()")
  private String country;
 
  @XmlPath("Placemark/ns:AddressDetails/ns:Country/ns:AdministrativeArea/ns:Locality/ns:PostalCode/ns:PostalCodeNumber/text()")
  private String postalCode;
 
}


package-info

The @XmlSchema annotation is used to configure the namespace information. These namespaces will be ignored when the JSON binding is performed.

@XmlSchema(
    namespace="http://earth.google.com/kml/2.0",
    elementFormDefault=XmlNsForm.QUALIFIED,
    xmlns={
        @XmlNs(prefix="ns", 
            namespaceURI="urn:oasis:names:tc:ciq:xsdschema:xAL:2.0")
    }
)
@XmlAccessorType(XmlAccessType.FIELD)
package org.example.geocode.json;
 
import javax.xml.bind.annotation.XmlAccessorType;


Demo

The following code will be used to convert the XML and JSON messages to/from objects. Some things to note about this code:

  • Only one JAXBContext is created, this means only one set of initialized metadata.
  • The same instances of Marshaller and Unmarshaller are used for both the XML and JSON binding. JSON binding was enabled by setting the eclipselink.media.type property to application/json.
  • We also set the eclipselink.json.include-root property to false to indicate there is no root node.
  • A StAX parser is used to navigate to a local root that is comparable with the JSON structure.
package package org.example.geocode.json;
 
import javax.xml.bind.*;
import javax.xml.stream.*;
import javax.xml.transform.stream.StreamSource;
 
public class Demo {
 
    private final String xmlURL = 
        "http://maps.google.com/maps/geo?q=1600+Amphitheatre+Parkway,+Mountain+View,+CA&output=xml&sensor=false";
 
    private final String jsonURL = 
        "http://maps.google.com/maps/geo?q=1600+Amphitheatre+Parkway,+Mountain+View,+CA&output=json&sensor=false";
 
    public static void main(String[] args) throws Exception {
        JAXBContext jc = JAXBContext.newInstance(Address.class);
        Unmarshaller unmarshaller = jc.createUnmarshaller();
        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
 
        // XML
        XMLInputFactory xif = XMLInputFactory.newInstance();
        StreamSource xml = new StreamSource(xmlURL);
        XMLStreamReader xsr = xif.createXMLStreamReader(xml);
        xsr.nextTag(); // Advance to kml tag
        xsr.nextTag(); // Advance to Response tag
        JAXBElement<Address> addressFromXML = unmarshaller.unmarshal(xsr, Address.class);
        marshaller.marshal(addressFromXML, System.out);
 
        // JSON
        unmarshaller.setProperty("eclipselink.media-type", "application/json");
        unmarshaller.setProperty("eclipselink.json.include-root", false);
        StreamSource json = new StreamSource(jsonURL);
        JAXBElement<Address> addressFromJSON = unmarshaller.unmarshal(json, Address.class);
        marshaller.setProperty("eclipselink.media-type", "application/json");
        marshaller.setProperty("eclipselink.json.include-root", false);
        marshaller.marshal(addressFromJSON, 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


XML Output

<?xml version="1.0" encoding="UTF-8"?>
<Response xmlns="http://earth.google.com/kml/2.0" xmlns:ns="urn:oasis:names:tc:ciq:xsdschema:xAL:2.0">
   <Placemark>
      <ns:AddressDetails>
         <ns:Country>
            <ns:CountryNameCode>US</ns:CountryNameCode>
            <ns:AdministrativeArea>
               <ns:AdministrativeAreaName>CA</ns:AdministrativeAreaName>
               <ns:Locality>
                  <ns:LocalityName>Mountain View</ns:LocalityName>
                  <ns:Thoroughfare>
                     <ns:ThoroughfareName>1600 Amphitheatre Pkwy</ns:ThoroughfareName>
                  </ns:Thoroughfare>
                  <ns:PostalCode>
                     <ns:PostalCodeNumber>94043</ns:PostalCodeNumber>
                  </ns:PostalCode>
               </ns:Locality>
            </ns:AdministrativeArea>
         </ns:Country>
      </ns:AddressDetails>
   </Placemark>
</Response>


JSON Output

{
   "Placemark" : {
      "AddressDetails" : {
         "Country" : {
            "CountryNameCode" : "US",
            "AdministrativeArea" : {
               "AdministrativeAreaName" : "CA",
               "Locality" : {
                  "LocalityName" : "Mountain View",
                  "Thoroughfare" : {
                     "ThoroughfareName" : "1600 Amphitheatre Pkwy"
                  },
                  "PostalCode" : {
                     "PostalCodeNumber" : "94043"
                  }
               }
            }
         }
      }
   }
}

Copyright © Eclipse Foundation, Inc. All Rights Reserved.