Java 如何在没有编组的情况下根据JAXB2.0中的模式进行验证?

Java 如何在没有编组的情况下根据JAXB2.0中的模式进行验证?,java,jaxb,Java,Jaxb,在编组到XML文件之前,我需要验证JAXB对象。在JAXB2.0之前,可以使用javax.xml.bind.Validator。但这已经被弃用了,所以我正试图找出正确的方法来做到这一点。我熟悉marshall时间的验证,但就我而言,我只想知道它是否有效。我想我可以把它放到一个临时文件或内存中扔掉,但不知道是否有更优雅的解决方案。首先,javax.xml.bind.Validator已经被弃用,取而代之的是javax.xml.validation.Schema()。其思想是通过javax.xml.

在编组到XML文件之前,我需要验证JAXB对象。在JAXB2.0之前,可以使用javax.xml.bind.Validator。但这已经被弃用了,所以我正试图找出正确的方法来做到这一点。我熟悉marshall时间的验证,但就我而言,我只想知道它是否有效。我想我可以把它放到一个临时文件或内存中扔掉,但不知道是否有更优雅的解决方案。

首先,
javax.xml.bind.Validator
已经被弃用,取而代之的是
javax.xml.validation.Schema
()。其思想是通过
javax.xml.validation.SchemaFactory
()解析模式,并将其注入封送器/解封器

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

这种实现的最低影响是使用SAX处理器的“/dev/null”实现。编组到空输出流仍然需要生成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
将丢弃所有事件,如果对架构的验证失败,
marshal()
操作将抛出一个JAXBEException。

我们就是这样做的。我必须找到一种方法来验证xml文件,而不是对应于xml版本的xsd,因为我们有许多应用程序使用不同版本的xml内容

我在网上没有找到任何好的例子,最后我完成了这个。希望这会有所帮助

ValidationEventCollector vec = new ValidationEventCollector();

SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);

URL xsdURL = getClass().getResource("/xsd/" + xsd);
Schema schema = sf.newSchema(xsdURL);

//You should change your jaxbContext here for your stuff....
Unmarshaller um = (getJAXBContext(NotificationReponseEnum.NOTIFICATION, notificationWrapper.getEnteteNotification().getTypeNotification()))
    .createUnmarshaller();
um.setSchema(schema);

try {
    StringReader reader = new StringReader(xml);
    um.setEventHandler(vec);
    um.unmarshal(reader);
} catch (javax.xml.bind.UnmarshalException ex) {
    if (vec != null && vec.hasEvents()) {
        erreurs = new ArrayList < MessageErreur > ();
        for (ValidationEvent ve: vec.getEvents()) {
            MessageErreur erreur = new MessageErreur();
            String msg = ve.getMessage();
            ValidationEventLocator vel = ve.getLocator();
            int numLigne = vel.getLineNumber();
            int numColonne = vel.getColumnNumber();
            erreur.setMessage(msg);
            msgErreur.setCode(ve.getSeverity())
            erreur.setException(ve.getLinkedException());
            erreur.setPosition(numLigne, numColonne);
            erreurs.add(erreur);

            logger.debug("Erreur de validation xml" + "erreur : " + numLigne + "." + numColonne + ": " + msg);
        }
    }
}
ValidationEventCollector vec=new ValidationEventCollector();
SchemaFactory sf=SchemaFactory.newInstance(xmlstants.W3C\u XML\u SCHEMA\u NS\u URI);
URL xsdURL=getClass().getResource(“/xsd/”+xsd);
Schema=sf.newSchema(xsdURL);
//您应该在此处更改您的jaxbContext以获取您的资料。。。。
解组器um=(getJAXBContext(notificationreponseum.NOTIFICATION,notificationWrapper.getEnteteNotification().getTypeNotification())
.createUnmarshaller();
um.setSchema(schema);
试一试{
StringReader=新的StringReader(xml);
setEventHandler(vec);
嗯,unmarshal(读者),;
}catch(javax.xml.bind.UnmarshalException ex){
if(vec!=null&&vec.hasEvents()){
erreurs=newarraylist();
for(ValidationEvent ve:vec.getEvents()){
MessageErreur=newmessageerreur();
字符串msg=ve.getMessage();
ValidationEventLocator vel=ve.getLocator();
int numlinge=vel.getLineNumber();
int numcollone=vel.getColumnNumber();
erreur.setMessage(msg);
msgErreur.setCode(ve.getSeverity())
erreur.setException(ve.getLinkedException());
错误设置位置(numLigne、Numcolone);
添加(erreur);
debug(“Erreur de validation xml”+“Erreur:”+numlinge+“+numColonne+”:“+msg);
}
}
}

您可以使用
javax.xml.bind.util.JAXBSource
()和
javax.xml.validation.Validator
(),插入
org.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);
    }

}
有关更多信息,请参阅我的博客


这种方法的一个问题是:使用这种方法无法获得有关验证错误的行号/列号信息,因此很难跟踪问题。这种方法适用于取消归档吗。我无法创建JAXBSource对象。您从哪个包获取
DefaultHandler
?它是来自
org.xml.sax.helpers
?@StefanHöltker
DefaultHandler
还是
DefaultHandler2