Почему JAXB не хочет проверить - PullRequest
5 голосов
/ 25 июля 2010
  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);

Запускается написанный XMLвот так:

 <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
 <ns2:customer xmlns:ns2="http://bla.com/">

Даже подключенный ValidationEventCollector не дал никакой информации:

 unmarshaller.setEventHandler(new JAXBEventCollector());

JAXBEventCollector:

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

1 Ответ

2 голосов
/ 26 июля 2010

Ваш код должен работать. Пара вещей, на которые стоит обратить внимание:

  • Является ли 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);
}

В метро ошибка выглядит так:

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)

С 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)
...