【问题标题】:JAXB-ElipseLink: Marshaller not validatingJAXB-ElipseLink:编组器未验证
【发布时间】:2012-02-14 00:11:42
【问题描述】:

我希望我的 Eclipselink 2.3 Marshaller 在编组时执行验证。 我确保Schema 是由SchemaFactory 正确创建的,我将它传递给Marshaller.setSchema,并且我已经通过Marshaller.setEventHandler() 注册了一个处理程序。

marshal 结果显然是无效的 acc。到它的 Schema(在 Eclipse 中验证),但我可以看到我在 handleEvent(ValidationEvent event) 中的断点从未被命中。

我正在使用 marshal(Object, XMLStreamWriter) 编组 XML 片段,并希望编组器根据我传递的 Schema 对这些片段执行验证。

有人知道为什么这没有发生吗?

编辑

应该发生的验证错误:元素上缺少 2 个属性。

该元素对应于 List 中包含的 Java-Object。我正在编组列表使用:

<xml-element java-attribute="listInstance" xml-path="ListWrapperElement/ListElement" type="foo.ElementType" container-type="java.util.ArrayList"/>

元素本身的映射:

<java-type name="foo.ElementType" xml-accessor-type="PROPERTY">
    <java-attributes>
        // just <xml-attribute> elements here
    </java-attributes>
</java-type>

因此,所有属性都编组到 ListWrapperElement/ListElement/@attribute。 其中 2 个缺失且未被验证检测到。

【问题讨论】:

    标签: validation jaxb schema eclipselink moxy


    【解决方案1】:

    我无法重现您看到的问题。以下是我尝试过的(改编自以下博客文章):

    MarshalDemo(改编自博文)

    import java.io.File;
    import javax.xml.XMLConstants;
    import javax.xml.bind.JAXBContext;
    import javax.xml.bind.Marshaller;
    import javax.xml.stream.XMLOutputFactory;
    import javax.xml.stream.XMLStreamWriter;
    import javax.xml.validation.Schema;
    import javax.xml.validation.SchemaFactory;
    
    import org.eclipse.persistence.Version;
    
    public class MarshalDemo {
    
        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());
    
            SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); 
            Schema schema = sf.newSchema(new File("src/blog/jaxb/validation/customer.xsd"));
    
            JAXBContext jc = JAXBContext.newInstance(Customer.class);
            System.out.println(jc.getClass());
            System.out.println(Version.getVersion());
    
            Marshaller marshaller = jc.createMarshaller();
            marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
            marshaller.setSchema(schema);
            marshaller.setEventHandler(new MyValidationEventHandler());
            XMLStreamWriter xsw = XMLOutputFactory.newFactory().createXMLStreamWriter(System.out);
            marshaller.marshal(customer, xsw);
        }
    
    }
    

    输出

    class org.eclipse.persistence.jaxb.JAXBContext
    2.3.0
    
    EVENT
    SEVERITY:  1
    MESSAGE:  cvc-maxLength-valid: Value 'Jane Doe' with length = '8' is not facet-valid with respect to maxLength '5' for type 'stringWithMaxSize5'.
    LINKED EXCEPTION:  org.eclipse.persistence.oxm.record.ValidatingMarshalRecord$MarshalSAXParseException: cvc-maxLength-valid: Value 'Jane Doe' with length = '8' is not facet-valid with respect to maxLength '5' for type 'stringWithMaxSize5'.
    LOCATOR
        LINE NUMBER:  -1
        COLUMN NUMBER:  -1
        OFFSET:  -1
        OBJECT:  forum8924293.Customer@ef2c60
        NODE:  null
        URL:  null
    
    EVENT
    SEVERITY:  1
    MESSAGE:  cvc-type.3.1.3: The value 'Jane Doe' of element 'name' is not valid.
    LINKED EXCEPTION:  org.eclipse.persistence.oxm.record.ValidatingMarshalRecord$MarshalSAXParseException: cvc-type.3.1.3: The value 'Jane Doe' of element 'name' is not valid.
    LOCATOR
        LINE NUMBER:  -1
        COLUMN NUMBER:  -1
        OFFSET:  -1
        OBJECT:  forum8924293.Customer@ef2c60
        NODE:  null
        URL:  null
    
    EVENT
    SEVERITY:  1
    MESSAGE:  cvc-complex-type.2.4.d: Invalid content was found starting with element 'customer'. No child element '{phone-number}' is expected at this point.
    LINKED EXCEPTION:  org.eclipse.persistence.oxm.record.ValidatingMarshalRecord$MarshalSAXParseException: cvc-complex-type.2.4.d: Invalid content was found starting with element 'customer'. No child element '{phone-number}' is expected at this point.
    LOCATOR
        LINE NUMBER:  -1
        COLUMN NUMBER:  -1
        OFFSET:  -1
        OBJECT:  forum8924293.Customer@ef2c60
        NODE:  null
        URL:  null
    <?xml version="1.0"?><customer><name>Jane Doe</name><phone-number></phone-number><phone-number></phone-number><phone-number></phone-number></customer>
    

    【讨论】:

    • 感谢 Blaise,我查看了您的博客文章,但找不到与我正在做的事情不同的地方。 Marshaller 是否在调用 marshal() 完成后执行验证?在我的具体用例中,元素中缺少 2 个必需属性,并且 Marshaller 没有检测到这一点。验证是否有任何限制?
    • @quaylar - 您的对象对应于 XML 模式的哪一部分:全局/匿名,元素/类型?它是用 XmlRootElememt 注释还是包装在 JAXBElement 中?
    • 更新了我的帖子以提供更多详细信息!
    • @quaylar - 您的更新不包括我之前问题的答案。您能否发布一个简单的示例来演示您所看到的问题?
    • 对不起,它是一个全局命名的类型定义,我使用元素的类型属性来引用它。没有为它定义 XmlRootElement!
    猜你喜欢
    • 1970-01-01
    • 2021-11-05
    • 1970-01-01
    • 2014-01-02
    • 1970-01-01
    • 2011-01-29
    • 1970-01-01
    • 2014-02-27
    • 1970-01-01
    相关资源
    最近更新 更多