任何人都知道如何使用JaxB 2.x进行自定义验证消息?我需要知道哪个标签或对象属性导致错误。 我已经有一个自定义的ValidationEventHandler,但handleEvent方法的ValidationEvent事件参数不会带来Node信息,只是与XML文档中的错误相关的行和列。 我的目的是使用更友好的用户自定义解组错误消息。有办法做到这一点吗?
谢谢!
答案 0 :(得分:1)
javax.xml.bind.ValidationEventLocator
提供了有关问题原因的一些信息。
元帅行动
在编组操作期间报告ValidationEvent时,应通过以下方式提供与错误相关的对象:
validationEvent.getLocator().getObject();
Unmarshal Operation
在解组操作期间报告ValidationEvent时,如果可用,则可以返回相应的DOM节点(当从DOM节点以外的源解组时,此属性上不会出现任何内容)。
validationEvent.getLocator().getNode();
了解更多信息
<强>更新强>
您可以执行以下操作:
<强>演示强>
import java.io.File;
import java.io.FileReader;
import javax.xml.XMLConstants;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.UnmarshallerHandler;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import org.xml.sax.InputSource;
import org.xml.sax.XMLReader;
public class Demo {
public static void main(String[] args) throws Exception {
SAXParserFactory spf = SAXParserFactory.newInstance();
spf.setNamespaceAware(true);
SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema schema = sf.newSchema(new File("customer.xsd"));
spf.setSchema(schema);
JAXBContext jc = JAXBContext.newInstance(Customer.class);
Unmarshaller unmarshaller = jc.createUnmarshaller();
UnmarshallerHandler unmarshallerHandler = unmarshaller.getUnmarshallerHandler();
SAXParser sp = spf.newSAXParser();
XMLReader xr = sp.getXMLReader();
ContentAndErrorHandler contentErrorHandler = new ContentAndErrorHandler(unmarshallerHandler);
xr.setErrorHandler(contentErrorHandler);
xr.setContentHandler(contentErrorHandler);
InputSource xml = new InputSource(new FileReader("input.xml"));
xr.parse(xml);
}
}
<强> ContentAndErrorHandler 强>
此类充当ContentHandler和ErrorHandler。这样就可以存储错误发生时的当前节点名称。
import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.ErrorHandler;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
public class ContentAndErrorHandler implements ContentHandler, ErrorHandler {
private ContentHandler contentHandler;
private String qname;
private String namespaceURI;
public ContentAndErrorHandler(ContentHandler contentHandler) {
this.contentHandler = contentHandler;
}
public void characters(char[] arg0, int arg1, int arg2) throws SAXException {
contentHandler.characters(arg0, arg1, arg2);
}
public void endDocument() throws SAXException {
contentHandler.endDocument();
}
public void endElement(String arg0, String arg1, String arg2)
throws SAXException {
qname = arg2;
namespaceURI = arg0;
contentHandler.endElement(arg0, arg1, arg2);
}
public void endPrefixMapping(String arg0) throws SAXException {
contentHandler.endPrefixMapping(arg0);
}
public void ignorableWhitespace(char[] arg0, int arg1, int arg2)
throws SAXException {
contentHandler.ignorableWhitespace(arg0, arg1, arg2);
}
public void processingInstruction(String arg0, String arg1)
throws SAXException {
contentHandler.processingInstruction(arg0, arg1);
}
public void setDocumentLocator(Locator arg0) {
contentHandler.setDocumentLocator(arg0);
}
public void skippedEntity(String arg0) throws SAXException {
contentHandler.skippedEntity(arg0);
}
public void startDocument() throws SAXException {
contentHandler.startDocument();
}
public void startElement(String arg0, String arg1, String arg2,
Attributes arg3) throws SAXException {
qname = arg2;
namespaceURI = arg0;
contentHandler.startElement(arg0, arg1, arg2, arg3);
}
public void startPrefixMapping(String arg0, String arg1)
throws SAXException {
contentHandler.startPrefixMapping(arg0, arg1);
}
public void error(SAXParseException arg0) throws SAXException {
System.out.println("{" + namespaceURI + "}" + qname);
arg0.printStackTrace(System.out);
}
public void fatalError(SAXParseException arg0) throws SAXException {
System.out.println("{" + namespaceURI + "}" + qname);
arg0.printStackTrace(System.out);
}
public void warning(SAXParseException arg0) throws SAXException {
System.out.println("{" + namespaceURI + "}" + qname);
arg0.printStackTrace(System.out);
}
}
<强>客户强>
import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
@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;
}
}
<强> ******中国强>
public class PhoneNumber {
}
<强> customer.xsd 强>
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="customer">
<xs:complexType>
<xs:sequence>
<xs:element name="name" type="stringWithMaxSize5" />
<xs:element ref="phone-number" maxOccurs="2" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="phone-number">
<xs:complexType />
</xs:element>
<xs:simpleType name="stringWithMaxSize5">
<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>
<强>输出强>
{}name
org.xml.sax.SAXParseException: cvc-maxLength-valid: Value 'Jane Doe' with length = '8' is not facet-valid with respect to maxLength '5' for type 'stringWithMaxSize5'.
at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(Unknown Source)
at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.error(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator$XSIErrorReporter.reportError(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.reportSchemaError(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.elementLocallyValidType(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.processElementContent(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.handleEndElement(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.endElement(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanEndElement(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.next(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(Unknown Source)
at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(Unknown Source)
at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(Unknown Source)
at example.Demo.main(Demo.java:39)
{}name
org.xml.sax.SAXParseException: cvc-type.3.1.3: The value 'Jane Doe' of element 'name' is not valid.
at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(Unknown Source)
at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.error(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator$XSIErrorReporter.reportError(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.reportSchemaError(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.elementLocallyValidType(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.processElementContent(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.handleEndElement(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.endElement(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanEndElement(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.next(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(Unknown Source)
at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(Unknown Source)
at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(Unknown Source)
at example.Demo.main(Demo.java:39)
{}phone-number
org.xml.sax.SAXParseException: cvc-complex-type.2.4.d: Invalid content was found starting with element 'customer'. No child element '{phone-number}' is expected at this point.
at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(Unknown Source)
at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.error(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator$XSIErrorReporter.reportError(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.reportSchemaError(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.elementLocallyValidComplexType(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.elementLocallyValidType(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.processElementContent(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.handleEndElement(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.endElement(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanEndElement(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.next(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(Unknown Source)
at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(Unknown Source)
at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(Unknown Source)
at example.Demo.main(Demo.java:39)