Stas,

I've thought about it a little more and realized that the code change below,
while required to get the Address and PhoneNumber classes to serialize
properly, is still not sufficient.  Body entries are required to implement
Serializer (the exception message is right on the mark), which means you
need a "MethodMessage" or similar class, which would contain a list of
Parameters, to be the body entry.

Scott Ncihol

----- Original Message -----
From: "Scott Nichol" <[EMAIL PROTECTED]>
To: <[EMAIL PROTECTED]>
Sent: Thursday, June 13, 2002 11:49 PM
Subject: Re: Messaging and Bean Serialization


Stas,

I think the initial problem was really that Message#send does not use a
user-defined type mapping.  What you really wanted to do was:

     Envelope msgEnv = new Envelope();
     Message msg = new Message ();
     Body body = new Body();
     Vector bodyEntries = new Vector();
     ...
     bodyEntries.addElement(new Bean(Address.class, address));
     body.setBodyEntries(bodyEntries);
     msgEnv.setBody(body);

 **  SOAPHTTPConnection st = new SOAPHTTPConnection();
 **  st.send (new URL (args[0]), "urn:this-is-the-action-uri", null, msgEnv,
smr, new SOAPContext());

This way, the mapping you defined actually gets used to marshal everything.
(Note: I *think* this is true, but I did not actually write/compile/run the
code!)

Assuming this successfully serializes things, I notice that your message
does not specify a method.  You've made an Address the body entry, yet what
you really need it to be is a "MethodMessage".  This would look like the
"outbound" half of RPCMessage, e.g. the buildEnvelope, marshal,
serializeParams methods.  Such a class would produce the envelope you want
your body to have.

Scott Nichol

----- Original Message -----
From: "Turzhavskiy, Stanislav (GMI-EDSI)" <[EMAIL PROTECTED]>
To: <[EMAIL PROTECTED]>
Sent: Wednesday, June 12, 2002 12:53
Subject: Messaging and Bean Serialization


> Good time of day to you,
>
> I tried this question on soap-user, but didn't get any answers, maybe you
can help me..
>
> I'm trying to modify the "messaging" example to send an object from
address (from "addressbook" example) object using bean encoding.  The code
is at the end of the message.
>
> If I just run the code I get the following exception:
>
> java.lang.IllegalArgumentException: Body entries must implement the
Serializer interface.
> at org.apache.soap.Body.marshall(Body.java:166)
> at org.apache.soap.Envelope.marshall(Envelope.java:195)
> at com.ml.edsi.mif.soap.test.SendMessage.main(SendMessage.java:86)
>
> To fix it I modified the Address and PhoneNumber classes to extend
BeanSerializer which implements Serializer and should work for beans.
>
> In this case I get the following exception:
>
> java.lang.NullPointerException
> at
org.apache.soap.encoding.soapenc.SoapEncUtils.generateStructureHeader(SoapEn
cUtils.java:160)
> at
org.apache.soap.encoding.soapenc.SoapEncUtils.generateStructureHeader(SoapEn
cUtils.java:116)
> at
org.apache.soap.encoding.soapenc.BeanSerializer.marshall(BeanSerializer.java
:86)
> at org.apache.soap.Body.marshall(Body.java:146)
> at org.apache.soap.Envelope.marshall(Envelope.java:195)
> at com.ml.edsi.mif.soap.test.SendMessage.main(SendMessage.java:86)
>
> The reason it that at in the org.apache.soap.Body(145)  the application
sends null instead of soap context to BodyEntry.marshal.  So I fixed it by
replacing
>
> ((Serializer)bodyEntry.value).marshall(actualEncStyle,
>                                                    bodyEntry.type,
>                                                    bodyEntry.value,
>                                                    null, //****Here is the
change***
>                                                    sink,
>                                                    nsStack,
>                                                    xjmr,
>                                                    ctx);
>
> with
>
> ((Serializer)bodyEntry.value).marshall(actualEncStyle,
>                                                    bodyEntry.type,
>                                                    bodyEntry.value,
>                                                    ctx, //****Here is the
change***
>                                                    sink,
>                                                    nsStack,
>                                                    xjmr,
>                                                    ctx);
>
> At this point marshaling works, but I get this strange output from the
marshaler:
>
> <?xml version="1.0" encoding="UTF-8"?>
> <SOAP-ENV:Envelope
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/";
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
xmlns:xsd="http://www.w3.org/2001/XMLSchema";>
> <SOAP-ENV:Body>
> <[Parts={}] xmlns:ns1="urn:po-processor" xsi:type="ns1:address"
SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/";>
> <phoneNumber xsi:type="ns1:phone">
> <exchange xsi:type="xsd:string">exch</exchange>
> <areaCode xsi:type="xsd:int">201</areaCode>
> <number xsi:type="xsd:string">671-1572</number>
> </phoneNumber>
> <zip xsi:type="xsd:int">10100</zip>
> <streetNum xsi:type="xsd:int">95</streetNum>
> <state xsi:type="xsd:string">NJ</state>
> <streetName xsi:type="xsd:string">Green</streetName>
> <city xsi:type="xsd:string">JCity</city>
> </[Parts={}]>
> </SOAP-ENV:Body>
> </SOAP-ENV:Envelope>
>
> And the application fails when I try to send a message:
>
> java.lang.NullPointerException
> at
org.apache.soap.encoding.soapenc.SoapEncUtils.generateStructureHeader(SoapEn
cUtils.java:129)
> at
org.apache.soap.encoding.soapenc.SoapEncUtils.generateStructureHeader(SoapEn
cUtils.java:116)
> at
org.apache.soap.encoding.soapenc.BeanSerializer.marshall(BeanSerializer.java
:86)
> at org.apache.soap.Body.marshall(Body.java:155)
> at org.apache.soap.Envelope.marshall(Envelope.java:195)
> at
org.apache.soap.transport.http.SOAPHTTPConnection.send(SOAPHTTPConnection.ja
va:273)
> at org.apache.soap.messaging.Message.send(Message.java:123)
> at com.ml.edsi.mif.soap.test.SendMessage.main(SendMessage.java:92)
>
>
>
>
> Am I doing something fundamentally wrong?  I will appreciate any help.
>
> Beast regards,
>
> Stas.
>
>
> /*************************************************
> * com.ml.edsi.mif.soap.test.SendMessage
> *****************************************************/
>
>
>
> public class SendMessage {
>   public static void main (String[] args) throws Exception {
>     if (args.length != 2) {
>       System.err.println ("Usage: java " + SendMessage.class.getName () +
>                           " SOAP-router-URL envelope-file");
>       System.exit (1);
>     }
>
>     SOAPMappingRegistry smr = new SOAPMappingRegistry();
>     BeanSerializer beanSer = new BeanSerializer();
>
>     smr.mapTypes(Constants.NS_URI_SOAP_ENC,
>                  new QName("urn:po-processor", "address"),
>                  com.ml.edsi.mif.soap.test.Address.class, beanSer,
beanSer);
>     smr.mapTypes(Constants.NS_URI_SOAP_ENC,
>                  new QName("urn:po-processor", "phone"),
>                  com.ml.edsi.mif.soap.test.PhoneNumber.class, beanSer,
beanSer);
>
>     Envelope msgEnv = new Envelope();
>
>     Message msg = new Message ();
>
>     Body body = new Body();
>     Vector bodyEntries = new Vector();
>
>         PhoneNumber phoneNumber = new PhoneNumber();
> phoneNumber.setAreaCode(201);
> phoneNumber.setExchange("exch");
> phoneNumber.setNumber("671-1572");
>
> Address address = new Address();
> address.setStreetNum(95);
> address.setStreetName("Green");
> address.setCity("JCity");
> address.setState("NJ");
> address.setZip(10100);
> address.setPhoneNumber(phoneNumber);
>
>     bodyEntries.addElement(new Bean(Address.class, address));
>
>     body.setBodyEntries(bodyEntries);
>     msgEnv.setBody(body);
>
>     SOAPContext reqCtx = new SOAPContext();
>
>     StringWriter payloadSW = new StringWriter ();
>
>     msgEnv.marshall (payloadSW, smr, reqCtx); //use smr used for encoding
instead of null
>
>     String payload = payloadSW.toString ();
>
>     System.out.println(payload);
>
>     msg.send (new URL (args[0]), "urn:this-is-the-action-uri", msgEnv);
>
>     // receive whatever from the transport and dump it to the screen
>     System.out.println ("RESPONSE:");
>     System.out.println ("--------");
>     SOAPTransport st = msg.getSOAPTransport ();
>     BufferedReader br = st.receive ();
>     String line;
>     while ((line = br.readLine ()) != null) {
>       System.out.println (line);
>     }
>   }
> }
>
>
>
>
>
>





Reply via email to