为什么JAXB不想验证

Mic*_*ert 5 java xml schema xsd jaxb

  1. 我编写了一些Java类,并使用JAXB注释对它们进行了注释.
  2. 之后我使用schemagen生成xsd.
  3. 然后我构建一个对象图并将其编组到一个xml文件中.
  4. 我修改了xml文件,使其无效.

我希望使用xsd,希望JAXB解组失败.但事实并非如此.为什么?

JAXB正在读取一个模式(如果模式XML是错误的,JAXB给出了一个异常),但它接触到JAXB在读取时忽略了模式.

 SchemaFactory sf = SchemaFactory.newInstance(javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI);
 Schema schema = sf.newSchema(getClass().getResource( "/schema1.xsd"));
 JAXBContext context = JAXBContext.newInstance(Customer.class);
 Unmarshaller unmarshaller = context.createUnmarshaller();
 unmarshaller.setSchema( schema );

 Customer c = JAXB.unmarshal(file, Customer.class);
Run Code Online (Sandbox Code Playgroud)

编写的XML就是这样开始的:

 <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
 <ns2:customer xmlns:ns2="http://bla.com/">
Run Code Online (Sandbox Code Playgroud)

即使附加的ValidationEventCollector也没有提供任何信息:

 unmarshaller.setEventHandler(new JAXBEventCollector());
Run Code Online (Sandbox Code Playgroud)

JAXBEventCollector是:

 class JAXBEventCollector extends ValidationEventCollector
 {
   @Override
   public boolean handleEvent(ValidationEvent event)
   {
       System.out.println(event.getLocator());
       return true;
   }
 }
Run Code Online (Sandbox Code Playgroud)

bdo*_*han 2

你的代码应该可以工作。有几点需要注意:

  • 您的架构的 URL 是否返回为空?
  • 您的最后一行是拼写错误“JAXB.unmarshal(file, Customer.class)”,还是 JAXB 是另一个没有设置模式的解组器。

下面是一段代码,当取消无效的 XML 时,该代码肯定会引发错误。此代码可与MOXy和 Metro (RI) JAXB 实现一起正常工作。

public static void main(String[] args) throws Exception  {
    SchemaFactory sf = SchemaFactory.newInstance(javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI);
    File xsd = new File("customer.xsd");
    Schema schema = sf.newSchema(xsd); 
    JAXBContext context = JAXBContext.newInstance(Customer.class);
    Unmarshaller unmarshaller = context.createUnmarshaller(); 
    unmarshaller.setSchema( schema ); 

    FileInputStream xml = new FileInputStream("invalid.xml");
    unmarshaller.unmarshal(xml);
}
Run Code Online (Sandbox Code Playgroud)

对于 Metro,错误如下所示:

Exception in thread "main" javax.xml.bind.UnmarshalException
 - with linked exception:
[org.xml.sax.SAXParseException: cvc-complex-type.2.4.a: Invalid content was found starting with element 'phone-numbers'. One of '{phoneNumbers}' is expected.]
    at javax.xml.bind.helpers.AbstractUnmarshallerImpl.createUnmarshalException(AbstractUnmarshallerImpl.java:315)
    at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.createUnmarshalException(UnmarshallerImpl.java:514)
    at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:215)
    at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal(UnmarshallerImpl.java:184)
    at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:137)
    at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:184)
    at example.gettingstarted.Demo2.main(Demo2.java:23)
Run Code Online (Sandbox Code Playgroud)

使用 MOXy 时,错误如下所示:

Exception in thread "main" javax.xml.bind.UnmarshalException
 - with linked exception:
[Exception [EclipseLink-25004] (Eclipse Persistence Services - 2.0.3.qualifier): org.eclipse.persistence.exceptions.XMLMarshalException
Exception Description: An error occurred unmarshalling the document
Internal Exception: org.xml.sax.SAXParseException: cvc-complex-type.2.4.a: Invalid content was found starting with element 'phone-numbers'. One of '{phoneNumbers}' is expected.]
    at org.eclipse.persistence.jaxb.JAXBUnmarshaller.unmarshal(JAXBUnmarshaller.java:114)
    at example.gettingstarted.Demo2.main(Demo2.java:23)
Run Code Online (Sandbox Code Playgroud)