ServersSending a Complex Request Page 13

Sending a Complex Request Page 13

ServerWatch content and product recommendations are editorially independent. We may make money when you click on links to our partners. Learn More.




As we have seen, Apache SOAP processes all simple types by default. In the case of a response or an object send, this must be
defined so as to be understandable by both parties. For this task, the Apache SOAP implementation gives us some classes to define t
hese objects easily.

Let”s take the example of a Web service that supplies a directory. The request must, from a name sent t
o the server, find its characteristics — the address, telephone number, town, and so on. The queried service will send back a much
more complex response than the calculator service.

According to the description of the service, the server sends back a compl
ex object in the form of an XML hierarchy. The main difficulty is knowing how to process the response issued by the server when it d
oes not send back a known type.

If we use the same development as before, the SOAP stream will be correctly formulated on ei
ther side, but the response will not be understood in Java, since it will have no instructions as to how to process the received str
eam.

  &ltSOAP-ENV:Envelope xmlns:SOAP- ENV="http://schemas.xmlsoap.org/soa
p/ envelope/"xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance" xmlns:xsd="http://www.w3.org/1999/XMLSchema"> &ltSOAP-ENV:Body
> &ltns1:getAddressFromName xmlns:ns1="urn:AddressFetcher" SOAP- ENV:encodingStyle="http://schemas.xmlsoap.org/ soap/encoding/"&g
t; &ltnameToLookup xsi:type="xsd:string">Bertrand Goupil  
  

The Java client does not understand the response and throws an exception. This exception clearl
y indicates to us that the program has not found a method to deserialize the response, which is of the type urn:xml-soap_address-dem
o:address. In fact, the server sends back the following response:

 &ltreturn xmlns:ns2="urn:xml-soap-address-demo" xsi:type
="ns2:address"> &ltphoneNumber xsi:type="ns2:phone"> &ltexchange xsi:type="xsd:string">0 &ltareaCode xsi:ty
pe="xsd:int">33 &ltnumber xsi:type="xsd:string">155932600  &ltzip xsi:type="x
sd:int">93200 &ltstreetNum xsi:type="xsd:int">268 &ltstate xsi:type="xsd:string">Francee> &ltstreetName xsi:type="xsd:string">ave du prisident Wilson &ltcity xsi:type="xsd:string">Saint Denis&
lt/city>  

The XML response indicates to us that there are two unknown types belonging to the namespace ns
2: xsi:type=”ns2:address” and “xsi:type=”ns2:phone”

Each response type sent by SOAP must be serialized and deserialized betwe
en the client and the server. If these types do not belong to any known definition, we must then indicate which deserializer we have
to use.

To define a complex type, we use the BeanSerializer class to deserialize the server response. Each object received
or sent must be programmed as a JavaBean (set and get methods), with XML elements of the return message as parameters.

In the
example below, and according to the previous SOAP message, streetNum is an int type, and streetName is a String type.

...
public void setStreetNum(int streetNum){ this.streetNum = streetNum; } public int getStreetNum(){ return streetNum; } public void se
tStreetName(String streetName){ this.streetName = streetName; } public String getStreetName(){ return streetName; } ... 

Th
e definition of a new type must be included in Apache SOAP”s serialization/deserialization mechanism. To do this, we must use the S
OAPMappingRegistry class. In this way, the object will contain all the information to process new types. This class enables us to de
fine SOAP/JAVA mapping through the mapTypes method.

In our example, we have a complex type comprising two objects: Address an
d PhoneNumber.

 import org.apache.soap.encoding.SOAPMappingRegistry; import org.apache.soap.encoding.soapenc.BeanSerializer
; ... SOAPMappingRegistry smr = new SOAPMappingRegistry(); BeanSerializer beanSer = new BeanSerializer(); smr.mapTypes(Constants.NS_
URI_SOAP_ENC, new QName("urn:xml-soap-address-demo", "address"), Address.class, beanSer, beanSer); smr.mapTypes(Constants.NS_URI_SOA
P_ENC, new QName("urn:xml-soap-address-demo", "phone"), PhoneNumber.class, beanSer, beanSer); Call call = new Call(); call.setSOAPMa
ppingRegistry(smr); ... 

The setSOAPMappingRegistry method will link the definition of new types and the processing of the
response. Therefore it is vital that it is added.

It is important to note that the classes Address.class and PhoneNumber.cla
ss must be present on the client side for the application to function well. If we develop an application calling a service that has
never been contacted, it is essential to know the structure of the message to define the mapping.

Even so, it is very diffic
ult to know the structure of a message. If by chance you do know the XML structure, you do not need to create a JavaBean to define t
he mapping, as you can process the XML tags as a character string. However, when programming the mapping, all elements of the SOAP r
esponse (except the envelope) on all levels will have to be mapped.

In our service:

 SOAPMappingRegistry smr = new
SOAPMappingRegistry (); StringDeserializer sd = new StringDeserializer (); ... smr.mapTypes (Constants.NS_URI_SOAP_ENC, new QName ("
", "street"), null, null, sd); smr.mapTypes (Constants.NS_URI_SOAP_ENC, new QName ("", "city"), null, null, sd); smr.mapTypes (Const
ants.NS_URI_SOAP_ENC, new QName ("", "state"), null, null, sd); ... 

Get the Free Newsletter!

Subscribe to Daily Tech Insider for top news, trends & analysis

Latest Posts

Related Stories