Java servlets: xml vs xsd validation

I have a servlet that uses a utility packaged in a .jar archive:

@Override public void init() throws ServletException { ... try (InputStream stream = getClass().getResourceAsStream("/fileToParse.xml")) { App.check(stream); } catch (Exception e) { throw new ServletException(e); } ... } 

This utility accepts a stream of XML files, checks using the xsd schema, and parses it:

 public class App { private static final String JAXP_SCHEMA_LANGUAGE = "http://java.sun.com/xml/jaxp/properties/schemaLanguage"; private static final String W3C_XML_SCHEMA = "http://www.w3.org/2001/XMLSchema"; ... public static void check(InputStream stream) { SAXParserFactory spf = SAXParserFactory.newInstance(); spf.setNamespaceAware(true); spf.setValidating(true); MyHandler handler = new MyHandler(); try { SAXParser sp = spf.newSAXParser(); sp.setProperty(JAXP_SCHEMA_LANGUAGE, W3C_XML_SCHEMA); XMLReader rdr = sp.getXMLReader(); rdr.setContentHandler(handler); rdr.setErrorHandler(new MyErrorHandler()); rdr.parse(new InputSource(stream)); } ... } ... } 

The xsd file starts with:

 <?xml version="1.0" encoding="UTF-8"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.mydomain.org" elementFormDefault="qualified" xmlns:t="http://www.mydomain.org"> <xs:element name="appContext"> ... 

xml file:

 <?xml version="1.0" encoding="UTF-8"?> <appContext xmlns="http://www.mydomain.org" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.mydomain.org appContext.xsd"> ... 

.war structure:

 css/ js/ WEB-INF/ classes/ mypackage/ MyServlet.class fileToParse.xml lib/ App.jar web.xml 

App.jar structure:

 mypackage2/ App.class appContext.xsd 

The Servlet Init method throws an exception:

 ... at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) [na:1.7.0_21] at java.lang.Thread.run(Thread.java:722) [na:1.7.0_21] Caused by: java.io.FileNotFoundException: /PATH_TO_TOMCAT/bin/appContext.xsd (No such file or directory) at java.io.FileInputStream.open(Native Method) ~[na:1.7.0_21] at java.io.FileInputStream.<init>(FileInputStream.java:138) ~[na:1.7.0_21] 

How can I tell SAXParser where the xsd schema is needed to validate the XML file?

PS sorry for my bad english

UPD:

I am trying to add this property:

  private static final String JAXP_SCHEMA_SOURCE = "http://java.sun.com/xml/jaxp/properties/schemaSource"; .... public static void check(InputStream stream) { ... try { ... sp.setProperty(JAXP_SCHEMA_SOURCE, new File(getPath("/appContext.xsd"))); ... } } public static String getPath(String path) { return App.class.getResource(path).toString(); } 

Now I have this exception:

 ERROR mypackage2.App - Error: URI=null Line=5: schema_reference.4: Failed to read schema document 'jar:file:/PATH_TO_TOMCAT/webapps/myapp/WEB-INF/lib/App.jar!/appContext.xsd', because 1) could not find the document; 2) the document could not be read; 3) the root element of the document is not <xsd:schema>. org.xml.sax.SAXParseException: schema_reference.4: Failed to read schema document 'jar:file:/PATH_TO_TOMCAT/webapps/myapp/WEB-INF/lib/App.jar!/appContext.xsd', because 1) could not find the document; 2) the document could not be read; 3) the root element of the document is not <xsd:schema>. at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(ErrorHandlerWrapper.java:198) ~[na:1.7.0_21] 

UPD2: From "classpath: appContext.xsd" in the xml file:

 WARN mypackage.App - Warning: URI=null Line=5: schema_reference.4: Failed to read schema document 'classpath:appContext.xsd', because 1) could not find the document; 2) the document could not be read; 3) the root element of the document is not <xsd:schema>. org.xml.sax.SAXParseException: schema_reference.4: Failed to read schema document 'classpath:appContext.xsd', because 1) could not find the document; 2) the document could not be read; 3) the root element of the document is not <xsd:schema>. at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(ErrorHandlerWrapper.java:198) ~[na:1.7.0_21] ... at java.lang.Thread.run(Thread.java:722) [na:1.7.0_21] Caused by: java.net.MalformedURLException: unknown protocol: classpath at java.net.URL.<init>(URL.java:592) ~[na:1.7.0_21 ;;; 
+1
java xml servlets xsd jaxp
source share
2 answers

Problem resolved:

 public class App { ... public static void check(InputStream stream) { SAXParserFactory spf = SAXParserFactory.newInstance(); spf.setNamespaceAware(true); spf.setValidating(true); MyHandler handler = new MyHandler(); try (InputStream schemaStream = App.class.getResourceAsStream("/appContext.xsd")) { SAXParser sp = spf.newSAXParser(); sp.setProperty(JAXPConstants.JAXP_SCHEMA_LANGUAGE, JAXPConstants.W3C_XML_SCHEMA); sp.setProperty(JAXPConstants.JAXP_SCHEMA_SOURCE, new InputSource(schemaStream)); XMLReader rdr = sp.getXMLReader(); rdr.setContentHandler(handler); rdr.setErrorHandler(new MyErrorHandler()); rdr.parse(new InputSource(stream)); } ... } ... } 
0
source share

Try setting the circuit source directly as InputStream

 public static void check(InputStream stream) { ... try { ... sp.setProperty(JAXP_SCHEMA_SOURCE, getInputStream("/appContext.xsd"))); ... } } public static InputStream getInputStream(String path) { return SAXLoader.class.getResourceAsStream(path); } 

Check if this property works after removing the XSD link from the XML file. If not, check if the property works or not by simply checking it with the XSD located outside the jar and its absolute path passed as the File link, as you are doing right now.

+2
source share

All Articles