7

JAXB アノテーションを持ついくつかのクラスがあり、いくつかのインスタンスを作成しましたが、それらを XSD ファイルに対して検証する必要があります。オブジェクトが無効な場合に何が問題なのかの詳細を取得できるはずです。

このクラス ValidationEventHandler については知っていますが、明らかに Unmarshaller クラスで使用できます。問題は、生の XML ではなくオブジェクトを検証する必要があることです。

私はこのコードを持っています:

MyClass myObject = new MyClass();
JAXBContext jaxbContext = JAXBContext.newInstance("x.y.z");
JAXBSource jaxbSource = new JAXBSource(jaxbContext, myObject);
SchemaFactory factory = SchemaFactory
                .newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Source schemaFile = new StreamSource(getClass().getClassLoader()
                .getResourceAsStream("mySchema.xsd"));
Schema schema = factory.newSchema(schemaFile);

Validator validator = schema.newValidator();

validator.validate(jaxbSource);

このコードは機能し、オブジェクトを検証して、次のようなメッセージで例外をスローします。

cvc-pattern-valid: 値 '12345678901' は、タイプ 'id' のパターン '\d{10}' に関してファセット有効ではありません。]

問題は、すべてのメッセージを解析する必要があるような文字列を使用して、特定の詳細が必要なことです。

4

2 に答える 2

1

のインスタンスをErrorHandleron に設定して、Validator個々のエラーをキャッチできます。

    Validator validator = schema.newValidator();
    validator.setErrorHandler(new MyErrorHandler());
    validator.validate(source);

MyErrorHandler

以下は、ErrorHandlerインターフェースの実装例です。例外を再スローしない場合、検証は続行されます。

import org.xml.sax.ErrorHandler;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;

public class MyErrorHandler implements ErrorHandler {

    public void warning(SAXParseException exception) throws SAXException {
        System.out.println("\nWARNING");
        exception.printStackTrace();
    }

    public void error(SAXParseException exception) throws SAXException {
        System.out.println("\nERROR");
        exception.printStackTrace();
    }

    public void fatalError(SAXParseException exception) throws SAXException {
        System.out.println("\nFATAL ERROR");
        exception.printStackTrace();
    }

} 

詳細については

于 2012-06-19T19:24:56.333 に答える
0

I. 複雑なオブジェクト階層を検証する場合、Marshaller を自分で作成し、そのリスナーを設定できます。

Marshaller marshaller = jaxbContext.createMarshaller();
marshaller.setListener(yourListener);
JAXBSource source = new JAXBSource(marshaller, object);

このリスナーは、階層を移動するときに、オブジェクトのインスタンスで通知を受け取ります。

Ⅱ.ErrorHandler他の回答から追加します。少なくとも Wildfly 15 では、メッセージは次のようになります。

cvc-maxInclusive-valid: 値 '360.953674' は、タイプ '#AnonType_longitudeGeographicalPosition' の maxInclusive '180.0' に関してファセット有効ではありません。
cvc-type.3.1.3: 要素「経度」の値「360.953674」は無効です。

したがって、有罪の端末フィールド名である要素名を解析できます。

III. I と II をいくつかのイントロスペクションと組み合わせると、必要に応じて、エラーのあるフィールドへの Java Beans スタイルの完全なパスを再構築できます。

于 2020-08-31T13:30:38.310 に答える