Our Wiki:
http://wiki.apache.org/ws/FrontPage/Axis
-- dims
On 11/10/06, John Pfeifer <[EMAIL PROTECTED]> wrote:
Here is the filter... The trick with this is that you have to wrap the
HttpServletRequest so that you can send the request on to filters down
stream once you have read the input stream. You can do this using
HttpServletRequestWrapper. I will be happy to post this somewhere, but I am
not sure where to post it.
public class XMLValidationFilter extends GenericFilterBean {
/**
* The object that is used for logging.
*/
private static Log log = LogFactory.getLog(XMLValidationFilter.class);
/**
* schemaMap
*/
private Map schemaMap = null;
/** (non-Javadoc)
* @see javax.servlet.Filter#destroy()
*/
public void destroy() {
super.destroy();
}
/**
* Initialize schemaMap from Spring Context
*/
private void initSchemaMap() {
if (schemaMap == null) {
schemaMap = (Map)
WebApplicationContextUtils.getWebApplicationContext(getServletContext()).getBean("schemaToURIMap");
}
}
/** (non-Javadoc)
* @see javax.servlet.Filter#doFilter(javax.servlet.ServletRequest,
* javax.servlet.ServletResponse, javax.servlet.FilterChain)
*/
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain)
throws IOException, ServletException {
final String methodName = "doFilter()";
if (log.isTraceEnabled()) {
log.trace(methodName + ": Entry");
}
HttpServletRequest httpRequest = ((HttpServletRequest) request);
if (log.isDebugEnabled()) {
log.debug("XMLValidationFilter: doFilter");
log.debug("Schema Map Entries "+ schemaMap);
}
// set the schemaMap from the spring context, the
// context is loaded after the filter is initialized but
// before the first request can be handled
initSchemaMap();
if (schemaMap.get(httpRequest.getRequestURI()) == null) {
if (log.isDebugEnabled()) {
log.debug("No schema found for RequestURI " +
httpRequest.getRequestURI());
}
// continue with rest of the filter chain as no further
processing is required
chain.doFilter(request, response);
return;
} else {
if (log.isDebugEnabled()) {
log.debug("Schema found for RequestURI " +
httpRequest.getRequestURI());
}
}
XMLValidationRequestWrapper requestWrapper =
new
XMLValidationRequestWrapper((HttpServletRequest) request);
String queryString = httpRequest.getQueryString();
if (log.isDebugEnabled()) {
log.debug("queryString = " + queryString);
}
boolean isValid = true;
if (!StringUtils.equalsIgnoreCase(queryString,
"wsdl"))
{
isValid = validateIncomingXML(httpRequest,
requestWrapper);
}
else
{
if (log.isInfoEnabled()) {
log.info("Skipping XML Schema validation.");
}
}
if (isValid) {
if (log.isDebugEnabled()) {
log.debug("Continue processing filter chain");
}
chain.doFilter(requestWrapper, response);
} else {
log.error("Schema validation failed");
generateSOAPFault(response.getOutputStream());
}
if (log.isTraceEnabled()) {
log.trace(methodName + ": Exit");
}
}
/**
* validateIncomingXML
* @param request
* @param httpRequest
* @param buffer
* @param requestWrapper
* @return
*/
private boolean validateIncomingXML(HttpServletRequest
httpRequest,
XMLValidationRequestWrapper requestWrapper) {
boolean isValid = false;
StringBuffer buffer = new StringBuffer();
InputStream xmlIn;
String soapRequest;
String xmlBody;
try {
xmlIn = httpRequest.getInputStream();
int x = 0;
while ((xmlIn != null) && ((x = xmlIn.read()) >= 0)) {
buffer.append((char) x);
}
soapRequest = buffer.toString();
if (log.isDebugEnabled()) {
log.debug("Original SOAP Request = " + soapRequest);
}
xmlBody = SOAPUtils.getSOAPBody(buffer.toString());
if (log.isDebugEnabled()) {
log.debug("XML to be validated = " + xmlBody);
}
XMLSchemaValidator validator = new XMLSchemaValidator();
URL url = this.getClass().getResource((String)
schemaMap.get(httpRequest.getRequestURI()));
if (log.isDebugEnabled()) {
log.debug("XSD Url = " + url);
}
isValid = validator.validateDocument(xmlBody, url);
if (log.isDebugEnabled()) {
log.debug("Schema validation isValid = " + isValid);
}
requestWrapper.setBodyText(soapRequest);
// Don't parse the request again, set it as a request attribute
to be
// used by ServiceRequestProxyServlet down stream
requestWrapper.setAttribute(ServiceRequestProxyServlet.SOAP_REQUEST_ATTRIBUTE,
soapRequest);
} catch (Throwable t) {
log.error("Error validating xml", t);
}
return isValid;
}
private void generateSOAPFault(OutputStream out) {
String soapFault = SOAPUtils.generateSOAPFault(
"Server", "Invalid XML", "Test Actor", "..... Details ....");
try {
if (log.isDebugEnabled()) {
log.debug("SOAP Fault = " + soapFault);
}
out.write(soapFault.getBytes());
out.flush();
} catch (Throwable t) {
log.error("Error Generating SOAP Fault", t);
}
finally {
try {
out.close();
} catch (Throwable t) {}
}
}
Here is the schema validator class
===========================================
public class XMLSchemaValidator {
/**
* logger
*/
private static Logger logger =
Logger.getLogger(XMLSchemaValidator.class.getName());
/**
* JAXP_SCHEMA_LANGUAGE
*/
public static final String JAXP_SCHEMA_LANGUAGE =
"http://java.sun.com/xml/jaxp/properties/schemaLanguage";
/**
* W3C_SCHEMA_LANGUAGE
*/
public static final String W3C_SCHEMA_LANGUAGE =
"http://www.w3.org/2001/XMLSchema";
/**
* JAXP_SCHEMA_SOURCE
*/
public static final String JAXP_SCHEMA_SOURCE =
"http://java.sun.com/xml/jaxp/properties/schemaSource";
/**
* parser
*/
private ThreadLocal parser = new ThreadLocal() {
protected Object initialValue() {
if (logger.isDebugEnabled()) {
logger.debug("Creating new thread local parser");
}
return createParser();
}
};
/**
* XMLSchemaValidator
*/
public XMLSchemaValidator() {
}
/**
* Returns the JDOM <code>SAXParser</code> associated to the
* current thread.
* <p>
* If no SAXParser is yet associated to the current thread,
* this implementation relies on [EMAIL PROTECTED] #createParser()} to
* allocate and configure a new SAXParser.</p>
*
* @return the <code>DocumentBuilder</code> associated to the
* current thread.
*/
protected final SAXParser getParser() {
return (SAXParser) (this.parser.get());
//return createParser();
}
/**
* Create a SAX Parser settings it's properties
* @return SAXParser
*/
protected SAXParser createParser() {
if (logger.isDebugEnabled()) {
logger.debug("Creating new SAX Parser");
}
SAXParserFactory factory = null;
SAXParser parser = null;
try {
factory = SAXParserFactory.newInstance();
factory.setNamespaceAware(true);
factory.setValidating(true);
parser = factory.newSAXParser();
parser.setProperty(JAXP_SCHEMA_LANGUAGE, W3C_SCHEMA_LANGUAGE);
} catch (SAXException se) {
logger.error("SAXException creating SAXParser", se);
} catch (ParserConfigurationException pe) {
logger.error("ParserConfigurationException creating SAXParser",
pe);
}
catch (Throwable t) {
logger.error("Unknown Exception: ", t);
}
return parser;
}
/**
* Validate an XML string against a specific xsd
* @param xmlInput xmlInput
* @param xsdName xsdName
* @return isValid
* @throws XMLValidationException validationException
*/
public boolean validateDocument(String xmlInput, String xsdName) throws
XMLValidationException {
URL url = null;
try {
url = this.getClass().getResource("/" + xsdName);
} catch (Throwable t) {
logger.error("Error retrieving xsd resource", t);
}
return validateDocument(new
ByteArrayInputStream(xmlInput.getBytes()), url);
}
/**
* Validate an XML string against a specific xsd
* @param xmlInput xml doc
* @param url schemaUrl
* @return isValid
* @throws XMLValidationException validationException
*/
public boolean validateDocument(String xmlInput, URL url) throws
XMLValidationException {
return validateDocument(new
ByteArrayInputStream(xmlInput.getBytes()), url);
}
/**
* Validate an XML InputStream against a list of xsd's.
* @param xmlInput xmlInput
* @param url url
* @return isValid
* @throws XMLValidationException validationException
*/
public boolean validateDocument(InputStream xmlInput, URL url) throws
XMLValidationException {
boolean isValid = false;
try {
if (logger.isDebugEnabled()) {
logger.debug("XSD URL = " + url);
}
if (url != null) {
this.getParser().setProperty(JAXP_SCHEMA_SOURCE,
url.toString());
}
Validator validator = new Validator();
if (logger.isDebugEnabled()) {
logger.debug("Attempting to validate schema");
}
this.getParser().parse(xmlInput, validator);
isValid = !validator.isValidationError();
if (logger.isDebugEnabled()) {
if (isValid) {
logger.debug("Validation passed");
} else {
logger.debug("Validation failed");
}
}
if (!isValid) {
logger.error("Schema validation failed ",
validator.getSaxParseException());
throw new
XMLValidationException(validator.getSaxParseException().getMessage());
}
} catch (XMLValidationException ve) {
throw ve;
} catch (Throwable t) {
logger.error("Error validating schema", t);
throw new XMLValidationException(t.getMessage());
}
return isValid;
}
/**
* Error handler used to log SAX Parser Errors.
* @author I4Commerce
*
*/
private class Validator extends DefaultHandler {
/**
* validationError
*/
private boolean validationError = false;
/**
* saxParseException
*/
private SAXParseException saxParseException = null;
/** (non-Javadoc)
* @see
org.xml.sax.helpers.DefaultHandler#error(org.xml.sax.SAXParseException)
*/
public void error(SAXParseException exception) throws SAXException
{
validationError = true;
saxParseException = exception;
}
/** (non-Javadoc)
* @see
org.xml.sax.helpers.DefaultHandler#fatalError(org.xml.sax.SAXParseException)
*/
public void fatalError(SAXParseException exception) throws
SAXException {
validationError = true;
saxParseException = exception;
}
/** (non-Javadoc)
* @see
org.xml.sax.helpers.DefaultHandler#warning(org.xml.sax.SAXParseException)
*/
public void warning(SAXParseException exception) throws
SAXException {
saxParseException = exception;
}
/**
* Get validationError
* @return the validationError
*/
public boolean isValidationError() {
return validationError;
}
/**
* Get saxParseException
* @return the saxParseException
*/
public SAXParseException getSaxParseException() {
return saxParseException;
}
/**
* Set saxParseException
* @param saxParseException the saxParseException to set
*/
public void setSaxParseException(SAXParseException
saxParseException) {
this.saxParseException = saxParseException;
}
}
}
-----Original Message-----
From: Rodrigo Ruiz [mailto:[EMAIL PROTECTED]
Sent: Fri 11/10/2006 9:06 AM
To: [email protected]
Subject: Re: Schema validation Axis 1.3
Hi John, how complex is your filter code? It would be a great entry in
the Axis wiki ;-)
Regards,
Rodrigo Ruiz
John Pfeifer wrote:
>
> Good luck with this one. I have posted several times about schema
> validation in axis2 and it looks like you have to do it yourself. I
> wrote a servlet filter that sits in front of the axis servlet and
> validates the request against a given xsd.
>
--
-------------------------------------------------------------------
GRIDSYSTEMS S.A. Rodrigo Ruiz
Parc Bit - Son Espanyol R & D
07120 Palma de Mallorca rruiz at gridsystems dot com
Baleares - Espa�a Tel: +34 971 435 085
http://www.gridsystems.com/ Fax: +34 971 435 082
-------------------------------------------------------------------
---------------------------------------------------------------------
To unsubscribe, e-mail:
[EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
--
Davanum Srinivas : http://www.wso2.net (Oxygen for Web Service Developers)