Details
Description
[Introduction]:
Maybe you have known that, the axis-c-1.5final's "nillable" dealing is completely wrong.
I found that axis-c-1.6beta has taken some improvement on this area, it's good.
But after really verify axis-c-1.6beta, I found axis-c-1.6beta seems has NOT resolved the old nillable issue correctly.
At first, the design of "nillable" is too strange and hard-for-maintain in axis-c-1.6beta.
The W3C's standard set default of "nillable" to "false", but axis-c-1.6beta set it's default to "true" in related constructor.
Anyway, if axis-c-1.6beta can deal with "nillable" carefully & correctly in inner logic, there will has no problem.
But after verify, I found that axis-c-1.6beta seems does not deal with "nillable" correctly in case of minOccurs="0".
This problem occurred in nearly all XSD types.
The below is a sample which has been verified by me, which indicate that axis-c-1.6beta has problem to deal with "nillable" in case of minOccurs="0".
[Error Statement]:
The below is a piece of WSDL which used by me:
... ...
<xs:element name="TestingResponse">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" name="testcase" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
... ...
I created server code by axis-c-1.6beta on this WSDL, wrote the related code logic(demo purpose only) inside server module like the below:
xsd_string_Array * MyTesting::Testing(xsdstring Value0,xsdstring Value1,xsd_string Value2)
{
//<mxiong debug 2006/5/19
xsd_string_Array* pIDs = new xsd_string_Array();
xsd_string* p = new xsd_string[3];
p[0] = strdup("");
p[1] = strdup("");
p[2] = strdup("2");
pIDs->set(p,3);
return pIDs;
//>mxiong debug 2006/5/19
}
I build my server module and run, **TESTING IT BY A CLIENT APPLICATION WHICH SPEAK THE SAME WSDL**, the response looks like this:
... ...
<TestingResponse xmlns="... ...">;
<testcase xsi:nil="true"></testcase>
<testcase xsi:nil="true"></testcase>
<testcase>2</testcase>
</TestingResponse>
... ...
You can found that the response xsi:nil="true" is wrong.(because my schema does not allow xsi:nil="true", my schema means xsi:nil="false" indeed for it's the default setting according to W3C's standard )
That will cause my client application to decline the response since it does not follow contracted schema.
[My Solution]:
After analyzing and debug to axis-c-1.6beta code, I modified soap/xsd/String.cpp, it became OK.
The correct response looks like the below:
... ...
<TestingResponse xmlns="... ...">;
<testcase></testcase>
<testcase></testcase>
<testcase>2</testcase>
</TestingResponse>
... ...
Thus my client application can accept the response correctly and succeed to complete the whole session.
My detail modification is like the below:
String::String(const xsd__string value)
{
#ifdef ENABLE_AXISTRACE
if (axiscpp::AxisTrace::isTraceOn())
axiscpp::AxisTrace::traceEntry("String", "String", this, 1,
TRACETYPE_STRING, 0, ((void*)&value)); /* AUTOINSERTED TRACE */
#endif
//<mxiong debug 2006/5/19
// if (value)
//
//>mxiong debug 2006/5/19
{
#ifdef ENABLE_AXISTRACE
if (axiscpp::AxisTrace::isTraceOn())
axiscpp::AxisTrace::traceExit("String", "String", this, 0); /* AUTOINSERTED TRACE */
#endif
return;
}
}
AxisChar* String::serialize(const xsd__string value) throw (AxisSoapException)
{
#ifdef ENABLE_AXISTRACE
if (axiscpp::AxisTrace::isTraceOn())
axiscpp::AxisTrace::traceEntry("String", "serialize", this, 1,
TRACETYPE_STRING, 0, ((void*)&value)); /* AUTOINSERTED TRACE */
#endif
MinLength* minLength= getMinLength();
//<mxiong debug 2006/5/19
unsigned int nLen = 0;
//>mxiong debug 2006/5/19
if (minLength->isSet())
{
//<mxiong debug 2006/5/19
if (NULL != value)
{
nLen = strlen(value);
}
if (nLen < (unsigned int) minLength->getMinLength())
//>mxiong debug 2006/5/19
// if (strlen(value) < (unsigned int) minLength->getMinLength())
}
delete minLength;
MaxLength* maxLength = getMaxLength();
if (maxLength->isSet())
{
//<mxiong debug 2006/5/19
// if (strlen(value) > (unsigned int) maxLength->getMaxLength())
if (nLen > (unsigned int) maxLength->getMaxLength())
//>mxiong debug 2006/5/19
}
delete maxLength;
Length* length = getLength();
if (length->isSet())
{
//<mxiong debug 2006/5/19
if (nLen != (unsigned int) length->getLength())
//>mxiong debug 2006/5/19
// if (strlen(value) != (unsigned int) length->getLength())
}
delete length;
//<mxiong debug 2006/5/19
AxisString valueAsString;
if (NULL != value)
{
valueAsString = value;
} else
{
valueAsString = "";
}
//>mxiong debug 2006/5/19
// AxisString valueAsString = value;
AxisChar* serializedValue = (AxisChar*) replaceReservedCharacters(valueAsString).c_str();
IAnySimpleType::serialize(serializedValue);
So I think axis-c-1.6beta has bug in dealing with "nillable" for nearly all the XSD types, especially for String type(but not only for String type, but also other types) as my sample indicated.
[My Suggestion]
Would you like to give it a careful check to correct this problem in axis-c-1.6beta?
My code modification may be regarded as a candicate solution for you to resolve this problem, but I think there may has some better detail design for axis-c-1.6beta on "nillable" area.