So I found the answer to my question. When sending the data to XFire,
the namespaces must be set on the fields of the complex data type, as
below:
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/
envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:ns4="http://rpc.whisper.ucsc.edu"
xmlns:ns5="http://core.whisper.ucsc.edu"
>
...
<ns4:addItemToLibrary>
<in0>
<ns5:authors>
<AuthorData>
<ns5:person>false</ns5:person>
<ns5:organizationName>test org</ns5:organizationName>
</AuthorData>
</ns5:authors>
<ns5:dateCreated></ns5:dateCreated>
<ns5:primaryKeyword>test2</ns5:primaryKeyword>
<ns5:title>test</ns5:title>
</in0>
Note the ns5: on the person and organizationName fields.
The only part that I'm left confused about though is why XFire
doesn't put (or maybe doesn't need to put) the namespaces on outgoing
messages, as below:
<getAllItemsInfoResponse xmlns="http://rpc.whisper.ucsc.edu">
<out xmlns="http://rpc.whisper.ucsc.edu">
<ns1:LibraryItemInfoData xmlns:ns1="http://
core.whisper.ucsc.edu">
<UUID xmlns="http://
core.whisper.ucsc.edu">9c2fa34d-4d2d-4907-9736-38f72d3c705d</UUID>
<authors xmlns="http://core.whisper.ucsc.edu">
<AuthorData>
<familyName xsi:nil="true" />
<firstName xsi:nil="true" />
<fullName>Cuba</fullName>
<organizationName>Cuba</organizationName>
<otherNames xsi:nil="true" />
<person>false</person>
<username xsi:nil="true" />
</AuthorData>
</authors>
<dateCreated xmlns="http://
core.whisper.ucsc.edu">1978-05-09T00:00:00-07:00</dateCreated>
<dateEntered xmlns="http://
core.whisper.ucsc.edu">2006-04-19T16:31:51.725-07:00</dateEntered>
<encoding xmlns="http://core.whisper.ucsc.edu"
xsi:nil="true" />
<keywords xmlns="http://core.whisper.ucsc.edu">
<ns2:string xmlns:ns2="http://
rpc.whisper.ucsc.edu">cuban</ns2:string>
<ns2:string xmlns:ns2="http://
rpc.whisper.ucsc.edu">raisens</ns2:string>
<ns2:string xmlns:ns2="http://
rpc.whisper.ucsc.edu">recipe</ns2:string>
<ns2:string xmlns:ns2="http://
rpc.whisper.ucsc.edu">rice</ns2:string>
</keywords>
<lastModified xmlns="http://
core.whisper.ucsc.edu">2006-04-19T16:31:51.725-07:00</lastModified>
<mimeType xmlns="http://core.whisper.ucsc.edu">text/rtf</
mimeType>
<primaryKeyword xmlns="http://
core.whisper.ucsc.edu">recipe</primaryKeyword>
<size xmlns="http://core.whisper.ucsc.edu">1128</size>
<title xmlns="http://core.whisper.ucsc.edu">cuban rice</
title>
<typeExtension xmlns="http://
core.whisper.ucsc.edu">.rtf</typeExtension>
<username xmlns="http://core.whisper.ucsc.edu">mark</
username>
<whisperId xmlns="http://
core.whisper.ucsc.edu">631edcaf69edfd75f5816706b89016356ba28c6a</
whisperId>
</ns1:LibraryItemInfoData>
</out>
</getAllItemsInfoResponse>
Mark
On Apr 19, 2006, at 3:34 PM, Mark Slater wrote:
On Apr 19, 2006, at 2:07 PM, Mika Göckel wrote:
I'm a little bit confused, because you mixed System.out and log.
Could it be that the first element of the List returns null, it
fails with a NPE in author.isPerson() and we don't see the
System.out logs?
M.
Bloody hell. Thanks for catching that. I'm teaching a beginning
programming course this quarter (in Java), and spent all afternoon
yesterday telling students how to use System.out.println().
After fixing the logging statements, I'm finally able to see the
exception that's getting thrown. Its a NullPointerException within
the proxy for my Author object.
2006-04-19 15:11:26,734 INFO
[edu.ucsc.whisper.core.LibraryItemInfoData] - <Setting authors to:
[EMAIL PROTECTED]>
2006-04-19 15:11:26,734 INFO
[edu.ucsc.whisper.core.LibraryItemInfoData] - <author =
[EMAIL PROTECTED]>
2006-04-19 15:11:26,738 INFO
[edu.ucsc.whisper.core.LibraryItemInfoData] - <Exception while
extracting authors>
java.lang.NullPointerException
at $Proxy13.isPerson(Unknown Source)
at edu.ucsc.whisper.core.AuthorData.<init>(AuthorData.java:34)
at edu.ucsc.whisper.core.LibraryItemInfoData.setAuthors
(LibraryItemInfoData.java:273)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke
(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke
(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at
org.codehaus.xfire.aegis.type.basic.BeanType.writeProperty
(BeanType.java:223)
The method signature for isPerson() is:
public final boolean isPerson()
So that made me think that perhaps a value wasn't sent for that
field, but the SOAP message did send one (I've formatted this to
make it more readable):
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/
envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:ns4="http://rpc.whisper.ucsc.edu"
xmlns:ns5="http://core.whisper.ucsc.edu"
>
...
<in0>
<ns5:authors>
<AuthorData>
<person>true</person>
<familyName>Slater</familyName>
<firstName>Mark</firstName>
<otherNames>David</otherNames>
<username>mark</username>
</AuthorData>
</ns5:authors>
<ns5:dateCreated>2006-02-23T00:00:00-08:00</ns5:dateCreated>
<ns5:primaryKeyword>Directions</ns5:primaryKeyword>
<ns5:title>Directions</ns5:title>
<ns5:keywords>
<ns4:string>stephen</ns4:string>
<ns4:string>alameda</ns4:string>
</ns5:keywords>
</in0>
The WSDL for the service is below.
So I tried changing the type from the Author interface to the
AuthorData implementation class, and added logging statements to
the constructors and property setters. With those changes, the
output I get is:
2006-04-19 15:23:40,710 DEBUG
[org.springframework.web.servlet.handler.SimpleUrlHandlerMapping] -
<Looking up handler for [/LibraryService]>
2006-04-19 15:23:40,710 DEBUG
[org.springframework.web.servlet.DispatcherServlet] - <Testing
handler adapter
[EMAIL PROTECTED]
f649]>
2006-04-19 15:23:40,827 INFO [edu.ucsc.whisper.core.AuthorData] -
<Making new AuthorData with default Constructor>
2006-04-19 15:23:40,828 INFO
[edu.ucsc.whisper.core.LibraryItemInfoData] - <Setting authors to:
[{AuthorData: authorType=person; fullName=}]>
2006-04-19 15:23:40,828 INFO
[edu.ucsc.whisper.core.LibraryItemInfoData] - <author =
{AuthorData: authorType=person; fullName=}>
2006-04-19 15:23:40,829 INFO
[edu.ucsc.whisper.core.LibraryItemInfoData] - <authorClass = class
edu.ucsc.whisper.core.AuthorData>
2006-04-19 15:23:40,829 INFO
[edu.ucsc.whisper.core.LibraryItemInfoData] - <authorClass
interfaces = [Ljava.lang.Class;@33f21d>
2006-04-19 15:23:40,829 INFO [edu.ucsc.whisper.core.AuthorData] -
<Making new AuthorData with existing Author>
2006-04-19 15:23:40,829 INFO
[edu.ucsc.whisper.core.LibraryItemInfoData] - <authors list is now:
[{AuthorData: authorType=person; fullName=}]>
So you can see that the class is begin created, but the properties
aren't being set. I'd be willing to bet that this is the cause of
the NullPointerException when the dynamic proxy for the Author
interface is used instead of the concrete class. And it brings me
back to my question from last night: Is the AuthorData part of my
message formatted/layed out correctly, and if not, what should it
look like?
Thanks,
Mark
WSDL for the types involved.
<wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:ns1="http://core.whisper.ucsc.edu"
xmlns:soap11="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:soap12="http://www.w3.org/2003/05/soap-envelope"
xmlns:soapenc11="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:soapenc12="http://www.w3.org/2003/05/soap-encoding"
xmlns:tns="http://rpc.whisper.ucsc.edu"
xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://rpc.whisper.ucsc.edu">
<wsdl:types>
<xsd:schema targetNamespace="http://core.whisper.ucsc.edu"
elementFormDefault="qualified" attributeFormDefault="qualified">
<xsd:complexType name="LibraryItemInfoData">
<xsd:sequence>
<xsd:element name="UUID" type="xsd:string" minOccurs="0"
nillable="true" />
<xsd:element name="authors" type="ns1:ArrayOfAuthorData"
minOccurs="0" nillable="true" />
<xsd:element name="dateCreated" type="xsd:dateTime"
minOccurs="0" nillable="true" />
<xsd:element name="dateEntered" type="xsd:dateTime"
minOccurs="0" nillable="true" />
<xsd:element name="encoding" type="xsd:string"
minOccurs="0" nillable="true" />
<xsd:element name="keywords" type="tns:ArrayOfString"
minOccurs="0" nillable="true" />
<xsd:element name="lastModified" type="xsd:dateTime"
minOccurs="0" nillable="true" />
<xsd:element name="mimeType" type="xsd:string"
minOccurs="0" nillable="true" />
<xsd:element name="primaryKeyword" type="xsd:string"
minOccurs="0" nillable="true" />
<xsd:element name="size" type="xsd:long" minOccurs="0" />
<xsd:element name="title" type="xsd:string" minOccurs="0"
nillable="true" />
<xsd:element name="typeExtension" type="xsd:string"
minOccurs="0" nillable="true" />
<xsd:element name="username" type="xsd:string"
minOccurs="0" nillable="true" />
<xsd:element name="whisperId" type="xsd:string"
minOccurs="0" nillable="true" />
<xsd:any minOccurs="0" maxOccurs="unbounded" />
</xsd:sequence>
<xsd:anyAttribute />
</xsd:complexType>
<xsd:complexType name="ArrayOfAuthorData">
<xsd:sequence>
<xsd:element name="AuthorData" type="ns1:AuthorData"
nillable="true" minOccurs="0" maxOccurs="unbounded" />
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="AuthorData">
<xsd:sequence>
<xsd:element name="familyName" type="xsd:string"
minOccurs="0" nillable="true" />
<xsd:element name="firstName" type="xsd:string"
minOccurs="0" nillable="true" />
<xsd:element name="fullName" type="xsd:string"
minOccurs="0" nillable="true" />
<xsd:element name="organizationName" type="xsd:string"
minOccurs="0" nillable="true" />
<xsd:element name="otherNames" type="xsd:string"
minOccurs="0" nillable="true" />
<xsd:element name="person" type="xsd:boolean"
minOccurs="0" />
<xsd:element name="username" type="xsd:string"
minOccurs="0" nillable="true" />
<xsd:any minOccurs="0" maxOccurs="unbounded" />
</xsd:sequence>
<xsd:anyAttribute />
</xsd:complexType>
<xsd:complexType name="ArrayOfString">
<xsd:sequence>
<xsd:element name="string" type="xsd:string"
nillable="true" minOccurs="0" maxOccurs="unbounded" />
</xsd:sequence>
</xsd:complexType>