users@jax-ws.java.net

Re: Problem with string arrays containing nulls

From: Sekhar Vajjhala <Sekhar.Vajjhala_at_Sun.COM>
Date: Fri, 09 Feb 2007 12:13:12 -0500

In your code,

    @XmlElement(nillable=true)
    private String[] array;

The annnotation @XmlElement(nillable=true) is not required
for a collection property. That is the default.

Sekhar

Egor Samarkhanov wrote:

>Hello !
>
>Thanks for the hint about wrapper bean. I've created the following
>wrapper:
>
>@XmlAccessorType(value=XmlAccessType.FIELD)
>public class StringArrayWrapper
>{
> @XmlElement(nillable=true)
> private String[] array;
>
> public StringArrayWrapper( String[] array ) {
> this.array = array;
> }
>
> public StringArrayWrapper() {
> }
>
> public String[] getArray() {
> return array;
> }
>
> public void setArray( String[] array ) {
> this.array = array;
> }
>}
>
>changed the services's method signature to
>
>@WebMethod()
>public StringArrayWrapper testStringArray( StringArrayWrapper w )
>
>and got the expected result. Moreover, the WCF's service method
>signature is still
>
>string[] testStringArray(string[] arg0)
>
>
>Great! But then I decided to implement the same using Java Type Adapters
>(to keep using String[] on Java side).
>I wrote the simple adapter:
>
>public class AdapterStringArrayToBean extends XmlAdapter<StringArrayWrapper, String[]>
>{
> public String[] unmarshal( StringArrayWrapper wrapper ) throws Exception
> {
> if( wrapper == null )
> return null;
> return wrapper.getArray();
> }
>
> public StringArrayWrapper marshal( String[] s ) throws Exception
> {
> return new StringArrayWrapper( s );
> }
>}
>
>and then changed the service's method signature like this:
>
>@WebMethod()
>public @XmlJavaTypeAdapter(type=String[].class, value=AdapterStringArrayToBean.class) String[] testStringArray( @XmlJavaTypeAdapter(type=String[].class, value=AdapterStringArrayToBean.class) String[] s )
>
>
>After the deployment I got the following method signature in WCF:
>
>public stringArrayWrapper[] testStringArray(stringArrayWrapper[] arg0)
>
>Well, I didn't expect array of wrappers. I thought it should be just the
>wrapper. I checked the WSDL and indeed, maxOccurs="unbounded" is set for
>the arg0 element (line 3):
>
><xs:complexType name="testStringArray">
> <xs:sequence>
> <xs:element name="arg0" type="tns:stringArrayWrapper" maxOccurs="unbounded" minOccurs="0" />
> </xs:sequence>
></xs:complexType>
><xs:complexType name="stringArrayWrapper">
> <xs:sequence>
> <xs:element name="array" type="xs:string" nillable="true" maxOccurs="unbounded" minOccurs="0" />
> </xs:sequence>
></xs:complexType>
>
>
>I guess my adapter is wrong. How can I write the adapter correctly for
>this case?
>
>
>Thanks for your help,
>
>Egor.
>
>
>Thursday, February 8, 2007, 2:52:10 AM, you wrote:
>
>VP> After talking to jaxb experts - there is no jaxb annotation that you can
>VP> put on method parameters to achieve such behaviour. This is something
>VP> that can be handled by JAXWS, where it can generate
>VP> @XmlElement(nillable="true") in the wrapper bean on the property.
>
>VP> However we would need to verify whether such change will be
>VP> non-compliant w.r.t. generated code from such schema by wsimport.
>
>VP> Please go ahead and report and issue at
>VP> http://jax-ws.dev.java.net/servlets/ProjectIssues.
>
>VP> -vivek.
>
>VP> Vivek Pandey wrote:
>
>
>>>The generated schema look ok to me. String[] is mapped to and it seems
>>>correct as per JAXB schema.
>>>
>>><xs:element name="return" type="xs:string" maxOccurs="unbounded"
>>>minOccurs="0"/>
>>>
>>>Which look ok as per JAXB spec and expectedly at runtime the null
>>>element is ignored. So your analysis is correct.
>>>I am wondering if there is any jaxb annotation or some mechanism to
>>>generate such schema. Ccing it to users_at_jaxb alias.
>>>
>>>-vivek.
>>>
>>>
>>>
>>>
>>>
>>>Egor Samarkhanov wrote:
>>>
>>>
>>>>Hi!
>>>>
>>>>I have a problem with string arrays containing nulls (WSIT):
>>>>
>>>>Here is my simple service:
>>>>
>>>>@WebService
>>>>public class MyServiceImpl
>>>>{
>>>> @WebMethod()
>>>> public String[] testStringArray( String[] s )
>>>> {
>>>> return new String[] {"s","",null};
>>>> }
>>>>}
>>>>
>>>>WSIT generates the following WSDL types for it:
>>>>
>>>><xs:schema xmlns:tns="http://wsitproto/"
>>>>xmlns:xs="http://www.w3.org/2001/XMLSchema" version="1.0"
>>>> targetNamespace="http://wsitproto/">
>>>> <xs:element name="testStringArray" type="tns:testStringArray"/>
>>>> <xs:element name="testStringArrayResponse"
>>>>type="tns:testStringArrayResponse"/>
>>>> <xs:complexType name="testStringArray">
>>>> <xs:sequence>
>>>> <xs:element name="arg0" type="xs:string"
>>>>maxOccurs="unbounded" minOccurs="0"/>
>>>> </xs:sequence>
>>>> </xs:complexType>
>>>> <xs:complexType name="testStringArrayResponse">
>>>> <xs:sequence>
>>>> <xs:element name="return" type="xs:string"
>>>>maxOccurs="unbounded" minOccurs="0"/>
>>>> </xs:sequence>
>>>> </xs:complexType>
>>>></xs:schema>
>>>>
>>>>I created WCF client and tried to invoke the service with the new
>>>>String[] {"s","",null} parameter,
>>>>but my service received only two first values (only {"s",""}). The
>>>>last null string is missed.
>>>>
>>>>I examined SOAP envelopes and they look accordingly:
>>>>
>>>>Inbound message:
>>>>
>>>><s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
>>>> <s:Header/>
>>>> <s:Body xmlns:xsd="http://www.w3.org/2001/XMLSchema"
>>>>xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
>>>> <testStringArray xmlns="http://wsitproto/">
>>>> <arg0 xmlns="">s</arg0>
>>>> <arg0 xmlns=""/>
>>>> </testStringArray>
>>>> </s:Body>
>>>></s:Envelope>
>>>>
>>>>Outbound message:
>>>>
>>>><S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
>>>> <S:Body>
>>>> <ns2:testStringArrayResponse xmlns:ns2="http://wsitproto/">
>>>> <return>s</return>
>>>> <return></return>
>>>> </ns2:testStringArrayResponse>
>>>> </S:Body>
>>>></S:Envelope>
>>>>
>>>>As I understand that's because elements are not marked as
>>>>nillable="true" in WSDL.
>>>>I think the correct WSDL types would be as follows:
>>>>
>>>><xs:schema xmlns:tns="http://wsitproto/"
>>>>xmlns:xs="http://www.w3.org/2001/XMLSchema" version="1.0"
>>>> targetNamespace="http://wsitproto/">
>>>> <xs:element name="testStringArray" type="tns:testStringArray"/>
>>>> <xs:element name="testStringArrayResponse"
>>>>type="tns:testStringArrayResponse"/>
>>>> <xs:complexType name="testStringArray">
>>>> <xs:sequence>
>>>> <xs:element name="arg0" type="xs:string"
>>>>maxOccurs="unbounded" minOccurs="0" nillable="true"/>
>>>> </xs:sequence>
>>>> </xs:complexType>
>>>> <xs:complexType name="testStringArrayResponse">
>>>> <xs:sequence>
>>>> <xs:element name="return" type="xs:string"
>>>>maxOccurs="unbounded" minOccurs="0" nillable="true"/>
>>>> </xs:sequence>
>>>> </xs:complexType>
>>>></xs:schema>
>>>>
>>>>(note the nillable attributes)
>>>>
>>>>And the question is how can I make WSIT generate and correctly handle
>>>>nillable types in WSDL?
>>>>
>>>>
>>>>----
>>>>Egor
>>>>
>>>>
>>>>---------------------------------------------------------------------
>>>>To unsubscribe, e-mail: users-unsubscribe_at_jax-ws.dev.java.net
>>>>For additional commands, e-mail: users-help_at_jax-ws.dev.java.net
>>>>
>>>>
>>>>
>>>>
>>>---------------------------------------------------------------------
>>>To unsubscribe, e-mail: users-unsubscribe_at_jax-ws.dev.java.net
>>>For additional commands, e-mail: users-help_at_jax-ws.dev.java.net
>>>
>>>
>>>
>
>VP> ---------------------------------------------------------------------
>VP> To unsubscribe, e-mail: users-unsubscribe_at_jax-ws.dev.java.net
>VP> For additional commands, e-mail: users-help_at_jax-ws.dev.java.net
>
>
>
>
>
>
>
>---------------------------------------------------------------------
>To unsubscribe, e-mail: users-unsubscribe_at_jax-ws.dev.java.net
>For additional commands, e-mail: users-help_at_jax-ws.dev.java.net
>
>
>