2011-10-24 9 views
0

IこのJSONの例をしました:xStreamではJSON - NULL値を処理する方法を

{ 
    "rows": [ 
     { 
      "anaid": "1", 
      "anaint": "123", 
      "anastring": "-" 
     }, 
     { 
      "anaid": "2", 
      "anaint": "-", 
      "anastring": "Hello World" 
     }, 
     { 
      "anaid": "3", 
      "anaint": "-", 
      "anastring": "-" 
     } 
    ] 
} 

私のクラスのテストでは、次のとおりです。

  • int型anaid
  • int型anaint
  • 文字列anastring

マイクコード:

XStream xstream = new XStream(new JettisonMappedXmlDriver()); 
xstream.alias("rows", Test.class); 
ArrayList<Test> product = (ArrayList<Test>) xstream.fromXML(json); 

文字「 - 」は、私のjsonのヌル値です。 jsonを作成するコードを変更することはできませんが、xStreamパーサーを正しく使用するにはnull値を処理します。

答えて

0

カスタムコンバータを使用します。 Tutorial here

+0

私は読んだけど、私はどうすればいいのか理解できませんでした... – CeccoCQ

0

XStreamのドキュメントとメーリングリストによれば、null値はマーシャル出力には含まれていません。

discussionは、表示方法を理解するのに役立ちました。要するに、このトリックは、Varunが言ったことです:デフォルトのReflectionConverterを拡張するためのカスタムコンバータ。このアイデアは、ヌル値イベントを無視して出力に書き込むことを止めることです。

ここでは、それがどのように働いたかについて詳しく説明します。残念ながら私は最終的な解決策を配布できません。私は次のことが多くのロックを解除したり、メインツリーの統合につながることを願っています。ここで

レシピ

は[1]とXStreamの1.4.2に基づいて、私の解決策の骨子である:

  1. com.thoughtworks.xstream.converters.reflection.ReflectionConverterクラスを拡張します。
  2. doMarshal/3メソッドをオーバーライドします。元のメソッドはnullイベントを無視するので、何も書き込まれません。新しいメソッドは、それらのイベントを受け取り、必要なもの(空ノード、自己閉じノード)を書き込むだけです。
  3. ヌル値ノードを書き込むためにwriteField/5メソッドをオーバーライドします。何を書くかは、何が望まれているかによって異なり、ライターオブジェクトに委任されるべきです。
  4. com.thoughtworks.xstream.io.ExtendedHierarchicalStreamWritercom.thoughtworks.xstream.io.ExtendedHierarchicalStreamWriterHelperクラスを拡張してカスタムライターを提供します。ヌル値ノードを書き留めるには、1つの方法が必要です。
  5. (非常に低い優先度で、リフレクションが基本であり、他のコンバータを引き継ぐので)コンバータを登録します。

より詳細

アプローチで、例えば、一方はXStreamのが設けられたライターを拡張し、余分なインターフェースを実装することができる:

// Context of "MyReflectionConverter"'s doMarshal method. 
void writeField(...) 
    if (newObj == null) { 
     NullExtendedHierarchicalStreamWriterHelper.emptyNode(
         writer.underlyingWriter(), 
         aliasName != null ? aliasName: 
          mapper.serializedMember(source.getClass(), fieldName), 
         fieldType); 
    } 
    else { // Rest of the original writeField method 
    } 
} 

インターフェースはここでemptyNodeを追加NullExtendedHierarchicalStreamWriterあります/ 2メソッドをExtendedHierarchicalStreamWriterに設定します。このメソッドは、セルフクローズノードとしてヌル値を書き込みます(例:XML <int value="num"/>の場合、numはヌル整数)。上記のスニペットは、補助者NullExtendedHierarchicalStreamWriterHelperを使用してこのライターのインスタンスを取得します。それ自体はExtendedHierarchicalStreamWriterHelperという単純な拡張です。ライターはラップされ、ラッパーはインターフェイスのヌル拡張を実装していないため、ヘルパーに渡されたライターはwriter.underlyingWriter()であることに注意してください。これは、より深い統合が行われるまで、私のソリューションはハックのままです。コンバータの

登録は、典型的には、このように行われる:

serializer = new XStream(new MyStreamDriver()); 

MyReflectionConverter reflectionConverter = new 
     MyReflectionConverter(serializer.getMapper(), 
           serializer.getReflectionProvider()); 
serializer.registerConverter(reflectionConverter, XStream.PRIORITY_VERY_LOW); 
Here

は、元のコードに対して、上記カスタム反射コンバータの差分です。これはメインツリーの一部ではなく、元のコードよりもはるかにテストされていない拡張機能だと考えてください。今日まで、テストスイートのケースをパスしています。

0

私にとっては簡単な方法は、ソースコードを入手ReflexionConvertedクラスをコピーして、メソッドpublicボイドマーシャル(オブジェクトの元、最終HierarchicalStreamWriterライター、最終MarshallingContextコンテキスト)...

にあなたが持っていることです。

reflectionProvider.visitSerializableFields(source, new ReflectionProvider.Visitor() { 
    public void visit(String fieldName, Class fieldType, Class definedIn, Object newObj) { 
     if (newObj != null) { 
      ... 
      complete the else method with your code...for example: 

     } else { 
      Object obj = new String(""); 

      writeField(fieldName, fieldType, definedIn, obj); 
      seenFields.add(fieldName); 

     } 
    } 
} 
関連する問題