如何在不编组的情况下针对 JAXB 2.0 中的模式进行验证?

2022-08-31 20:31:10

在编组到 XML 文件之前,我需要验证我的 JAXB 对象。在 JAXB 2.0 之前,可以使用 javax.xml.bind.Validator。但这已被弃用,所以我正试图找出正确的方法来做到这一点。我熟悉在马歇尔时间验证,但在我的情况下,我只想知道它是否有效。我想我可以编组到一个临时文件或内存并将其丢弃,但想知道是否有更优雅的解决方案。


答案 1

首先,已被弃用,转而支持(javadoc)。这个想法是你通过(javadoc)解析你的模式,并将其注入到marshaller/unmarshaller中。javax.xml.bind.Validatorjavax.xml.validation.Schemajavax.xml.validation.SchemaFactory

至于您关于在没有编组的情况下进行验证的问题,这里的问题是JAXB实际上将验证委托给Xerces(或您正在使用的任何SAX处理器),而Xerces将您的文档作为SAX事件流进行验证。因此,为了进行验证,您需要执行某种封送处理。

对此影响最小的实现是使用 SAX 处理器的“/dev/null”实现。封送到空的 OutputStream 仍将涉及 XML 生成,这是浪费。所以我建议:

SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema schema = schemaFactory.newSchema(locationOfMySchema); 

Marshaller marshaller = jaxbContext.createMarshaller();
marshaller.setSchema(schema);
marshaller.marshal(objectToMarshal, new DefaultHandler());

DefaultHandler将丢弃所有事件,如果针对模式的验证失败,该操作将引发 JAXBException。marshal()


答案 2

您可以使用 (javadoc) 和 (javadoc),放入 (javadoc) 的实现并执行以下操作:javax.xml.bind.util.JAXBSourcejavax.xml.validation.Validatororg.xml.sax.ErrorHandler

import java.io.File;

import javax.xml.XMLConstants;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.util.JAXBSource;
import javax.xml.validation.*;

public class Demo {

    public static void main(String[] args) throws Exception {
        Customer customer = new Customer();
        customer.setName("Jane Doe");
        customer.getPhoneNumbers().add(new PhoneNumber());
        customer.getPhoneNumbers().add(new PhoneNumber());
        customer.getPhoneNumbers().add(new PhoneNumber());

        JAXBContext jc = JAXBContext.newInstance(Customer.class);
        JAXBSource source = new JAXBSource(jc, customer);

        SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); 
        Schema schema = sf.newSchema(new File("customer.xsd")); 

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

}

有关详细信息,请参阅我的博客


推荐