CSci 4608 Principles of Web Programming, UMM: XSD validation in a servlet.

Source files

The path to the xml and xsd files is relative to jakarta-tomcat-5.0.30/bin. At this point the files are right in the directory. In general, this is not a good idea, creating a subfolder would be better.

Compiling and running the servlet

Since schema validation uses Xerces, the path to xercesImpl.jar must be added to the classpath for compilation. Xerces is included as a part of the standard Tomcat distribution, with the path

jakarta-tomcat-5.0.30/common/endorsed/xercesImpl.jar
Therefore the compilation path command for the servlet and the error-handling class is:

javac CheckSchemaServlet.java -classpath .:jakarta-tomcat-5.0.30/common/endorsed/xercesImpl.jar:jakarta-tomcat-5.0.30/common/lib/servlet-api.jar
(assuming that the servlet's .java files are in the directory that contains jakarta-tomcat-5.0.30 directory, otherwise you need to adjust the paths accordingly)

"Running" the servlet just means copying all of its files into the class directory of your application (we are using the servlets-examples as our application). Don't forget to add the servlet (but not the supporting classes!) to the web.xml file. Since Xerces is included as a part of a standard distribution, its .jar file is accessible by Tomcat. Use Tomcat manager to reload the application (see the problem set for instructions).

The code

A few changes had to be made to the validation program to make it into a servlet. The most important change is that all necessary output must be written to the PrintWriter of the HttpRequest. It is up to you to decide which messages should be printed on the page, but all of them should be added to the PrintWriter. Note that the error class ShowValidationErrorsServlets needs to get access to the PrintWriter, so the PrintWriter is passed as a parameter to its constructor. Also note that doGet() cannot throw a SAXException (it overwrites an inherited doGet() method that only throws IOException and ServletException), therefore all SAXExceptions must be caught in the method. Same goes for doPost().

import java.io.*;
import java.text.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
import org.xml.sax.*;
import org.xml.sax.helpers.*;
import javax.xml.parsers.SAXParser;


public class CheckSchemaServlet extends HttpServlet {


    public void doGet(HttpServletRequest request,
                      HttpServletResponse response)
        throws IOException, ServletException
    {

        response.setContentType("text/html");
        PrintWriter out = response.getWriter();

        // Set the filenames here:
        String xmlSource = "shiporder.xml";
        String xsdSchema = "shiporder.xsd";

        out.println("<html>");
        out.println("<body bgcolor=\"white\">");
        out.println("<head>");

        out.println("<title> Schema validation </title>");
        out.println("</head>");
        out.println("<body>");

        // strings to set up properties
        String JAXP_SCHEMA_LANGUAGE =
            "http://java.sun.com/xml/jaxp/properties/schemaLanguage";
        String W3C_XML_SCHEMA =
            "http://www.w3.org/2001/XMLSchema";
        String JAXP_SCHEMA_SOURCE =
            "http://java.sun.com/xml/jaxp/properties/schemaSource";


        // the parser variable
        XMLReader parser = null;

        // create the XML parser
        try {
            // get a new parser from the factory
            parser = XMLReaderFactory.createXMLReader("org.apache.xerces.parsers.SAXParser");

            // XML Schema is used as the schema language
            parser.setProperty(JAXP_SCHEMA_LANGUAGE, W3C_XML_SCHEMA);
            // Set up the schema file
            parser.setProperty(JAXP_SCHEMA_SOURCE,xsdSchema);

            // both lines are needed to make the program
            // validate against the schema.
            // Otherwise it just validates well-formedness
            parser.setFeature("http://xml.org/sax/features/validation", true);
            parser.setFeature("http://apache.org/xml/features/validation/schema",true);

            // default contents handler
            parser.setContentHandler(new DefaultHandler());
            // set customized error handler 
	    // (needed to display validation errors)
            parser.setErrorHandler(new ShowValidationErrorsServlets(out));

        } catch  (SAXException e) {
            // print out the error message
            out.println("Cannot create a parser");
            // rethrow the exception
            //throw e;
        }

        try {
            FileInputStream theStream = new FileInputStream(xmlSource);
            if (parser != null) {
                parser.parse(new InputSource(theStream));
            }
        } catch (IOException e) {
            out.println("Cannot open a file");
            //throw e;
        } catch (SAXException e) {
            out.println("The document is invalid");
            //throw e;
        }


        out.println("<h2>DONE!</h2>");
        out.println("</body>");
        out.println("</html>");

    }
}



import org.xml.sax.*;
import java.io.*;
import java.text.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class ShowValidationErrorsServlets implements ErrorHandler {
    private PrintWriter out;

    public ShowValidationErrorsServlets(PrintWriter out) {
        super();
        this.out = out;
    }


    public void warning(SAXParseException exception) {
        // Ignore warnings
        out.println("WARNING: " + exception.getMessage());
    }

    public void error(SAXParseException exception) {
        out.println("VALIDATION ERROR: " + exception.getMessage());
        // IF YOU WANT TO STOP AT AN ERROR, UNCOMMENT THE LINE BELOW
        // throw exception;

    }

    public void fatalError(SAXParseException exception)
        throws SAXException {
        out.println("WELL-FORMEDNESS ERROR: " + exception.getMessage());
        // A well-formedness error
        throw exception;

    }

}

CSci 2101 home page