【问题标题】:How to get validation events with JaXB?如何使用 JaXB 获取验证事件?
【发布时间】:2012-08-30 23:24:11
【问题描述】:

我尝试使用 Jaxb 在变量中获取验证消息。 从这里尝试示例http://docs.oracle.com/cd/E17802_01/webservices/webservices/docs/1.6/api/javax/xml/bind/Unmarshaller.html

我的代码:

JAXBContext jaxbContext = JAXBContext.newInstance("com.piyush");
SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema schema = factory.newSchema(new StreamSource(new File("D:/liferay-develop/workspace/cat_test/v1/STD_MP.xsd")));
Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
jaxbUnmarshaller.setSchema(schema);
ValidationEventCollector validationCollector= new ValidationEventCollector();
jaxbUnmarshaller.setEventHandler( validationCollector );
STDMP ts = (STDMP)jaxbUnmarshaller.unmarshal(xml_gkuzu);
if(validationCollector.hasEvents())
{
    for(ValidationEvent event:validationCollector.getEvents())
    {
        String msg = event.getMessage();
        System.out.println(msg);
    }
}

但是什么也没发生。我做错了什么?

【问题讨论】:

标签: java xml validation jaxb


【解决方案1】:

以下内容应该会有所帮助:

JAXB2ValidationEventCollector

ValidationEventCollector 来自JAXB 1 (JSR-31),似乎不太支持我们在JAXB 2 (JSR-222) 中对验证所做的更改。您可以通过创建ValidationEventHandler 的子类来解决此问题,如下所示。

package forum12295028;

import javax.xml.bind.ValidationEvent;
import javax.xml.bind.util.ValidationEventCollector;

class JAXB2ValidationEventCollector extends ValidationEventCollector {

    @Override
    public boolean handleEvent(ValidationEvent event) {
        super.handleEvent(event);
        return true;
    }

}

示例

下面的例子可以用来证明一切正常

客户

package forum12295028;

import java.util.*;
import javax.xml.bind.annotation.*;

@XmlRootElement
public class Customer {

    private String name;

    private List<PhoneNumber> phoneNumbers = 
        new ArrayList<PhoneNumber>();

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @XmlElement(name="phone-number")
    public List<PhoneNumber> getPhoneNumbers() {
        return phoneNumbers;
    }

    public void setPhoneNumbers(List<PhoneNumber> phoneNumbers) {
        this.phoneNumbers = phoneNumbers;
    }

}

电话号码

package forum12295028;

public class PhoneNumber {

}

customer.xsd

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">

    <xs:element name="customer">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="name" type="stringMaxSize5"/>
                <xs:element ref="phone-number" maxOccurs="2"/>
             </xs:sequence>
        </xs:complexType>
    </xs:element>

    <xs:element name="phone-number">
        <xs:complexType>
            <xs:sequence/>
        </xs:complexType>
    </xs:element>

    <xs:simpleType name="stringMaxSize5">
        <xs:restriction base="xs:string">
            <xs:maxLength value="5"/>
        </xs:restriction>
    </xs:simpleType>

</xs:schema> 

input.xml

<?xml version="1.0" encoding="UTF-8"?>
<customer>
   <name>Jane Doe</name>
   <phone-number/>
   <phone-number/>
   <phone-number/>
</customer>

演示

package forum12295028;

import java.io.File;

import javax.xml.XMLConstants;
import javax.xml.bind.*;
import javax.xml.bind.util.ValidationEventCollector;
import javax.xml.validation.*;

public class Demo {

    public static void main(String[] args) throws Exception {
        SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); 
        Schema schema = sf.newSchema(new File("src/forum12295028/customer.xsd")); 

        JAXBContext jc = JAXBContext.newInstance(Customer.class);

        Unmarshaller unmarshaller = jc.createUnmarshaller();
        unmarshaller.setSchema(schema);
        ValidationEventCollector validationCollector = new JAXB2ValidationEventCollector();
        unmarshaller.setEventHandler(validationCollector);

        Customer customer = (Customer) unmarshaller.unmarshal(new File("src/forum12295028/input.xml"));

        if(validationCollector.hasEvents())
        {
            for(ValidationEvent event:validationCollector.getEvents())
            {
                String msg = event.getMessage();
                System.out.println(msg);
            }
        }
    }

}

输出

cvc-maxLength-valid: Value 'Jane Doe' with length = '8' is not facet-valid with respect to maxLength '5' for type 'stringMaxSize5'.
cvc-type.3.1.3: The value 'Jane Doe' of element 'name' is not valid.
cvc-complex-type.2.4.d: Invalid content was found starting with element 'phone-number'. No child element is expected at this point.

【讨论】:

  • 此解决方案有效。但它看起来确实像 ValidationEventCollector 中的一个错误。
  • @JérômeRadix - 同意,这是一个没有很好地从 JAXB 1 过渡到 JAXB 2 的类。它也是一个不经常使用的类。
  • 这不适用于 rt.jar 中的 JaxBeanInfo.invokeUnmarshallCallback。我必须将 jaxb-impl 添加到类路径
  • (我的 bean 有 afterUnmarshal() 回调用于额外的验证)。
猜你喜欢
  • 2012-10-10
  • 2014-03-18
  • 1970-01-01
  • 1970-01-01
  • 2014-09-05
  • 2014-12-17
  • 2011-01-22
  • 1970-01-01
  • 2011-06-07
相关资源
最近更新 更多