16

Here I am not creating a RESTful service indeed I have to call an external Restful service from my java code. Currently I am implementing this using Apache HttpClient. The response that I get from the web service is in XML format. I need to extract the data from XML and put them on Java objects. Rather than using SAX parser, I heard that we can use JAX-RS and JERSEY which automatically maps the xml tags to corresponding java objects.

I have being looking through but unable to find a source to get started. I did look at existing links Consuming RESTful APIs using Java RESTful call in Java

Any help is appreciated in moving forward.

Thanks!!

Community
  • 1
  • 1
Rishi
  • 1,331
  • 4
  • 13
  • 16
  • If you can call the service and get json back instead, the gson/Jackson Apis are easier than jaxb, in that you don't need annotations on the model objects – Kevin Aug 24 '11 at 15:11
  • Hi Kevin, I have an external REST service and I want to call it from web app. What is the best way to do it? REST Service returns JSON format as response. you said it's easy to handle JSON response. Can you please explain how? – Jignesh Mar 14 '13 at 09:55

5 Answers5

18

UPDATE

as follow up with this: Can I do this way?? if the xml being returned as 4 ..... If I am constructing a Person object, I believe this will choke up. Can I just bind only the xml elements that I want? if Yes how can I do that.

You could map this XML as follows:

input.xml

<?xml version="1.0" encoding="UTF-8"?>
<Persons>
    <NumberOfPersons>2</NumberOfPersons>
        <Person>
            <Name>Jane</Name>
            <Age>40</Age>
        </Person>
        <Person>
            <Name>John</Name>
            <Age>50</Age>
        </Person>
</Persons> 

Persons

package forum7177628;

import java.util.List;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name="Persons")
@XmlAccessorType(XmlAccessType.FIELD)
public class Persons {

    @XmlElement(name="Person")
    private List<Person> people;

}

Person

package forum7177628;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;

@XmlAccessorType(XmlAccessType.FIELD)
public class Person {

    @XmlElement(name="Name")
    private String name;

    @XmlElement(name="Age")
    private int age;

}

Demo

package forum7177628;

import java.io.File;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;

public class Demo {

    public static void main(String[] args) throws Exception {
        JAXBContext jc = JAXBContext.newInstance(Persons.class);

        Unmarshaller unmarshaller = jc.createUnmarshaller();
        Persons persons = (Persons) unmarshaller.unmarshal(new File("src/forum7177628/input.xml"));

        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.marshal(persons, System.out);
    }

}

Output

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Persons>
    <Person>
        <Name>Jane</Name>
        <Age>40</Age>
    </Person>
    <Person>
        <Name>John</Name>
        <Age>50</Age>
    </Person>
</Persons>

ORIGINAL ANSWER

Below is an example of calling a RESTful service using the Java SE APIs including JAXB:

String uri =
    "http://localhost:8080/CustomerService/rest/customers/1";
URL url = new URL(uri);
HttpURLConnection connection =
    (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setRequestProperty("Accept", "application/xml");

JAXBContext jc = JAXBContext.newInstance(Customer.class);
InputStream xml = connection.getInputStream();
Customer customer =
    (Customer) jc.createUnmarshaller().unmarshal(xml);

connection.disconnect();

For More Information:

bdoughan
  • 147,609
  • 23
  • 300
  • 400
  • 1
    as follow up with this: Can I do this way?? if the xml being returned as 4 ..... If I am constructing a Person object, I believe this will choke up. Can I just bind only the xml elements that I want? if Yes how can I do that. – Rishi Aug 24 '11 at 17:00
7

JAX-RS is the Java api for restful webservice. Jersey is an implementation from sun/oracle.

You need jaxb to convert your xml to a POJO. But it is not the always case that, converted object can be used without any transformation. If this is the scenario SAXParser is a nice solution.

Here is a nice tutorial on JAXB.

Kowser
  • 8,123
  • 7
  • 40
  • 63
4

You could consider using jaxb to bind your java objects to an xml document (marshalling).

http://www.oracle.com/technetwork/articles/javase/index-140168.html#xmp1

Snicolas
  • 37,840
  • 15
  • 114
  • 173
3

I use Apache CXF to build my RESTful services, which is another JAX-RS implementation (it also provides a JAX-WS implementation). I also use its "org.apache.cxf.jaxrs.client.WebClient" class in unit tests, which will completely manage all the marshalling and unmarshalling under the covers. You give it a URL and ask for an object of a particular type, and it does all the work. I don't know if Jersey has similar facilities.

David M. Karr
  • 14,317
  • 20
  • 94
  • 199
1

If you also need to convert that xml string that comes as a response to the service call, an x object you need can do it as follows:

 import java.io.BufferedReader;
 import java.io.IOException;
 import java.io.InputStreamReader;
 import java.io.StringReader;
 import java.net.HttpURLConnection;
 import java.net.MalformedURLException;
 import java.net.URL;
 import java.util.ArrayList;
 import java.util.List;

 import javax.xml.bind.JAXB;
 import javax.xml.bind.JAXBException;
 import javax.xml.parsers.DocumentBuilder;
 import javax.xml.parsers.DocumentBuilderFactory;
 import javax.xml.parsers.ParserConfigurationException;

 import org.w3c.dom.CharacterData;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 import org.w3c.dom.Node;
 import org.w3c.dom.NodeList;
 import org.xml.sax.InputSource;
 import org.xml.sax.SAXException;

 public class RestServiceClient {

// http://localhost:8080/RESTfulExample/json/product/get
public static void main(String[] args) throws ParserConfigurationException,
    SAXException {

try {

    URL url = new URL(
        "http://localhost:8080/CustomerDB/webresources/co.com.mazf.ciudad");
    HttpURLConnection conn = (HttpURLConnection) url.openConnection();
    conn.setRequestMethod("GET");
    conn.setRequestProperty("Accept", "application/xml");

    if (conn.getResponseCode() != 200) {
    throw new RuntimeException("Failed : HTTP error code : "
        + conn.getResponseCode());
    }

    BufferedReader br = new BufferedReader(new InputStreamReader(
        (conn.getInputStream())));

    String output;

    Ciudades ciudades = new Ciudades();
    System.out.println("Output from Server .... \n");
    while ((output = br.readLine()) != null) {
    System.out.println("12132312");
    System.err.println(output);

    DocumentBuilder db = DocumentBuilderFactory.newInstance()
        .newDocumentBuilder();
    InputSource is = new InputSource();
    is.setCharacterStream(new StringReader(output));

    Document doc = db.parse(is);
    NodeList nodes = ((org.w3c.dom.Document) doc)
        .getElementsByTagName("ciudad");

    for (int i = 0; i < nodes.getLength(); i++) {
        Ciudad ciudad = new Ciudad();
        Element element = (Element) nodes.item(i);

        NodeList name = element.getElementsByTagName("idCiudad");
        Element element2 = (Element) name.item(0);

        ciudad.setIdCiudad(Integer
            .valueOf(getCharacterDataFromElement(element2)));

        NodeList title = element.getElementsByTagName("nomCiudad");
        element2 = (Element) title.item(0);

        ciudad.setNombre(getCharacterDataFromElement(element2));

        ciudades.getPartnerAccount().add(ciudad);
    }
    }

    for (Ciudad ciudad1 : ciudades.getPartnerAccount()) {
    System.out.println(ciudad1.getIdCiudad());
    System.out.println(ciudad1.getNombre());
    }

    conn.disconnect();

} catch (MalformedURLException e) {
    e.printStackTrace();
} catch (IOException e) {
    e.printStackTrace();
}
}

public static String getCharacterDataFromElement(Element e) {
Node child = e.getFirstChild();
if (child instanceof CharacterData) {
    CharacterData cd = (CharacterData) child;
    return cd.getData();
}
return "";
}

}

Note that the xml structure that I expected in the example was as follows:

 <ciudad><idCiudad>1</idCiudad><nomCiudad>BOGOTA</nomCiudad></ciudad>