4

私たちの製品では、apache CXF を使用しています。パフォーマンスの制限により、スキーマ検証は false に設定されています。ここで、無効な値を提供している整数要素の場合、JAXB はそれを別のものにアンマーシャリングしています。例えば、

9999999999 は 141006540​​7 に変換されます。

988888888888 は 1046410808 に変換されます。

私の質問は、ここで従われているロジック (式) は何ですか?

これを処理する方法(検証がオフになることを考慮して)?そのような値は拒否されたいです。

4

1 に答える 1

7

注: 私はEclipseLink JAXB(MOXy)のリーダーであり、JAXB(JSR-222)エキスパートグループのメンバーです。

短い答え

これは、JAXBリファレンス実装のバグのようです。次の場所にバグを入力することをお勧めします。

これと同じユースケースは、EclipseLink JAXB(MOXy)で正しく機能します。


長い答え

以下は、問題を示す完全な例です。

int以下は、integerフィールドを持つドメインクラスです。

package forum13216624;

import javax.xml.bind.annotation.*;

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Root {

    int int1;
    int int2;
    Integer integer1;
    Integer integer2;

}

input.xml

以下は、質問の値を含むXMLドキュメントです。

<?xml version="1.0" encoding="UTF-8"?>
<root>
    <int1>9999999999</int1>
    <int2>988888888888</int2>
    <integer1>9999999999</integer1>
    <integer2>988888888888</integer2>
</root>

デモ

以下のデモコードでは、にを指定しValidationEventHandlerましたUnmarshallerValidationEventこれは、操作中に検出された無効な値をキャッチする必要がありunmarhsalます。

package forum13216624;

import java.io.File;
import javax.xml.bind.*;

public class Demo {

    public static void main(String[] args) throws Exception {
        JAXBContext jc = JAXBContext.newInstance(Root.class);

        Unmarshaller unmarshaller = jc.createUnmarshaller();
        unmarshaller.setEventHandler(new ValidationEventHandler() {

            @Override
            public boolean handleEvent(ValidationEvent event) {
                System.out.println(event.getMessage());
                return true;
            }}

        );
        File xml = new File("src/forum13216624/input.xml");
        Root root = (Root) unmarshaller.unmarshal(xml);

        System.out.println(root.int1);
        System.out.println(root.int2);
        System.out.println(root.integer1);
        System.out.println(root.integer2);
    }

}

出力-JAXBリファレンス実装

この出力は、表示されている動作と一致します。

1410065407
1046410808
1410065407
1046410808

出力-EclipseLinkJAXB(MOXy)

JAXBプロバイダーとしてMOXyを指定した場合(http://blog.bdoughan.com/2011/05/specifying-eclipselink-moxy-as-your.htmlを参照)、このユースケースは期待どおりに機能します。ValidationEvent無効な値ごとにを取得し、ValidationEventが処理された場合、フィールド/プロパティは無効な値に設定されません。

Exception Description: The object [9999999999], of class [class java.lang.String], from mapping [org.eclipse.persistence.oxm.mappings.XMLDirectMapping[int1-->int1/text()]] with descriptor [XMLDescriptor(forum13216624.Root --> [DatabaseTable(root)])], could not be converted to [class java.lang.Integer].
Internal Exception: java.lang.NumberFormatException: For input string: "9999999999"

Exception Description: The object [988888888888], of class [class java.lang.String], from mapping [org.eclipse.persistence.oxm.mappings.XMLDirectMapping[int2-->int2/text()]] with descriptor [XMLDescriptor(forum13216624.Root --> [DatabaseTable(root)])], could not be converted to [class java.lang.Integer].
Internal Exception: java.lang.NumberFormatException: For input string: "988888888888"

Exception Description: The object [9999999999], of class [class java.lang.String], from mapping [org.eclipse.persistence.oxm.mappings.XMLDirectMapping[integer1-->integer1/text()]] with descriptor [XMLDescriptor(forum13216624.Root --> [DatabaseTable(root)])], could not be converted to [class java.lang.Integer].
Internal Exception: java.lang.NumberFormatException: For input string: "9999999999"

Exception Description: The object [988888888888], of class [class java.lang.String], from mapping [org.eclipse.persistence.oxm.mappings.XMLDirectMapping[integer2-->integer2/text()]] with descriptor [XMLDescriptor(forum13216624.Root --> [DatabaseTable(root)])], could not be converted to [class java.lang.Integer].
Internal Exception: java.lang.NumberFormatException: For input string: "988888888888"
0
0
null
null

潜在的な回避策

フィールド/プロパティがタイプIntegerであり、JAXBリファレンス実装から切り替えることができる場合XmlAdapterは、独自のIntegerto/fromString 変換を行うためのを作成できます。

IntegerAdapter

XmlAdapter以下は、独自の変換ロジックを提供する方法を示す例です。

package forum13216624;

import javax.xml.bind.annotation.adapters.XmlAdapter;

public class IntegerAdapter extends XmlAdapter<String, Integer>{

    @Override
    public Integer unmarshal(String string) throws Exception {
        return Integer.valueOf(string);
    }

    @Override
    public String marshal(Integer integer) throws Exception {
        return String.valueOf(integer);
    }

}

package-info

@XmlJavaTypeAdapterパッケージレベルでアノテーションを使用するということは、がこのパッケージのクラスXmlAdapterのタイプのすべてのフィールド/プロパティに適用されることを意味します。Integer

@XmlJavaTypeAdapter(value=IntegerAdapter.class, type=Integer.class)
package forum13216624;

import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;

出力

以下は、RIを使用した場合の更新された出力です。int値はまだ間違っていますが、値は正しくなく、期待IntegerどおりnullValidationEvents生成されます。

java.lang.NumberFormatException: For input string: "9999999999"
java.lang.NumberFormatException: For input string: "988888888888"
1410065407
1046410808
null
null

詳細については

于 2012-11-04T10:56:58.823 に答える