任何人都知道如何使用 JaxB 2.x 进行自定义验证消息?我需要知道哪个标签或对象属性导致了错误。我已经有一个自定义的ValidationEventHandler,但是handleEvent方法的ValidationEvent事件参数并没有带来Node信息,只是XML文档中与错误相关的行和列。我的意图是用更用户友好的方式自定义解组错误消息。有办法做到这一点吗?
谢谢!
任何人都知道如何使用 JaxB 2.x 进行自定义验证消息?我需要知道哪个标签或对象属性导致了错误。我已经有一个自定义的ValidationEventHandler,但是handleEvent方法的ValidationEvent事件参数并没有带来Node信息,只是XML文档中与错误相关的行和列。我的意图是用更用户友好的方式自定义解组错误消息。有办法做到这一点吗?
谢谢!
提供有关问题原因的javax.xml.bind.ValidationEventLocator
一些信息。
元帅行动
在封送操作期间报告 ValidationEvent 时,与错误相关的对象应可通过以下方式获得:
validationEvent.getLocator().getObject();
解组操作
在解组操作期间报告 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 {
}
客户.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>
输入.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)