java-use-top-down-method-and-jax-ws-to-develop-web-service-provider
Uncategorized

Java Use Top Down Method and JAX-WS to Develop Web Service Provider

Java Use Top Down Method and JAX-WS to Develop Web Service Provider

In the perivous post: Java Use Bottom-Up Method and JAX-WS to Develop Web Service

I have been talk about Bottom up method. In this post, I will talk about Top Down method to deploy Web Service.

Using Top Down method, you must have a knowledge in XML Schema and Web Services Description Language. If you do not have those knowledge, please follow the URL to learn about that.

XML Schema: http://www.w3schools.com/schema/default.asp
Web Services Description Language: http://www.w3schools.com/WSDL/default.asp

In this tutorial, I will simulate a employee lookup service. Client send a list of employee to service provider. Service provider lookup an employee info and return a list of info to client.

When creating a Web service using a top-down approach, first you design the implementation of the Web service by creating a WSDL file. You can do this using the WSDL Editor. You can then use the Web services wizard to create the Web service and skeleton Java™ classes to which you can add the required code.

First, you need create a WAR project in Eclipse, NetBeans or other IDE. Add 2 file in web root – company.xsd and company.wsdl.

company.xsd:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.memorylack.com/company" xmlns:tns="http://www.memorylack.com/company"
elementFormDefault="qualified">

<xs:simpleType name="EmployeeId">
<xs:restriction base="xs:string">
<xs:length value="7" />
<xs:pattern value="E[0-9]{7}" />
</xs:restriction>
</xs:simpleType>

<xs:simpleType name="EmployeeTitle">
<xs:restriction base="xs:string">
<xs:enumeration value="CEO" />
<xs:enumeration value="Manger" />
<xs:enumeration value="Supervisor" />
<xs:enumeration value="Clerk" />
</xs:restriction>
</xs:simpleType>

<xs:complexType name="EmployeeInfo">
<xs:sequence>
<xs:element name="eid" type="tns:EmployeeId"
minOccurs="0" nillable="false" />
<xs:element name="firstName" type="xs:string"
minOccurs="0" nillable="false" />
<xs:element name="lastName" type="xs:string"
minOccurs="0" nillable="false" />
<xs:element name="age" type="xs:unsignedShort"
minOccurs="0" nillable="false" />
<xs:element name="title" type="tns:EmployeeTitle"
minOccurs="0" nillable="false" />
</xs:sequence>
</xs:complexType>

<xs:complexType name="EmployeeInfoWrapper">
<xs:sequence>
<xs:element name="employeeInfo" type="tns:EmployeeInfo"
minOccurs="0" maxOccurs="unbounded" nillable="false" />
</xs:sequence>
</xs:complexType>

<xs:complexType name="EmployeeIdWrapper">
<xs:sequence>
<xs:element name="eid" type="tns:EmployeeId"
minOccurs="0" maxOccurs="unbounded" nillable="false" />
</xs:sequence>
</xs:complexType>

<xs:element name="EmployeeIdList" type="tns:EmployeeIdWrapper" />
<xs:element name="EmployeeInfoList" type="tns:EmployeeInfoWrapper" />

</xs:schema>

company.wsdl:

<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions name="Company" targetNamespace="http://www.memorylack.com/company"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://www.memorylack.com/company"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema">

<wsdl:types>
<xsd:schema>
<xsd:import namespace="http://www.memorylack.com/company"
schemaLocation="company.xsd" />
</xsd:schema>
</wsdl:types>

<wsdl:message name="employeeLookupRequest">
<wsdl:part element="tns:EmployeeIdList" name="employeeIdList" />
</wsdl:message>

<wsdl:message name="employeeLookupResponse">
<wsdl:part element="tns:EmployeeInfoList" name="employeeInfoList" />
</wsdl:message>

<wsdl:portType name="employeeLookupService">
<wsdl:operation name="employeeLookup">
<wsdl:input message="tns:employeeLookupRequest" />
<wsdl:output message="tns:employeeLookupResponse" />
</wsdl:operation>
</wsdl:portType>

<wsdl:binding name="employeeLookupBinding" type="tns:employeeLookupService">
<soap:binding style="document"
transport="http://schemas.xmlsoap.org/soap/http" />
<wsdl:operation name="employeeLookup">
<soap:operation
soapAction="http://www.memorylack.com/company/employeeLookup" />
<wsdl:input>
<soap:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap:body use="literal" />
</wsdl:output>
</wsdl:operation>
</wsdl:binding>

<wsdl:service name="employeeLookupService">
<wsdl:port binding="tns:employeeLookupBinding" name="employeeLookupPort">
<soap:address location="http://localhost" />
</wsdl:port>
</wsdl:service>

</wsdl:definitions>

you have complete web service interface, but you need create a corresponding Java class. We use JAXB compiler to transfer XML Schema complex type to Java object. Open the CMD.exe to enter below command:

xjc -wsdl company.wsdl -p com.memorylack.www.ws.model

**If Windows alert you xjc not found, Please add %JAVA_HOME%/bin to system path. default %JAVA_HOME% is: C:Program FilesJavajdk1.6.0_21bin**

  • -wsdl option is set your WSDL location
  • -p is set generated Java class package

More option can be found in: JAXB Using

After enter command. You can see following .java file.

  1. EmployeeIdWrapper
  2. EmployeeInfo
  3. EmployeeInfoWrapper
  4. EmployeeTitle
  5. ObjectFactory
  6. package-info

EmployeeIdWrapper:

//
// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vJAXB 2.1.3 in JDK 1.6
// See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a>
// Any modifications to this file will be lost upon recompilation of the source schema.
// Generated on: 2011.06.23 at 04:28:35 PM CST
//


package com.memorylack.www.ws.model;

import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlType;


/**
* <p>Java class for EmployeeIdWrapper complex type.
*
* <p>The following schema fragment specifies the expected content contained within this class.
*
* <pre>
* &lt;complexType name="EmployeeIdWrapper">
* &lt;complexContent>
* &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
* &lt;sequence>
* &lt;element name="eid" type="{http://www.memorylack.com/company}EmployeeId" maxOccurs="unbounded" minOccurs="0"/>
* &lt;/sequence>
* &lt;/restriction>
* &lt;/complexContent>
* &lt;/complexType>
* </pre>
*
*
*/
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "EmployeeIdWrapper", propOrder = {
"eid"
})
public class EmployeeIdWrapper {

protected List<String> eid;

/**
* Gets the value of the eid property.
*
* <p>
* This accessor method returns a reference to the live list,
* not a snapshot. Therefore any modification you make to the
* returned list will be present inside the JAXB object.
* This is why there is not a <CODE>set</CODE> method for the eid property.
*
* <p>
* For example, to add a new item, do as follows:
* <pre>
* getEid().add(newItem);
* </pre>
*
*
* <p>
* Objects of the following type(s) are allowed in the list
* {@link String }
*
*
*/
public List<String> getEid() {
if (eid == null) {
eid = new ArrayList<String>();
}
return this.eid;
}

}

EmployeeInfo:

//
// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vJAXB 2.1.3 in JDK 1.6
// See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a>
// Any modifications to this file will be lost upon recompilation of the source schema.
// Generated on: 2011.06.23 at 04:28:35 PM CST
//


package com.memorylack.www.ws.model;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlSchemaType;
import javax.xml.bind.annotation.XmlType;


/**
* <p>Java class for EmployeeInfo complex type.
*
* <p>The following schema fragment specifies the expected content contained within this class.
*
* <pre>
* &lt;complexType name="EmployeeInfo">
* &lt;complexContent>
* &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
* &lt;sequence>
* &lt;element name="eid" type="{http://www.memorylack.com/company}EmployeeId" minOccurs="0"/>
* &lt;element name="firstName" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
* &lt;element name="lastName" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
* &lt;element name="age" type="{http://www.w3.org/2001/XMLSchema}unsignedShort" minOccurs="0"/>
* &lt;element name="title" type="{http://www.memorylack.com/company}EmployeeTitle" minOccurs="0"/>
* &lt;/sequence>
* &lt;/restriction>
* &lt;/complexContent>
* &lt;/complexType>
* </pre>
*
*
*/
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "EmployeeInfo", propOrder = {
"eid",
"firstName",
"lastName",
"age",
"title"
})
public class EmployeeInfo {

protected String eid;
protected String firstName;
protected String lastName;
@XmlSchemaType(name = "unsignedShort")
protected Integer age;
protected EmployeeTitle title;

/**
* Gets the value of the eid property.
*
* @return
* possible object is
* {@link String }
*
*/
public String getEid() {
return eid;
}

/**
* Sets the value of the eid property.
*
* @param value
* allowed object is
* {@link String }
*
*/
public void setEid(String value) {
this.eid = value;
}

/**
* Gets the value of the firstName property.
*
* @return
* possible object is
* {@link String }
*
*/
public String getFirstName() {
return firstName;
}

/**
* Sets the value of the firstName property.
*
* @param value
* allowed object is
* {@link String }
*
*/
public void setFirstName(String value) {
this.firstName = value;
}

/**
* Gets the value of the lastName property.
*
* @return
* possible object is
* {@link String }
*
*/
public String getLastName() {
return lastName;
}

/**
* Sets the value of the lastName property.
*
* @param value
* allowed object is
* {@link String }
*
*/
public void setLastName(String value) {
this.lastName = value;
}

/**
* Gets the value of the age property.
*
* @return
* possible object is
* {@link Integer }
*
*/
public Integer getAge() {
return age;
}

/**
* Sets the value of the age property.
*
* @param value
* allowed object is
* {@link Integer }
*
*/
public void setAge(Integer value) {
this.age = value;
}

/**
* Gets the value of the title property.
*
* @return
* possible object is
* {@link EmployeeTitle }
*
*/
public EmployeeTitle getTitle() {
return title;
}

/**
* Sets the value of the title property.
*
* @param value
* allowed object is
* {@link EmployeeTitle }
*
*/
public void setTitle(EmployeeTitle value) {
this.title = value;
}

}

EmployeeInfoWrapper:

//
// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vJAXB 2.1.3 in JDK 1.6
// See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a>
// Any modifications to this file will be lost upon recompilation of the source schema.
// Generated on: 2011.06.23 at 04:28:35 PM CST
//


package com.memorylack.www.ws.model;

import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlType;


/**
* <p>Java class for EmployeeInfoWrapper complex type.
*
* <p>The following schema fragment specifies the expected content contained within this class.
*
* <pre>
* &lt;complexType name="EmployeeInfoWrapper">
* &lt;complexContent>
* &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
* &lt;sequence>
* &lt;element name="employeeInfo" type="{http://www.memorylack.com/company}EmployeeInfo" maxOccurs="unbounded" minOccurs="0"/>
* &lt;/sequence>
* &lt;/restriction>
* &lt;/complexContent>
* &lt;/complexType>
* </pre>
*
*
*/
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "EmployeeInfoWrapper", propOrder = {
"employeeInfo"
})
public class EmployeeInfoWrapper {

protected List<EmployeeInfo> employeeInfo;

/**
* Gets the value of the employeeInfo property.
*
* <p>
* This accessor method returns a reference to the live list,
* not a snapshot. Therefore any modification you make to the
* returned list will be present inside the JAXB object.
* This is why there is not a <CODE>set</CODE> method for the employeeInfo property.
*
* <p>
* For example, to add a new item, do as follows:
* <pre>
* getEmployeeInfo().add(newItem);
* </pre>
*
*
* <p>
* Objects of the following type(s) are allowed in the list
* {@link EmployeeInfo }
*
*
*/
public List<EmployeeInfo> getEmployeeInfo() {
if (employeeInfo == null) {
employeeInfo = new ArrayList<EmployeeInfo>();
}
return this.employeeInfo;
}

}

EmployeeTitle:

//
// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vJAXB 2.1.3 in JDK 1.6
// See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a>
// Any modifications to this file will be lost upon recompilation of the source schema.
// Generated on: 2011.06.23 at 04:28:35 PM CST
//


package com.memorylack.www.ws.model;

import javax.xml.bind.annotation.XmlEnum;
import javax.xml.bind.annotation.XmlEnumValue;
import javax.xml.bind.annotation.XmlType;


/**
* <p>Java class for EmployeeTitle.
*
* <p>The following schema fragment specifies the expected content contained within this class.
* <p>
* <pre>
* &lt;simpleType name="EmployeeTitle">
* &lt;restriction base="{http://www.w3.org/2001/XMLSchema}string">
* &lt;enumeration value="CEO"/>
* &lt;enumeration value="Manger"/>
* &lt;enumeration value="Supervisor"/>
* &lt;enumeration value="Clerk"/>
* &lt;/restriction>
* &lt;/simpleType>
* </pre>
*
*/
@XmlType(name = "EmployeeTitle")
@XmlEnum
public enum EmployeeTitle {

CEO("CEO"),
@XmlEnumValue("Manger")
MANGER("Manger"),
@XmlEnumValue("Supervisor")
SUPERVISOR("Supervisor"),
@XmlEnumValue("Clerk")
CLERK("Clerk");
private final String value;

EmployeeTitle(String v) {
value = v;
}

public String value() {
return value;
}

public static EmployeeTitle fromValue(String v) {
for (EmployeeTitle c: EmployeeTitle.values()) {
if (c.value.equals(v)) {
return c;
}
}
throw new IllegalArgumentException(v);
}

}

ObjectFactory:

//
// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vJAXB 2.1.3 in JDK 1.6
// See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a>
// Any modifications to this file will be lost upon recompilation of the source schema.
// Generated on: 2011.06.23 at 04:28:35 PM CST
//


package com.memorylack.www.ws.model;

import javax.xml.bind.JAXBElement;
import javax.xml.bind.annotation.XmlElementDecl;
import javax.xml.bind.annotation.XmlRegistry;
import javax.xml.namespace.QName;


/**
* This object contains factory methods for each
* Java content interface and Java element interface
* generated in the com.memorylack.www.ws.model package.
* <p>An ObjectFactory allows you to programatically
* construct new instances of the Java representation
* for XML content. The Java representation of XML
* content can consist of schema derived interfaces
* and classes representing the binding of schema
* type definitions, element declarations and model
* groups. Factory methods for each of these are
* provided in this class.
*
*/
@XmlRegistry
public class ObjectFactory {

private final static QName _EmployeeIdList_QNAME = new QName("http://www.memorylack.com/company", "EmployeeIdList");
private final static QName _EmployeeInfoList_QNAME = new QName("http://www.memorylack.com/company", "EmployeeInfoList");

/**
* Create a new ObjectFactory that can be used to create new instances of schema derived classes for package: com.memorylack.www.ws.model
*
*/
public ObjectFactory() {
}

/**
* Create an instance of {@link EmployeeIdWrapper }
*
*/
public EmployeeIdWrapper createEmployeeIdWrapper() {
return new EmployeeIdWrapper();
}

/**
* Create an instance of {@link EmployeeInfoWrapper }
*
*/
public EmployeeInfoWrapper createEmployeeInfoWrapper() {
return new EmployeeInfoWrapper();
}

/**
* Create an instance of {@link EmployeeInfo }
*
*/
public EmployeeInfo createEmployeeInfo() {
return new EmployeeInfo();
}

/**
* Create an instance of {@link JAXBElement }{@code <}{@link EmployeeIdWrapper }{@code >}}
*
*/
@XmlElementDecl(namespace = "http://www.memorylack.com/company", name = "EmployeeIdList")
public JAXBElement<EmployeeIdWrapper> createEmployeeIdList(EmployeeIdWrapper value) {
return new JAXBElement<EmployeeIdWrapper>(_EmployeeIdList_QNAME, EmployeeIdWrapper.class, null, value);
}

/**
* Create an instance of {@link JAXBElement }{@code <}{@link EmployeeInfoWrapper }{@code >}}
*
*/
@XmlElementDecl(namespace = "http://www.memorylack.com/company", name = "EmployeeInfoList")
public JAXBElement<EmployeeInfoWrapper> createEmployeeInfoList(EmployeeInfoWrapper value) {
return new JAXBElement<EmployeeInfoWrapper>(_EmployeeInfoList_QNAME, EmployeeInfoWrapper.class, null, value);
}

}

package-info:

//
// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vJAXB 2.1.3 in JDK 1.6
// See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a>
// Any modifications to this file will be lost upon recompilation of the source schema.
// Generated on: 2011.06.23 at 04:28:35 PM CST
//

@javax.xml.bind.annotation.XmlSchema(namespace = "http://www.memorylack.com/company", elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED)
package com.memorylack.www.ws.model;

Please copy .java file yo your WAR project and create a class named EmployeeLookupService:

package com.ctlok.pro.ws;

import java.util.HashMap;
import java.util.Map;

import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
import javax.xml.bind.annotation.XmlSeeAlso;

import com.memorylack.www.ws.model.EmployeeIdWrapper;
import com.memorylack.www.ws.model.EmployeeInfo;
import com.memorylack.www.ws.model.EmployeeInfoWrapper;
import com.memorylack.www.ws.model.EmployeeTitle;
import com.memorylack.www.ws.model.ObjectFactory;

@WebService(
name = "employeeLookupService",
serviceName = "employeeLookupService",
portName = "employeeLookupPort",
targetNamespace= "http://www.memorylack.com/company",
wsdlLocation = "company.wsdl")
@SOAPBinding(parameterStyle = SOAPBinding.ParameterStyle.BARE)
@XmlSeeAlso({ObjectFactory.class})
public class EmployeeLookupService {

private Map<String, EmployeeInfo> infoMap;

public EmployeeLookupService(){
infoMap = new HashMap<String, EmployeeInfo>();

EmployeeInfo info1 = new EmployeeInfo();
info1.setEid("E1000000");
info1.setFirstName("Lawrence");
info1.setLastName("Cheung");
info1.setAge(24);
info1.setTitle(EmployeeTitle.CEO);

EmployeeInfo info2 = new EmployeeInfo();
info2.setEid("E1524125");
info2.setFirstName("Tom");
info2.setLastName("Wong");
info2.setAge(22);
info2.setTitle(EmployeeTitle.CLERK);

EmployeeInfo info3 = new EmployeeInfo();
info3.setEid("E7452145");
info3.setFirstName("John");
info3.setLastName("Lee");
info3.setAge(29);
info3.setTitle(EmployeeTitle.MANGER);

EmployeeInfo info4 = new EmployeeInfo();
info4.setEid("E6523547");
info4.setFirstName("Katty");
info4.setLastName("Choi");
info4.setAge(24);
info4.setTitle(EmployeeTitle.SUPERVISOR);


infoMap.put(info1.getEid(), info1);
infoMap.put(info2.getEid(), info2);
infoMap.put(info3.getEid(), info3);
infoMap.put(info4.getEid(), info4);
}

@WebMethod(operationName="employeeLookup")
@WebResult(name = "EmployeeInfoList", partName = "employeeInfoList")
public EmployeeInfoWrapper employeeLookup(
@WebParam(name = "EmployeeIdList", partName = "employeeIdList")
EmployeeIdWrapper employeeIdWrapper){

EmployeeInfoWrapper employeeInfoWrapper = new EmployeeInfoWrapper();

for (String eid: employeeIdWrapper.getEid()){
EmployeeInfo info = infoMap.get(eid);

if (info == null)
info = new EmployeeInfo();

employeeInfoWrapper.getEmployeeInfo().add(info);
}

return employeeInfoWrapper;

}

}

Now, you have complete the web service provider.

@SOAPBinding(parameterStyle = SOAPBinding.ParameterStyle.BARE)

This annotation default value is WRAPPED. JAX-WS auto create a wrapper to wrap the object. In company.xsd, I have a wrapper so do not need this option. Set value to BARE to avoid JAX-WS auto create a wrapper.

——————- separate ——————-

@XmlSeeAlso({ObjectFactory.class})

This annotation will be allowed on any JAXB-bound type, and when JAXB binds that type, classes listed in @XmlSeeAlso will be also bound.

——————- separate ——————-

@WebResult(
name = "EmployeeInfoList",
partName = "employeeInfoList")

This annotation is mapped with WSDL:

<wsdl:message name="employeeLookupRequest">
<wsdl:part element="tns:EmployeeIdList" name="employeeIdList" />
</wsdl:message>

——————- separate ——————-

@WebResult(
name = "EmployeeInfoList",
partName = "employeeInfoList")

This annotation is mapped with WSDL:

<wsdl:message name="employeeLookupResponse">
<wsdl:part element="tns:EmployeeInfoList" name="employeeInfoList" />
</wsdl:message>

Now you can deploy this project to application server and run this URL in browser: http://localhost/employeeLookupService?wsdl.

If this URL not equal your project URL, please modify WSDL address:

<wsdl:service name="employeeLookupService">
<wsdl:port binding="tns:employeeLookupBinding" name="employeeLookupPort">
<soap:address location="http://localhost" />
</wsdl:port>
</wsdl:service>

Complete this part you can use soapUI to test your Web Service Provider. soapUI sent below SOAP XML to server:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:com="http://www.memorylack.com/company">
<soapenv:Header/>
<soapenv:Body>
<com:EmployeeIdList>
<!--Zero or more repetitions:-->
<com:eid>E1000000</com:eid>
<com:eid>E1524125</com:eid>
</com:EmployeeIdList>
</soapenv:Body>
</soapenv:Envelope>

Server response:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>
<EmployeeInfoList xmlns="http://www.memorylack.com/company">
<employeeInfo>
<eid>E1000000</eid>
<firstName>Lawrence</firstName>
<lastName>Cheung</lastName>
<age>24</age>
<title>CEO</title>
</employeeInfo>
<employeeInfo>
<eid>E1524125</eid>
<firstName>Tom</firstName>
<lastName>Wong</lastName>
<age>22</age>
<title>Clerk</title>
</employeeInfo>
</EmployeeInfoList>
</soapenv:Body>
</soapenv:Envelope>