I am trying to send TIFF images to a web service which accepts the image in the following way (this is just a fragment of a larger WSDL of course):
<complexType name="ArrayOfImage">
<sequence>
<element maxOccurs="unbounded" name="image" type="xsd:hexBinary"/>
</sequence>
</complexType>
The data is loaded in the following way, where the enclosingType is generated by JAX-WS RI (JAX-WS RI 2.1.7-b01-
):
final List<byte[]> imgData = new LinkedList<byte[]>();
for (final Iterator<File> iterator = files.iterator(); iterator.hasNext(); ) {
imgData.add(Files.toByteArray(iterator.next())); //Files class from Guava release 13
}
enclosingType.setArrayOfImage(imgData);
When the image is sent to the remote webservice, I get errors of the following style:
javax.xml.ws.soap.SOAPFaultException: org.xml.sax.SAXParseException: An invalid XML character (Unicode: 0x0) was found in the element content of the document. Message being parsed: HEXHEXHEXHEXHEXHEXHEXHEXHEXHEXHEXHEXHEXHEXHEXHEXHEXHEXHEXHEXHEXHEXHEXHEXHEXHEXHEXHEXHEXHEXHEXHEXHEXHEXHEXHEXHEXHEXHEXHEXHEXHEXHEXH</ns4:image></ns4:arrayOfImage><ns4:otherField></ns4:otherField></ns4:enclosingType></ns5:enclosingTypes></ns5:outerEnclosingType></S:Body></S:Envelope>
I suppose it is entirely possible for a TIFF to include Unicode NULL
byte, which I assume is what is being sent based upon this answer.
As I understand it, I am using the generated API correctly as hexBinary doesn't expect Base64 encoded data. Is there something else that needs to be done to make the images send correctly?
This was a fine case of the error message throwing the developer off the scent.
There was never a problem with null bytes in the binary file causing this exception - the null bytes were in normal String
-typed fields, but the Exception didn't show this for some reason.
We were able to test this by generating byte[]
s in test cases, and serialising the SOAP objects to XML. No error was thrown. However, placing the null byte into Strings in 'normal' fields did cause the error.
The Strings come from a database over which I have no control - I have therefore added some String-cleaning code which removes the null byte from all Strings before they are 'set' in the SOAP object.