Tutorial 02 - Basic Connection + XML Handling

Basic Connection + XML handling

The example code is contained in ElandingsClient2.zip

We can now get XML data from the web service. Now we need to be able to work with the XML data.

There are several online resources available to you to learn about eLandings XML. We recommend that you begin with:

eLandings System Interface Guide and its child pages.

In addition, the elandings Team presented a workshop on how to work with XML data early 2010. You can find information at:

2010 eLandings XML Interface Workshop

You can find some code examples for Java and .NET listed on this page.

For example on the Java tutorial found at:
Java Tutorial - Processing XML Using Software Libraries
Step-by-Step instructions are provided on how to work with XML. Accompanying code examples are includes as attachments to the page.

Let's extend the ElandingsClient project a little bit to include some very primitive XML handling.
The first step is to get the XML .XSD files that define the XML structure. These can be gotten at:
XML Resources and Documentation

Use the Test Schema, as I am working with the test webservices.
Schema
Download

  • Data Types and save it to datatypes.xsd
  • Data Elements and save it to dataelements.xsd
  • Landing Report and save it to landingreport.xsd
    Placed these xsd files in the root of my netbeans project.

For additional information on JAXB - see:
http://netbeans.org/kb/docs/websvc/jaxb.html

Go back to NetBeans
Right click on the Source Packages>New>Other

Click on

  1. XML
  2. JAXB Binding
  3. Next

Next, give it a name like landingreport. Then point it at the landingreport.xsd file that you placed in your Netbeans ElandingsClient project root. Then click Finished.

Netbeans will generate a number of java classes in Generated Sources (jaxb) folder.

We want to take the XML string that we got back from the web service call and insert it into the generated java object that relates to it. Let¿s do that now.

Open the ELandingsClient.java file
Run the file again.
Notice that the web service returned an XML structure of type processor_user_info.
If we look in the Generated Sources (jaxb) folder, we can find ProcessorUserInfo.java
We will attempt to put the XML processor_user_info into a java instance of ProcessorUserInfo.java

In the method connectToWebService() add:

ProcessorUserInfo user = new ProcessorUserInfo();

So it looks like:

public void connectToWebService() {
        try {
            String xml = svc.getUserInfo("amarx", "A_marx", "2.3");
            System.out.println(xml);
            ProcessorUserInfo user = new ProcessorUserInfo();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

We now have the String xml and the ProcessorUserInfo user. Next we need to put the xml into user.
To do this we need a JAXB unmarshaller. An unmarshaller can parse XML and convert it into a XSD generated Java object. Add the following code to the connectToWebService()

You can use this approach:

javax.xml.bind.JAXBContext jaxbCtx = javax.xml.bind.JAXBContext.newInstance(user.getClass().getPackage().getName());
javax.xml.bind.Unmarshaller unmarshaller = jaxbCtx.createUnmarshaller();

Or you could use this approach

javax.xml.bind.JAXBContext jaxbCtx = javax.xml.bind.JAXBContext.newInstance("generated");
javax.xml.bind.Unmarshaller unmarshaller = jaxbCtx.createUnmarshaller();

I will use the second approach as it is more general.

Next we need to give the unmarshaller the XML string as a stream object and have the unmarshaller populate our ProcessorUserInfo object with the XML data.
Add the following to the connectToWebService():

StreamSource s = new StreamSource(new StringReader(xml));
user = (ProcessorUserInfo)unmarshaller.unmarshal(s);

The ProcessorUserInfo user object should now be populated with all of the data we saw in the XML string.
To test this we, will display the user name associated with the user object. To connectToWebService(), add:

System.out.println("User Name "+user.getProcessorUser().get(0).getUserName().getValue());

The connectToWebService method should look something like this:

public void connectToWebService() {
        try {
            String xml = svc.getUserInfo("amarx", "A_marx", "2.3");
            System.out.println(xml);
            ProcessorUserInfo user = new ProcessorUserInfo();
            javax.xml.bind.JAXBContext jaxbCtx = javax.xml.bind.JAXBContext.newInstance("generated");
            javax.xml.bind.Unmarshaller unmarshaller = jaxbCtx.createUnmarshaller();
            StreamSource s = new StreamSource(new StringReader(xml));
            user = (ProcessorUserInfo)unmarshaller.unmarshal(s);

            System.out.println("User Name "+user.getProcessorUser().get(0).getUserName().getValue());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

Run the application
At the end of the application output we see: User Name Audrey Marx

We now have a ProcessorUserInfo object that is populated with data from the eLandings database. This is the same procedure used to work with all the XML data object sent by the web service methods. From here, we can manipulate the object, store it locally or convert it back to XML.

We might want to change a value locally before putting it into a third-party application. Third-party developers will probably not manipulate the user data however, we will show how it can be down with JAXB objects at this time. This will be very similar to how it is done with all the JAXB generated objects.

Let¿s say we want to change the user name assigned to the user object from ¿Audry Marx¿ to ¿Audry A Marx¿. To do this we, will need to access the username object contained within the ProcessorUserInfo object and modify it. To the connectToWebService() add:

UserName un = user.getProcessorUser().get(0).getUserName();
un.setValue("Audry A Marx");
user.getProcessorUser().get(0).setUserName(un);
userName = user.getProcessorUser().get(0).getUserName().getValue();
System.out.println("User Name "+userName);

The code method should now look like:

public void connectToWebService() {
        try {
            String xml = svc.getUserInfo("amarx", "A_marx", "2.3");
            System.out.println(xml);
            ProcessorUserInfo user = new ProcessorUserInfo();
            javax.xml.bind.JAXBContext jaxbCtx = javax.xml.bind.JAXBContext.newInstance("generated");
            javax.xml.bind.Unmarshaller unmarshaller = jaxbCtx.createUnmarshaller();
            StreamSource s = new StreamSource(new StringReader(xml));
            user = (ProcessorUserInfo)unmarshaller.unmarshal(s);

            System.out.println("User Name "+user.getProcessorUser().get(0).getUserName().getValue());

            UserName username = user.getProcessorUser().get(0).getUserName();
            username.setValue("Audry A Marx");
            user.getProcessorUser().get(0).setUserName(username);
            String userName = user.getProcessorUser().get(0).getUserName().getValue();
            System.out.println("User Name "+userName);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

If we run the application again we should see the name is now printed out as Audry A Marx

JAXB object are very helpful for working with data but we can¿t send a JAXB obect to the webservices. The web services can only take legal xml strings. Let¿s look how to convert the JAXB objects back into a XML string object. To do this we will need a marshaller object. An unmarshaller object can covert a XML string into a JAXB object. A marshaller object can covert a JAXB object into an XML string.
To the connectToWebServices() add:

javax.xml.bind.Marshaller marshaller = jaxbCtx.createMarshaller();
marshaller.setProperty(javax.xml.bind.Marshaller.JAXB_ENCODING, "UTF-8"); //NOI18N
marshaller.setProperty(javax.xml.bind.Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);

Use the marshaller to convert the ProcessorUserInfo object back into an xml string object. To the connectToWebServices() add:

StringWriter stringWriter = new StringWriter();
marshaller.marshal(user, stringWriter);
String result = stringWriter.toString();
System.out.println(result);

So the total method should look like:

public void connectToWebService() {
        try {
            String xml = svc.getUserInfo("amarx", "A_marx", "2.3");
            System.out.println(xml);
            ProcessorUserInfo user = new ProcessorUserInfo();
            javax.xml.bind.JAXBContext jaxbCtx = javax.xml.bind.JAXBContext.newInstance("generated");
            javax.xml.bind.Unmarshaller unmarshaller = jaxbCtx.createUnmarshaller();
            StreamSource s = new StreamSource(new StringReader(xml));
            user = (ProcessorUserInfo)unmarshaller.unmarshal(s);

            System.out.println("User Name "+user.getProcessorUser().get(0).getUserName().getValue());

            UserName username = user.getProcessorUser().get(0).getUserName();
            username.setValue("Audry A Marx");
            user.getProcessorUser().get(0).setUserName(username);
            String userName = user.getProcessorUser().get(0).getUserName().getValue();
            System.out.println("User Name "+userName);

            javax.xml.bind.Marshaller marshaller = jaxbCtx.createMarshaller();
            marshaller.setProperty(javax.xml.bind.Marshaller.JAXB_ENCODING, "UTF-8"); //NOI18N
            marshaller.setProperty(javax.xml.bind.Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);

            StringWriter stringWriter = new StringWriter();
            marshaller.marshal(user, stringWriter);
            String result = stringWriter.toString();
            System.out.println(result);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

Run the application. We now get XML as our last output with then changed user name of Audry A Marx