2

コードがさまざまな場所で無効な修飾名を作成しているという事実によって引き起こされる、多くの JAXB シリアライゼーション エラーに遭遇しました。私が使用している API やその他の Java XML オプションを調査していますが、奇妙なことの 1 つは、修飾名を実装するクラスが入力チェックをまったく実行していないように見えることです。

複雑なコードはさまざまな JAXB オブジェクトを生成するため、これは非常に問題があり、何かがひどく間違っていることに気付くのはマーシャリングの時までではありません。例外スタックは通常、どの要素/属性が間違っているかを教えてくれません。何かが間違っているだけです。

これらのライブラリが、シリアライズ不可能なコンテンツを最初から作成することをより困難にすることは、より理にかなっているのではないでしょうか?

コード スニペットを次に示します。なぜこれが機能するのでしょうか。スローすべきではありませんIllegalArgumentExceptionか?QName を定義する他の A​​PI でも、動作は同じです。このクラスの javadoc は、名前空間が null の場合は を取得するIllegalArgumentExceptionが、それ以外の場合は取得しないことを指定しています。

    QName q = new QName("Namespace URI is supposed to be an anyURI, but clearly !!THIS ISN'T!!", 
                        "Local part is supposed to be an NCName, but clearly !!THIS ISN'T!!",
                        "<><><><>&&& Laughably Invalid Namespace Prefix");
    System.out.println(q);

参考文献: QNameに関連する javadoc、name が anyURI であり、 localpart が NCName であることを示す仕様制約。つまり、仕様によれば、シリアル化に関係なく、上記のコードは明らかに無効です。

4

2 に答える 2

2

ここで仮説を立てます。

QName コンストラクターの主なユーザーは、一般的な Java コード自体ではなく、XML パーサーです。

XML 解析はパフォーマンスに影響されます。コンストラクターがパーサーによって呼び出されている場合、理論的にはパーサーは既に構文を検証しているため、もう一度検証するのは時間の無駄です。

95%の問題です。ユーザーの 5% に対価を支払う必要はありません。

有効な QName コンストラクターが必要な場合は、QName を拡張して独自のコードを追加できます。

例えば:

public class VerifiedQName extends QName {
    public VerifiedQName(String namespaceURI, String localPart) {            
        super(namespaceURI, localPart);
        verfiyNamespaceURI(namespaceURI); // throws IllegalArgumentException
        verifyLocalPart(localPart);  // throws IllegalArgumentException
    }
    ...
}

少なくとも、クラスは検証されていないと文書化されています。

于 2014-04-28T14:29:46.823 に答える
1

javax.xml.namespace.QNameは JAXB クラスではなく、JAXB が利用する Java SE の一部であるクラスです。

データを検証しない理由

  1. String操作にはコストがかかります。毎回検査の打撃を受けたいStringですか?
  2. 有効なローカル名または名前空間の定義が変更された場合、QNameどのバージョンの定義に対して検証するかを指定する必要がありますか? Java SE のバージョンが更新されてサポートされるまで、新しい定義を活用することはできませんか?
  3. ピンチでは、非 XML データで使用できます。一部の JAXB 実装 (つまり MOXy) は、XML (つまり JSON) 以外の形式をサポートしますQName。「無効な」データを許容するようなクラスを持つと、意図した以外の方法でそれらを使用することができます。

アップデート

これらが理由であることを知っていますか、それとも憶測ですか?

純粋な憶測ですが、私は JAXB のEclipseLink MOXy実装をリードしています。

コンストラクターで文字列チェックが高価になるのはなぜですか?

何もしないよりも費用がかかります。また、コンストラクター呼び出しあたりのコストが小さくても、操作を十分に実行すると、コストが高くなる可能性があります。

仕様に関連する他のタイプ (URL や URI など) は、両方ともコンストラクターから無効な形式の例外をスローすることに注意してください。

通常、これらのオブジェクトを大量に作成することはないため、例外によるユーザー支援は、チェックを行うコストを上回ります。

また、QNames の定義はいつ変更されますか?

変わる可能性が低いことは承知しています。ただし、JAXB 実装は、最近では XML 以外のサポートにも使用されることがよくあります。QNameJSON などの別の形式からデータを読み書きする場合は、寛容な実装を使用すると便利です。

于 2014-04-28T14:13:12.903 に答える