Java services are the majority of services. They operate on the method call level and map to RPC usage of SOAP.
In Java services, every incoming request is deserialized into a set of Java objects. The objects are then passed as parameters to a method of the service instance as follows:
The appropriate method is selected, based on the WSDL operation name. When methods are overloaded, method selection is based on parameters, as well.
When the service method call ends, the return value and the value of all the out parameters (in their respective holder objects) are serialized into the response message.
![]() | Caution |
---|---|
The service must not modify the return value or the values of out parameters after the service method call has ended. For example, if a service keeps any references to data returned, directly or indirectly, from one thread, and a second thread handling a different client request modifies this data, it can impact the first thread. |
The response message with the serialized return value and out parameters is returned.
The basics of writing a Java service are covered in Writing Web Services in Jumpstart. Two more use cases are covered in this book:
Writing a Java Service with Attachments
Passing In, Out and In/Out Parameters
Passing parameters by Remote Reference
Sometimes a server needs to send application-specific binary data to its peer. For example, a service might want to return a picture or audio data. The preferred way of sending these data over SOAP is by using the SOAP with Attachments specification. This specification defines how data is serialized into a DIME or MIME Multi-part message and how this data is referenced.
The following sections describe in detail how to write services capable of handling SOAP with Attachments. For information about clients using attachments, see Client with Attachments.
For a low-level view of attachments, WSO2 SOA Enablement Server offers a family of org.idoox.wasp.types.MessageAttachment classes:
org.idoox.wasp.types.MessageAttachment for documents that are in/out; that is, passed to the server, processed there, and then sent back to the client.
org.idoox.wasp.types.RequestMessageAttachment for documents that are passed to the server only.
org.idoox.wasp.types.ResponseMessageAttachment for documents that are passed to the client only.
Example 6 shows a service that accepts one request document:
Example 6. Service Accepting a Document
// Copyright WSO2 Inc. All rights reserved. // Use is subject to license terms. package example.processing.attachments; import org.idoox.wasp.types.RequestMessageAttachment; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; public class RequestAttachmentService { public String processAttachment(RequestMessageAttachment doc) throws IOException { // gets the first line from the attachment and returns it BufferedReader rdr = new BufferedReader(new InputStreamReader(doc.getData())); String ret = rdr.readLine(); rdr.close(); return ret; } }
Because the service is defined as String processAttachment(RequestMessageAttachment doc), it expects one parameter (doc) that is passed from client to server, and it returns a string. In the body of the function, it takes the input stream of the document and wraps it with a higher-level stream as shown in Example 7:
Example 7. BufferedReader Showing Input Stream Wrapping
BufferedReader rdr = new BufferedReader(new InputStreamReader(doc.getData()));
Then the service reads a line from the attachment and closes the stream, so that WSO2 SOA Enablement Server knows that it can discard any possible input and close the connection as shown in Example 8.
Finally, the service returns the line read.
![]() | Important |
---|---|
All attachment input streams have to be closed even if an input or input/output attachment is not used in the service. For example: public ResponseStructure helloAttachment(RequestMessageAttachment att) { //close attachment input stream att.getData().close(); return new ResponseStructure(...); } If the input stream is not closed, the MessageAttachment may not be serialized correctly. |
![]() | Important |
---|---|
Attachment parameters must not be used after the service method that handled them has returned execution to the framework. |
Example 12 shows how client data is serialized. One thing that might be confusing is the absence of OutputStream in the message attachment class. To write data into an attachment, use one of the following constructs:
Directly use the data input stream. For example, to transfer a file, just use the code in Example 9.
If the previous construct does not apply and the transferred data is short, you might want to use the code in Example 10.
For large data, you might want to use the code from Example 11: PipedInputStream.
The run method of FillingThread should look like:
Example 12. Filling Thread
public void run() { try { for (;;) { // get some data to write byte [] buffer = getDataToWrite(); // test end if (buffer.length == 0) { break; } // write and flush out.write(buffer); out.flush(); }; // close the stream out.close(); } catch (IOException e) { e.printStackTrace(); } }
Please see the Attachments demo for a complete example of this approach.
(Multipurpose Internet Mail Extensions) uses a number of data records which contain the data to be sent. Each of these records has a header and a payload. MIME uses a separator string to indicate where the current payload ends and the next payload begins. The separator string is located at the beginning of a MIME message and in between each data record. When parsing the data, the parser scans each data record until it locates the separator string. This string indicates the beginning of next data record. This type of attachment is WS-I compliant.
(Direct Internet Message Encapsulation) also uses data records with headers. However, with DIME each header contains the length of the payload, rather then a separator string. Therefore instead of using a separator string to delineate records, the record size is used. Using this method, parsing the payload is much simpler. Because the size of each record is known, moving from record to record is much quicker, as there is no need to scan every record. For this reason, DIME tends to be more efficient than MIME, especially on the receiving end.
DIME is a binary format with better performance. However, some SOAP frameworks implement DIME and others MIME, so the main criteria for choosing between the attachment styles is interoperability. Furthermore, DIME attachments are not WS-I compliant. For maximum interoperability you can use WSO2 SOA Enablement Server to publish a Web service with attachments to two separate endpoints, one in MIME style and the other in DIME. However, only the MIME endpoint will be WS-I compliant.
The type of attachment encapsulation used by the service is given in its WSDL description. The client is not affected by the encapsulation used. WSO2 SOA Enablement Server decides which to use after it obtains the service's WSDL upon the service lookup.
The service can use the default encapsulation chosen during WSO2 SOA Enablement Server installation as its default Multi-part encapsulation. Alternatively, the WSDL generator can be set up to choose a particular encapsulation type. Example 13 demonstrates publishing the same service to two endpoints, one using the default encapsulation and the other using explicitly chosen DIME encapsulation. It is invoked by pointing the same client to the two different URLs. The result will be the same, because WSO2 SOA Enablement Server automatically adapts itself to the endpoint's encapsulation, be it MIME or DIME.
Example 13. Publishing the Service Using Different Multi-Part Encapsulations
// Copyright WSO2 Inc. All rights reserved. // Use is subject to license terms. package example.processing.attachments; import org.idoox.wasp.tools.java2wsdl.Java2WSDL; import org.idoox.wasp.tools.java2wsdl.Java2WSDLFactory; import org.systinet.wasp.Wasp; import org.systinet.wasp.webservice.Registry; import org.systinet.wasp.webservice.ServiceEndpoint; import org.systinet.wasp.webservice.ServiceInstance; public class RequestAttachmentServer { public static void main(String[] args) throws Exception { // initialize WASP and start HTTP server Wasp.startServer("http://localhost:6060"); // create one service instance published on two different endpoints ServiceInstance serviceInstance = ServiceInstance.create(new RequestAttachmentService()); // publish MIME AttachmentsService using the (default) MIME transport ServiceEndpoint mimeEndpoint = ServiceEndpoint.create("/att", serviceInstance); Registry.publish(mimeEndpoint); // publish DIME AttachmentsService using the DIME transport ServiceEndpoint dimeEndpoint = ServiceEndpoint.create("/attdime", serviceInstance); Java2WSDL java2wsdl = Java2WSDLFactory.newJava2WSDL(); java2wsdl.setAttachmentType(Java2WSDL.ATTACHMENT_TYPE_DIME); dimeEndpoint.setWSDL( java2wsdl.generateDefinition(RequestAttachmentService.class)); Registry.publish(dimeEndpoint); } }
Please see the Attachments demo for a complete example of this approach.
Each method parameter in a SOAP RPC call can be classified into one of the following categories:
in parameter - transmitted from client to server.
return value - return value transmitted from server to client.
in/out parameter - transmitted from client to server, processed there and a new value transmitted back to the client.
out parameter - additional return value from server.
For passing in/out and out parameters, WSO2 SOA Enablement Server uses Holder classes. Because parameters in SOAP calls are passed by copy, we need a container that holds the reference to out and in-out parameters. This container is called Holder. There are predefined containers for basic data types and for basic java containers. But, if you have your own data type, you must use a tool to generate it as shown in the following commands:
WSDL2Java holders.wsdl
> Service.java MyStruct.java MyStructHolder.java
> cat MyStructureHolder.java
For more information about holders please see Holder Generator.
In most cases, these should be generated automatically by WSDL2Java. This is shown in Example 14.
Example 14. Holder Generated by WSDL2Java
public class MyStructHolder implements javax.xml.rpc.holders.Holder { public MyStruct value; public MyStructHolder() { } public MyStructHolder(MyStruct value) { this.value = value; } }
Example 15 shows the interface of the service and shows sample code for a client calling the out operation.
The interface of the service contains the following method:
Example 15. Using out Holders - Service Interface
/** * calls a operation on the server, returning true if the call succeeds. * In this case, outValue is filled with an out structure. */ public boolean callOutParameter(MyStructHolder outValue);
The sample code for a client calling the out operation is shown in Example 16:
Example 16. Sample Code for a Client Calling an Out Operation
Service myService = (Service) Registry.lookup(...); MyStructHolder outParameter = new MyStructHolder(); if (myService.callOutParameter(outParameter)) { System.out.println("Call OK, got value " + outParameter.value); }
Example 17 shows the service interface for using in-out holders and Example 18 show sample code for a client calling the in-out operation.
The interface of the service contains the following method:
Example 17. Using in-out Holders
/** * calls a operation on the server, transforming data from inoutValue. * The transformed data are sent back to the client. */ public boolean callInoutParameter(MyStructHolder inoutValue);
The sample code for a client calling the in-out operation is shown in Example 18:
Example 18. Sample Code for Calling a in-out Operation
Service myService = (Service) Registry.lookup(...); MyStruct str = new MyStruct(); // fill up str MyStructHolder inoutParameter = new MyStructHolder(str); if (myService.callInoutParameter(inoutParameter)) { System.out.println("Call OK, transformed value " + inoutParameter.value); }
In Web services, the basic level of granularity is a service, usually identified by its URI and described by a WSDL file. In other systems, like CORBA and DCOM, the granularity is on objects, each also having its interface described in some way. To be able to expose such systems over SOAP , it is necessary to somehow model the object granularity.
Usually, parameters in SOAP calls are passed by copy (for more information please see In-Out Parameters) but Remote References allows you to pass objects by reference.
In WSO2 SOA Enablement Server for Java, it is possible to have multiple objects on one endpoint. These objects may even be of the same type, serving different requests. Using SSJ's Instance ID extension, it is possible to address any of these objects separately. This allows a service to return almost any object; that object will be accessible as one instance in the whole Web service.
Three events occur when serializing such an object:
It is added to the set of instances that this Web service handles.
It is assigned its own instance ID.
A WSDL description for all of its implemented interfaces is generated.
The receiver of such a remote reference receives information on the interface of this object (a pointer to its WSDL description) and the appropriate instance ID so the remote reference can be invoked. In SSJ, the deserialization of this remote reference will result in a proxy that represents this particular instance and implements the same interfaces (if available) as the object on the server.
To enable this, the object must be serialized into a schema type with the name serviceReference in the namespace http://idoox.com/interface. WSO2 SOA Enablement Server tools generate this type in those places in data structures where there is any Java type implementing or extending Interface Remote.
Assuming the above, remote references work automatically in WSO2 SOA Enablement Server Server and WSO2 SOA Enablement Server clients when these two share the same Java interfaces. This is because the server sends to the client the mapping from the new object's WSDL portTypes to Java interfaces. If the client cannot load a particular interface, it ignores this particular WSDL portType in good faith that this interface (and therefore the portType) will not be used in the client software. This is true in vast majority of cases.
![]() | Note |
---|---|
Because a remote reference becomes a part of its service, it is impossible to serialize a new remote reference on the client side. However, a remote reference which you obtain from a service can be passed to any other service. In this case, you are not creating a new reference but passing a previously created remote reference. |
Example 19, Example 20, Example 21, Example 22, Example 23 and Example 24 are simplified versions of the demo for remote references.
Example 19 and Example 20 show a simple Java service the returns another object as a remote reference.
Example 19 is the CounterFactory Interface and Example 20 shows the implementation.
Example 21 and Example 22 also show a simple Java service that returns another object as a remote reference.
Example 21 is the CounterService Interface and Example 22 shows the implementation of the service. Example 23 shows a simple client for the service from Example 19.
Example 24 shows the SOAP message that is passed from the service back to its client.
Example 19. CounterFactory Interface: Creates Remote Reference
// Copyright WSO2 Inc. All rights reserved. // Use is subject to license terms. package example.remoting.remotereferences; public interface CounterFactory { public CounterService createCounter(); }
Example 20 shows the interface for the remote reference.
Example 20. CounterFactory Implementation: Creates Remote Reference
// Copyright WSO2 Inc. All rights reserved. // Use is subject to license terms. package example.remoting.remotereferences; import example.remoting.remotereferences.CounterFactory; import example.remoting.remotereferences.CounterService; public class CounterFactoryImpl implements CounterFactory { public CounterService createCounter() { return new CounterServiceImpl(); } }
Example 21 shows the Java Interface for the remote reference.
Example 21. CounterService: Java Interface of the Remote Reference
// Copyright WSO2 Inc. All rights reserved. // Use is subject to license terms. package example.remoting.remotereferences; public interface CounterService extends java.rmi.Remote { int getCount(); int increase(); }
Example 22 shows the Java implementation for the remote reference.
Example 22. CounterService: Implementation of the Remote Reference
// Copyright WSO2 Inc. All rights reserved. // Use is subject to license terms. package example.remoting.remotereferences; import example.remoting.remotereferences.CounterService; public class CounterServiceImpl implements CounterService { private int count; public CounterServiceImpl() { count = 0; } public int increase() { return ++count; } public int getCount() { return count; } }
Example 23. Simple Client for CounterFactory
// Copyright WSO2 Inc. All rights reserved. // Use is subject to license terms. package example.remoting.remotereferences; import example.remoting.remotereferences.CounterFactory; import example.remoting.remotereferences.CounterService; import org.systinet.wasp.webservice.Registry; public class CounterClient { private static String serviceWSDLPath = "/example/remoting/remotereferences/CounterFactoryService/wsdl"; public static void main(String[] args) throws Exception { String serverURL = "http://localhost:6060"; //lookup the counter factory CounterFactory cf = (CounterFactory) Registry.lookup(serverURL + serviceWSDLPath, CounterFactory.class); System.out.println("Getting counter."); //get remote reference to newly created CounterService CounterService counterService = cf.createCounter(); //invoke methods on CounterService System.out.println("Counter count: " + counterService.getCount()); System.out.println("Counter count: " + counterService.increase()); System.out.println("Counter count: " + counterService.increase()); } }
Example 24 shows the SOAP message that is passed back from the service to the client.
Example 24. A Remote Reference SOAP Message
<?xml version="1.0" encoding="UTF-8"?> <!-- Copyright WSO2 Inc. All rights reserved. Use is subject to license terms. --> <e:Envelope xmlns:d="http://www.w3.org/2001/XMLSchema" xmlns:e="http://schemas.xmlsoap.org/soap/envelope/" xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns:ns0="http://localhost:6060/example/remoting/remotereferences/ CounterFactoryService" xmlns:ns1="http://schemas.xmlsoap.org/soap/encoding/" xmlns:ns2="http://localhost:6060/example/remoting/remotereferences/ CounterFactoryService/example.remoting.remotereferences.CounterServiceDE4376" xmlns:wn0="http://idoox.com/interface" xmlns:wn1="http://wso2.com/xsd/SchemaTypes/"> <e:Body> <wn1:serviceReference_Response i:type="wn0:serviceReference"> <wn0:service>ns0:example.remoting.remotereferences.CounterServiceImplA166BD </wn0:service> <wn0:wsdl>http://localhost:6060/internal/java/wsdlGenerator/ ?class=example.remoting.remotereferences.CounterServiceImpl& amp;serviceURI=http%3A%2F%2Flocalhost%3A6060%2Fexample% 2Fremoting% 2Fremotereferences%2FCounterFactoryService</wn0:wsdl> <wn0:instanceID>x.in.idoox.com:2003.02.04 07:57:25 GMT:B5E165A985F8CB1F:1 </wn0:instanceID> <wn0:portTypeMappings ns1:arrayType="wn0:interfaceMapping[1]"> <wn0:item> <wn0:portType>ns2:example.remoting.remotereferences. CounterServiceDE4376 </wn0:portType> <wn0:className>example.remoting.remotereferences.CounterService</wn0:className> </wn0:item> </wn0:portTypeMappings> </wn1:serviceReference_Response> </e:Body> </e:Envelope>
WSO2 SOA Enablement Server makes it possible to use the SOAP protocol, which is an XML format, from Java. WSO2 SOA Enablement Server transparently converts XML documents into Java objects when a message is received and vice versa when the message is sent.
This process is largely hidden from the user. The mapping between xml schema and Java classes is, however, recorded in files with the extension .xmap. This chapter describes these files.
When WSDL2Java generates Java sources from a WSDL description file, along with these sources it always creates a mapping file. This file has the same name as the service interface and the extension .xmap. It contains valuable information for:
Mapping between Java classes and XML Schema types
Mapping between Java methods and WSDL operations
![]() | Important |
---|---|
.xmap files must be named after the lookup interface class on the client side or a service implementation class on the server side. (Except for the filename extension, which must be changed to .xmap). This .xmap file must be placed in the package as the implementation/interface class. It is therefore it is in the application classpath. |
On the service side, you only need the mapping files when using a WSDL that was not generated by WSO2 SOA Enablement Server. When you let WSO2 SOA Enablement Server generate the WSDL for you automatically, the mapping information is put directly into the WSDL file and you do not need the mapping file on the service side (however, the client's need remains).
The mapping between Java classes and XML Schema types is important for the WSO2 SOA Enablement Server serialization framework. Without it WSO2 SOA Enablement Server would not be able to determine which XML Schema type or Java class should be used when serializing between Java and XML (except very simple cases like int or string).
The mapping between Java methods and WSDL operations is important when you have overloaded methods (that is, there are two or more methods with the same name but different number of parameters). In this case the mapping helps WSO2 SOA Enablement Server to decide which operation should be called.
![]() | Important |
---|---|
When you modify the wsdl description, you have to also regenerate the xmap file. Do this by re-executing WSDL2Java. |
The mapping file is standard XML. The structure is as shown in Example 25:
Example 25. Mapping File Structure
<?xml version="1.0" encoding="UTF-8"?> <mapping> <schema-mapping> <!-- contains all the XML Schemas defined in WSDL. Each Schema --> <!-- carries the mapping information between Java class and XML Schema type --> </schema-mapping> <operation-mapping> <!-- contains the mapping between Java service methods and WSDL operations --> <operation method="Java methodname" name="WSDL operation" signature="Base64 encoded Java method signature"/> </operation-mapping> </mapping>
Each mapping file relates to one service interface and each service interface has exactly one mapping file. The mapping file must have the same name as the service interface, plus the extension ".xmap." When WSO2 SOA Enablement Server loads the service interface class, it searches for the mapping, too. The search is conducted in the classpath in the same directory as the class package.
Consider the WSDL file, shown in Example 26
Example 26. Service Definition WSDL
<?xml version="1.0" encoding="UTF-8"?> <wsdl:definitions name="example.basics.mapping.service.Service" targetNamespace="http://wso2.com/wsdl/example/basics/mapping/service/" xmlns:ns0="http://wso2.com/xsd/SchemaTypes/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://wso2.com/wsdl/example/basics/mapping/service/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"> <wsdl:types> <xsd:schema elementFormDefault="qualified" targetNamespace="http://wso2.com/xsd/SchemaTypes/" xmlns:xns4="http://wso2.com/wsdl/example/basics/mapping/service/" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <xsd:import namespace="http://wso2.com/wsdl/example/basics/mapping/service/"/> <xsd:element name="p0" nillable="true" type="xns4:MyStruct"/> <xsd:element name="MyStruct_Response" nillable="true" type="xns4:MyStruct"/> </xsd:schema> <xsd:schema elementFormDefault="qualified" targetNamespace="http://wso2.com/wsdl/example/basics/mapping/service/" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <xsd:complexType name="MyStruct"> <xsd:sequence> <xsd:element name="i" type="xsd:int"/> <xsd:element name="s" nillable="true" type="xsd:string"/> </xsd:sequence> </xsd:complexType> </xsd:schema> </wsdl:types> <wsdl:message name="Service_echo_Response"> <wsdl:part element="ns0:MyStruct_Response" name="response"/> </wsdl:message> <wsdl:message name="Service_echo_1_Request"> <wsdl:part element="ns0:p0" name="p0"/> </wsdl:message> <wsdl:portType name="Service"> <wsdl:operation name="echo" parameterOrder="p0"> <wsdl:input message="tns:Service_echo_1_Request"/> <wsdl:output message="tns:Service_echo_Response"/> </wsdl:operation> </wsdl:portType> <wsdl:binding name="Service" type="tns:Service"> <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/> <wsdl:operation name="echo"> <soap:operation soapAction="echo" style="document"/> <wsdl:input> <soap:body use="literal"/> </wsdl:input> <wsdl:output> <soap:body use="literal"/> </wsdl:output> </wsdl:operation> </wsdl:binding> <wsdl:service name="Service"> <wsdl:port binding="tns:Service" name="Service"> <soap:address location="urn:unknown-location-uri"/> </wsdl:port> </wsdl:service> </wsdl:definitions>
To generate a service from this WSDL file using WSDL2Java, you run the following command:
WSDL2Java -p example.basics.mapping.client Definitions_examples_service.wsdl
This command returns the following printout on screen:
writing file .\example\basics\mapping\client\MyStruct.java writing file .\example\basics\mapping\client\Service.java writing file .\example\basics\mapping\client\Service.xmap
From this printout you see that now we have Java sources (Service.java, MyStruct.java) and a mapping file (Service.xmap. (Please refer to Example 27). The package is example.basics.mapping.client. After the sources are compiled, you must copy the mapping file into the classpath in the directory example/basics/mapping/client.
Example 27. Service.xmap
<?xml version="1.0" encoding="UTF-8"?> <mapping> <schema-mapping> <xs:schema targetNamespace="http://wso2.com/xsd/SchemaTypes/" xmlns:sns2="http://wso2.com/wsdl/example/basics/mapping/service/" xmlns:xs="http://www.w3.org/2001/XMLSchema"> <xs:import namespace="http://wso2.com/wsdl/example/basics/mapping/service/"/> <xs:element form="qualified" name="p0" nillable="true" type="sns2:MyStruct"/> <xs:element form="qualified" name="MyStruct_Response" nillable="true" type="sns2:MyStruct"/> </xs:schema> <xs:schema targetNamespace="http://wso2.com/wsdl/example/basics/mapping/service/" xmlns:map="http://wso2.com/mapping/" xmlns:xs="http://www.w3.org/2001/XMLSchema"> <xs:import namespace="http://www.w3.org/2001/XMLSchema"/> <xs:complexType name="MyStruct"> <xs:annotation><xs:appinfo> <map:java-type name="example.basics.mapping.client.MyStruct"/> </xs:appinfo></xs:annotation> <xs:sequence name="MyStruct"> <xs:element form="qualified" name="i" type="xs:int"/> <xs:element form="qualified" name="s" nillable="true" type="xs:string"/> </xs:sequence> </xs:complexType> </xs:schema> </schema-mapping> <operation-mapping> <operation method="echo" name="echo" signature="KExleGFtcGxlcy9jbGllbnQvTXlTdHJ1Y3Q7KUxleGFtcGxlcy9jbGllbnQvTXlTdHJ1Y3Q7"/> </operation-mapping> </mapping>
When you use WSO2 SOA Enablement Server to generate WSDL for you automatically with Java2WSDL, the mapping information will be put into the WSDL directly. You might not need to use the mapping file on the service side. However, the Java package names you are using on the client and service side might not match, requiring the use of a mapping file on the client side. For example, the server might use the package example.basics.mapping.service However, the Java package names you are using on the client and service side might not match, requiring the use of a mapping file on the client side, where the mapping is put into WSDL, while the client on the other side might use the package example.basics.mapping.client. This would cause a mapping mismatch.
What if you are using both a WSDL and a mapping file? In this case the mapping file always has a higher priority and the WSDL mapping information will be ignored!
Example 28. WSDL Including Mapping Information
<?xml version="1.0" encoding="utf-8"?> <wsdl:definitions name="examples.service.Service" targetNamespace="http://wso2.com/wsdl/example/basics/mapping/service/" xmlns:ns0="http://wso2.com/xsd/SchemaTypes/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://wso2.com/wsdl/example/basics/mapping/service/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"> <wsdl:types> <xsd:schema elementFormDefault="qualified" targetNamespace="http://wso2.com/xsd/SchemaTypes/" xmlns:xns4="http://wso2.com/wsdl/example/basics/mapping/service/" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <xsd:import namespace="http://wso2.com/wsdl/example/basics/mapping/service/"/> <xsd:element name="p0" nillable="true" type="xns4:MyStruct"/> <xsd:element name="MyStruct_Response" nillable="true" type="xns4:MyStruct"/> </xsd:schema> <xsd:schema elementFormDefault="qualified" targetNamespace="http://wso2.com/wsdl/example/basics/mapping/service/" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <xsd:complexType name="MyStruct"> <xsd:annotation> <xsd:appinfo> <map:java-type name="examples.service.MyStruct"/> </xsd:appinfo> </xsd:annotation> <xsd:sequence> <xsd:element name="i" type="xsd:int"/> <xsd:element name="s" nillable="true" type="xsd:string"/> </xsd:sequence> </xsd:complexType> </xsd:schema> </wsdl:types> <wsdl:message name="Service_echo_Response"> <wsdl:part element="ns0:MyStruct_Response" name="response"/> </wsdl:message> <wsdl:message name="Service_echo_1_Request"> <wsdl:part element="ns0:p0" name="p0"/> </wsdl:message> <wsdl:portType name="Service"> <wsdl:operation name="echo" parameterOrder="p0"> <wsdl:input message="tns:Service_echo_1_Request"/> <wsdl:output message="tns:Service_echo_Response"/> </wsdl:operation> </wsdl:portType> <wsdl:binding name="Service" type="tns:Service"> <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/> <wsdl:operation name="echo"> <map:java-operation name="echo" signature="KExleGFtcGxlcy9zZXJ2aWNlL015U3RydWN0OylMZXhhbXBsZXMvc2VydmljZS9NeVN0cnVjdDs="/> <soap:operation soapAction="echo" style="document"/> <wsdl:input> <soap:body use="literal"/> </wsdl:input> <wsdl:output> <soap:body use="literal"/> </wsdl:output> </wsdl:operation> </wsdl:binding> <wsdl:service name="Service"> <wsdl:port binding="tns:Service" name="Service"> <soap:address location="urn:unknown-location-uri"/> </wsdl:port> </wsdl:service> </wsdl:definitions>
On the client side, if you are using dynamic invocation (that is, using service proxy or JAX-RPC, not JAXM), you always need to use your mapping file. A lack of mapping information often results in exceptions while Java/XML (de)serialization is in progress. Also the correct WSDL operation might not be recognized when the service call is made.
For an XMAP file to be used, it must be placed in the same directory as class file of the service interface used by the client side. Note that this is done with the example in Mapping Files in Detail.
![]() | Important |
---|---|
The .xmap file must be named after the service implementation class or an interface which this class implements (except for the filename extension, which must be changed to .xmap). This .xmap file must be placed in the same package as the implementation class so that it will be in the application classpath. |
The situation on the service side is the same as on the client side, except in one case. If you have WSO2 SOA Enablement Server generate WSDL for you automatically, the mapping information will be put directly into WSDL file and you will no longer need a mapping file on the service side (however, the client's need remains). When using a WSDL that was not generated by WSO2 SOA Enablement Server, you need the mapping file on the service, too. In such cases the conditions described above hold.
![]() | Important |
---|---|
The .xmap file must be named after the service implementation class or an interface which this class implements (except for the filename extension, which must be changed to .xmap). This .xmap file must be placed in the same package as the implementation class so that it will be in the application classpath. |