[
http://issues.apache.org/jira/browse/AXIS-2029?page=comments#action_66946 ]
Mark Tye commented on AXIS-2029:
--------------------------------
The diff is a step in the right direction: it's certainly better to throw a
DOMException with a meaningful error message than a totally unhelpful
ClassCastException. However, it would probably make more sense to throw a
SOAPException, since it's only within the context of SOAP that Header elements
are prohibited from having text nodes as their immediate children. From a
purely DOM perspective, it's perfectly legal to add a text node to the Header
element.
However, I'm not sure that throwing an exception is always the right thing to
do here. While the SOAP specs (and the javadoc comments of the
javax.xml.soap.SOAPHeader interface) forbid the addition of Text node children
to a SOAP Header element, that doesn't really address the whitespace issue I
mentioned in my original comment.
For example, if you're using the SAAJ API to build the response envelope in a
message-style service invocation (e.g. public void method(SOAPEnvelope req,
SOAPEnvelope resp)) and you're using a parsed DOM tree or SAX events as input,
you might be tempted, as I was, to use the SOAPElement.addTextNode(String)
method to handle the character data the parser feeds you. That works just fine
if the SOAPElement you're adding text to is an instance of SOAPHeaderElement,
SOAPBodyElement, or even SOAPBody - and it *used* to work for instances of
SOAPHeader under Axis 1.2 beta - but now it results in a ClassCastException.
You get this exception even if the String you're trying to add contains only
whitespace - which is perfectly legal in the context of a SOAP Header.
I suggest that the SOAPHeader.appendChild(Node) method should check to see if
the node being appended is an instance of Text (or maybe CharacterData?). If it
is, and the node contains only whitespace, no exception should be thrown.
(Presumably, the whitespace can be safely ignored).
An alternative might be to implement the addTextNode(String) method in
SOAPHeader, overriding the generic implementation in MessageElement, and throw
an exception if the parameter string contains non-whitespace characters. This
would push the point of failure closer to source of the problem, which is
generally a good design principle.
If you take the latter approach, you probably want to do the same thing for the
Axis SOAPBody and SOAPEnvelope implementations, too.
(Regarding Venkat's comment about the SOAP 1.2 spec, I should point out that a
SOAP header *block* element information item is not the same thing as the SOAP
Header element information item itself - although that's anything but obvious
at first glance. The sentence that Venkat references in section 5.2.1 allows
the *children* of the SOAP Header to have character information, like so:
<SOAP-ENV:Header>
<tns:element1>
this text is permitted
</tns:element1>
</SOAP-ENV:Header>
Whereas section 5.2 specifies that the immediate children of the SOAP Header
*must* be elements, which would seem to disallow text such as this:
<SOAP-ENV:Header>
this text is not permitted
</SOAP-ENV:Header>
The SOAP 1.1 spec says more or less the same thing, but without the fussy
nomenclature.)
> SOAPHeader.appendChild() throws unexpected ClassCastException
> -------------------------------------------------------------
>
> Key: AXIS-2029
> URL: http://issues.apache.org/jira/browse/AXIS-2029
> Project: Axis
> Type: Bug
> Components: Basic Architecture, SAAJ
> Versions: 1.2
> Environment: Windows XP Pro/WebSphere 4.0
> Reporter: Mark Tye
> Attachments: 2029.diff
>
> The class org.apache.axis.message.SOAPHeader overrides the
> appendChild(org.w3c.dom.Node) method of org.apache.axis.message.NodeImpl in
> such a way that it breaks the contract of the
> org.3c.dom.Node.appendChild(org.w3c.dom.Node) interface.
> Here's the implementation of appendChild(Node) in SOAPHeader:
> 390 public Node appendChild(Node newChild) throws DOMException {
> 391 SOAPHeaderElement headerElement = null;
> 392 if(newChild instanceof SOAPHeaderElement)
> 393 headerElement = (SOAPHeaderElement)newChild;
> 394 else
> 395 headerElement = new SOAPHeaderElement((Element)newChild);
> 396 try {
> 397 addChildElement(headerElement);
> 398 } catch (SOAPException e) {
> 399 throw new
> DOMException(DOMException.INVALID_STATE_ERR,e.toString());
> 400 }
> 401 return headerElement;
> 402 }
> This works fine if the newChild Node parameter is an instance of
> SOAPHeaderElement or org.w3c.dom.Element, but any other subclass of Node will
> cause a ClassCastException to be thrown at line 395.
> It's reasonable to expect that in most cases, the Node being appended to a
> SOAP Header will be DOM Element representing a header entry. However, there
> is no prohibition in the SOAP 1.1 Note or the SOAP 1.2 Recommendation against
> whitespace before, after, or in between the header entries of a SOAP Header.
> Some parsers will render such whitespace as Text nodes, which will cause a
> ClassCastException in the appendChild() method.
> Even if a deliberate design decision has been made not to support whitespace
> in the SOAPHeader class, the appendChild(Node) method should probably do
> something more elegant than throw a ClassCastException if the Node parameter
> is a Text node containing whitespace.
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
http://issues.apache.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see:
http://www.atlassian.com/software/jira