Schema Validation of XML/JAXB Annotated Object Containing MTOM Attachment [Code Snippet]
In this article, we will explain how can we validate an XML/JAXB annotated object containing an MTOM attachment against an XSD without losing the MTOM attachment.
Join the DZone community and get the full member experience.
Join For FreeIssue: JIRA reference https://java.net/jira/browse/JAXB-588
Resolution: Won't Fix
Description: If an XML or its corresponding JAXB annotated object which contains an MTOM attachment is validated using javax.xml.validation.Validator against an XSD, the referenced MTOM attachment is lost.
Workaround: In this article, we will explain how can we validate an XML/JAXB annotated object containing an MTOM attachment against an XSD without losing the MTOM attachment. In case an XML is used, it is advised to convert the same into a JAXB annotated object as it makes it easier to manipulate with the element which contains the MTOM attachment. Below Code shows a sample XSD snippet and it's corresponding JAVA code for schema validation.
SampleSchema.xsd snippet :
<xs:element name="request">
<xs:complexType>
<xs:sequence>
<xs:element name="requestDetails" type="ns:requestDetails" minOccurs="0" maxOccurs="1" nillable="true"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:complexType name="requestDetails">
<xs:sequence>
<xs:element name="fileName" type="xs:string" minOccurs="0"/>
<xs:element xmlns:xmime="http://www.w3.org/2005/05/xmlmime" name="fileMtomAttachment" type="xs:base64Binary" xmime:expectedContentTypes="application/octet-stream"/>
</xs:sequence>
</xs:complexType>
Code snippet :
import java.io.IOException;
import javax.xml.XMLConstants;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.util.JAXBSource;
import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import javax.xml.validation.Validator;
...
try {
//creating Schema Source
Source schemaFile = new StreamSource(new File("xsd/SampleSchema.xsd"));
SchemaFactory schemaFactory = SchemaFactory .newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema schema = schemaFactory.newSchema(schemaFile);
Validator validator = schema.newValidator();
// refPayload is the reference to the JAXB annotated object representing the XML.
Request request = (Request)refPayload;
//create a temporary handler to handle the original MTOM attachment
javax.activation.DataHandler tempHandler = null;
// check for availability of MTOM attachment
if (null != request.requestDetails() && null != request.requestDetails().getValue().getFileMtomAttachment()) {
// setting the original MTOM attachment in the temporary handler
tempHandler = request.requestDetails().getValue().getFileMtomAttachment();
// setting an empty object in the original JAXB annotated object which is to be validated
request.requestDetails().getValue().setFileMtomAttachment(new javax.activation.DataHandler(new Object() , ""));
} else {
request.requestDetails().getValue().setFileMtomAttachment(null);
}
// Validate as JAXB source
JAXBContext jaxbContext = JAXBContext.newInstance(Request.class);
JAXBSource jaxbSource = new JAXBSource(jaxbContext, request);
validator.validate(jaxbSource);
System.out.println("Jaxb Object is valid");
//Set original MTOM attachment in case Schema validation is successful
request.requestDetails().getValue().setFileMtomAttachment(tempHandler);
} catch (SAXException se) {
System.out.println("Jaxb Object is NOT valid");
System.out.println("Reason: " + se.getLocalizedMessage());
} catch (IOException e) {
e.printStackTrace();
}
This is a simple way to preserve the MTOM attachment while schema validating the rest of the elements and attributes inside an XML.
Opinions expressed by DZone contributors are their own.
Comments