7

I have some classes with JAXB annotations, I have created some instances and I need to validate them against my XSD files. I should be able to get the details of what is wrong when the objects are invalid.

So far I haven't had luck, I know about this class ValidationEventHandler but apperantly I can use it with the Unmarshaller class, the problem is that I have to validate the objects not the raw XML.

I have this code:

MyClass myObject = new MyClass();
JAXBContext jaxbContext = JAXBContext.newInstance("x.y.z");
JAXBSource jaxbSource = new JAXBSource(jaxbContext, myObject);
SchemaFactory factory = SchemaFactory
                .newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Source schemaFile = new StreamSource(getClass().getClassLoader()
                .getResourceAsStream("mySchema.xsd"));
Schema schema = factory.newSchema(schemaFile);

Validator validator = schema.newValidator();

validator.validate(jaxbSource);

This code will work, it will validate the object and throw an exception with the message, something like this:

cvc-pattern-valid: Value '12345678901' is not facet-valid with respect to pattern '\d{10}' for type 'id'.]

The problem is that I need specific details, with a string like that I would have to parse all the messages.

4

2 回答 2

1

ErrorHandler您可以设置on 的实例Validator以捕获单个错误:

    Validator validator = schema.newValidator();
    validator.setErrorHandler(new MyErrorHandler());
    validator.validate(source);

我的错误处理程序

下面是该ErrorHandler接口的示例实现。如果您不重新抛出异常,验证将继续。

import org.xml.sax.ErrorHandler;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;

public class MyErrorHandler implements ErrorHandler {

    public void warning(SAXParseException exception) throws SAXException {
        System.out.println("\nWARNING");
        exception.printStackTrace();
    }

    public void error(SAXParseException exception) throws SAXException {
        System.out.println("\nERROR");
        exception.printStackTrace();
    }

    public void fatalError(SAXParseException exception) throws SAXException {
        System.out.println("\nFATAL ERROR");
        exception.printStackTrace();
    }

} 

了解更多信息

于 2012-06-19T19:24:56.333 回答
0

I. If you validate a complex object hierarchy, you can create the Marshaller yourself and set its listener:

Marshaller marshaller = jaxbContext.createMarshaller();
marshaller.setListener(yourListener);
JAXBSource source = new JAXBSource(marshaller, object);

This listener will get notified with instances of your objects as it walks the hierarchy.

II. Add an ErrorHandler from the other answer. At least with Wildfly 15 the messages look like:

cvc-maxInclusive-valid: Value '360.953674' is not facet-valid with respect to maxInclusive '180.0' for type '#AnonType_longitudeGeographicalPosition'.'
cvc-type.3.1.3: The value '360.953674' of element 'longitude' is not valid.'

So you can parse out the element name, which is the guilty terminal field name.

III. Combine I and II with some introspection and you can reconstruct a full Java Beans style path to the erroneous field if necessary.

于 2020-08-31T13:30:38.310 回答