Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Exploring A Top-Down SOAP Service: Part VI

DZone's Guide to

Exploring A Top-Down SOAP Service: Part VI

We're going to repeat the steps from Part V, but using an Inheritance approach to the SOAP response type, and compare the two techniques step-by-step.

· Web Dev Zone
Free Resource

Start coding today to experience the powerful engine that drives data application’s development, brought to you in partnership with Qlik.

We Take Things Up Where We Left Off...

In Part V, we created our new SOAP response type for the single operation that we have so far in our web service, and we did so using a Composition approach.

We began with an XSD / WSDL, generated the code , merged it into what we already had, built, deployed, and tested it.

Let's repeat those steps now, but using an Inheritance approach to the SOAP response type, and compare the two techniques step-by-step.

Latest Code

You can go here for the latest code up to this point.

And here is the code for the child (Shape Calculator) project that this web service exposes.

Using Inheritance

Image title

The Schema Changes

We can leave the WSDL as-is, since the operation response type name doesn't change.

Here is our XSD file showing inheritance. Most of it doesn't change.  Just definition  of RunPendingRequestsResponse.

Using Inheritance:

    <xsd:element name="RunPendingRequestsResponse">
        <xsd:complexType>
            <xsd:complexContent>
                <xsd:extension base="resp:StatusResponse">
                    <xsd:sequence>
                        <xsd:element name="numRun" type="xsd:int"/>
                    </xsd:sequence>
                </xsd:extension>
            </xsd:complexContent>
        </xsd:complexType>
    </xsd:element>

Using Composition:

    <xsd:element name="RunPendingRequestsResponse">
        <xsd:complexType>
            <xsd:sequence>
                <xsd:element name="statusResponse" type="resp:StatusResponse" />
                <xsd:element name="numRun" type="xsd:int" />
            </xsd:sequence>
        </xsd:complexType>
    </xsd:element>


Generate Sources

The only difference here from Part 4, is again in RunPendingRequestsResponse.

Inheritance:

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
    "numRun"
})
@XmlRootElement(name = "RunPendingRequestsResponse")
@Generated(value = "com.sun.tools.xjc.Driver", date = "2016-09-26T11:55:28-04:00", comments = "JAXB RI v2.2.11")
public class RunPendingRequestsResponse
    extends StatusResponse
{

    @Generated(value = "com.sun.tools.xjc.Driver", date = "2016-09-26T11:55:28-04:00", comments = "JAXB RI v2.2.11")
    protected int numRun;

Composition:

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
    "statusResponse",
    "numRun"
})
@XmlRootElement(name = "RunPendingRequestsResponse")
@Generated(value = "com.sun.tools.xjc.Driver", date = "2016-09-25T12:50:08-04:00", comments = "JAXB RI v2.2.11")
public class RunPendingRequestsResponse {
    @XmlElement(required = true)
    @Generated(value = "com.sun.tools.xjc.Driver", date = "2016-09-25T12:50:08-04:00", comments = "JAXB RI v2.2.11")
    protected StatusResponse statusResponse;
    @Generated(value = "com.sun.tools.xjc.Driver", date = "2016-09-25T12:50:08-04:00", comments = "JAXB RI v2.2.11")
    protected int numRun;

Reconcile

We copy the one class that changed (RunPendingRequestsResponse) to its place in our working code ( src/main/java ), overwriting what was there before (Part IV).  And we need to make a change in our service implementation code.  Here again is the comparison:

Inheritance:

    @Generated(value = "org.apache.cxf.tools.wsdlto.WSDLToJava", date = "2016-09-21T13:21:57.958-04:00")
    public RunPendingRequestsResponse runAllPendingRequestsNoStopOnError() { 
        LOG.debug("\n\n\nExecuting operation runAllPendingRequestsNoStopOnError\n\n\n");
        RunPendingRequestsResponse _return = new RunPendingRequestsResponse();

        try {

            int numRun = calculator.runAllPendingRequestsNoStopOnError();

            LOG.debug("\n\n\noperation runAllPendingRequestsNoStopOnError returning "+numRun+"\n\n\n");
            _return.setStatus(StatusCode.SUCCESS);
            _return.setDescription("Ran Any Pending Requests: " + numRun);
            _return.setNumRun(numRun);

        } catch (java.lang.Exception ex) {
            ex.printStackTrace();
            LOG.debug("\n\n\noperation runAllPendingRequestsNoStopOnError threw an exception..\n\n\n");
            _return.setStatus(StatusCode.ERROR);
            _return.setClazz(ex.getClass().getName());
            _return.setDescription("Error attempting to Run Pending Requests");
            _return.setErrMsg(ex.getMessage());
            if(ex.getCause()!=null) _return.setCauseMsg(ex.getCause().getMessage());
        }
        return _return;
    }

Everything we had to set in the status (below), we set directly in _return (above).

Composition:

    @Generated(value = "org.apache.cxf.tools.wsdlto.WSDLToJava", date = "2016-09-21T13:21:57.958-04:00")
    public RunPendingRequestsResponse runAllPendingRequestsNoStopOnError() { 
        LOG.debug("\n\n\nExecuting operation runAllPendingRequestsNoStopOnError\n\n\n");
        RunPendingRequestsResponse _return = new RunPendingRequestsResponse();
        StatusResponse status = new StatusResponse();
        try {
            int numRun = calculator.runAllPendingRequestsNoStopOnError();
            LOG.debug("\n\n\noperation runAllPendingRequestsNoStopOnError returning "+numRun+"\n\n\n");
            status.setStatus(StatusCode.SUCCESS);
            status.setDescription("Ran Any Pending Requests: " + numRun);
            _return.setStatusResponse(status);
            _return.setNumRun(numRun);
        } catch (java.lang.Exception ex) {
            ex.printStackTrace();
            LOG.debug("\n\n\noperation runAllPendingRequestsNoStopOnError threw an exception..\n\n\n");
            status.setStatus(StatusCode.ERROR);
            status.setClazz(ex.getClass().getName());
            status.setDescription("Error attempting to Run Pending Requests");
            status.setErrMsg(ex.getMessage());
            if(ex.getCause()!=null) status.setCauseMsg(ex.getCause().getMessage());
            _return.setStatusResponse(status);
        }
        return _return;
    }

Build.Deploy.Start

And as always, we make sure MySQL is running.

We got a clean start in the console.

Test

We again take the WSDL URL and in a new SOAPUI project, we try our operation..

Inheritance:

Image title

Notice there is no enclosing statusResponse>.../</statusResponse> as below.

Composition:

Image title

We won't repeat the error-condition test, since it will be essentially the same as above.

Conclusion

I suppose we could go either way for this project.  It doesn't seem all that important, although normally I lean toward composition as a default.

Since we want all of our operations (we will be adding some more) to return a status, in addition to any operation-specific data, we could go with using Inheritance, so we'll leave our code as-is.

We need to move on.

Latest Code

Since we made the transition in this article to using Inheritance, you can go here for the latest code up to this point.

And here is the code for the child (Shape Calculator) project that this web service exposes.

We Conclude With...

Let's finish off our top-down SOAP service by adding the remaining operations, and we will focus a little on two of them.  One because it requires parameters, and another because it returns a list of objects.  The queueing operation will probably take up an article by itself, due to a certain wrinkle.

After we cover that, then one last article to finalize the project.

More To Come

After we complete this project, we will move on to exploring how to expose our underlying Shape Calculator using REST.

Then we'll take a look at some web application clients for both this SOAP service and the upcoming REST service. We can use the web application that we developed before in our past articles.

Stay tuned!

Create data driven applications in Qlik’s free and easy to use coding environment, brought to you in partnership with Qlik.

Topics:
java ,soap ,wsdl ,xsd ,web dev

Opinions expressed by DZone contributors are their own.

THE DZONE NEWSLETTER

Dev Resources & Solutions Straight to Your Inbox

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.

X

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}