2016-09-15 13 views
4

Jackson(JSONライブラリ)のValueNodeのすべてのサブクラスには、基本値オブジェクトを取得するためのさまざまなメソッドがあります。 IntNodegetIntValueBooleanNodegetBooleanValueとなります。Jackson - generic getValueメソッド

理由だけメソッドがコールされているノードのタイプに基づいて、等ObjectそのObjectあるいずれかInteger又はBooleanを返しgetValue単にないジェネリック/多型方法は存在しませんか?

または...実際にそのような方法はありますか? 私の目的にはこのような方法が必要ですが、図書館のデザイナーはこのような方法を追加すると便利ではないと思われます。または...何らかの理由でその方法が意図的に欠落していますか?

私の目的:私は、ツリーをトラバースし、唯一HashMapObject[]とJavaの基本タイプ(のようなIntegerBoolean、など)で構成される構造を生成しています下のコードでは。このような方法があれば、これらのすべてではなく、の場合はがValueNodeの葉ノードである場合には、ブロックの場合、 )。しかし、私はジャクソンのような方法はありません、そうです。だから私はそれらのすべてを醜いコード化しなければならなかったif-else if-elseの場合ブロック。

CODE:

@SuppressWarnings({ "rawtypes", "unchecked" }) 
     private static Object traverse(JsonNode nd) { 
      if (nd instanceof ObjectNode) { 
       ObjectNode ndd = (ObjectNode) nd; 
       HashMap mp = new HashMap(); 
       Iterator<String> it = ndd.getFieldNames(); 
       while (it.hasNext()) { 
        String s = it.next(); 
        mp.put(s, traverse(ndd.get(s))); 
       } 
       return mp; 
      } else if (nd instanceof ArrayNode) { 
       ArrayNode ndd = (ArrayNode) nd; 
       Object[] arr = new Object[ndd.size()]; 
       for (int i = 0; i < ndd.size(); i++) { 
        arr[i] = traverse(ndd.get(i)); 
       } 
       return arr; 
      } else if (nd instanceof NullNode) { 
       // NullNode ndd = (NullNode)nd; 
       return null; 
      } else if (nd instanceof BooleanNode) { 
       BooleanNode ndd = (BooleanNode) nd; 
       return ndd.getBooleanValue(); 
      } else if (nd instanceof IntNode) { 
       IntNode ndd = (IntNode) nd; 
       return ndd.getIntValue(); 
      } else if (nd instanceof LongNode) { 
       LongNode ndd = (LongNode) nd; 
       return ndd.getLongValue(); 
      } else if (nd instanceof DoubleNode) { 
       DoubleNode ndd = (DoubleNode) nd; 
       return ndd.getDoubleValue(); 
      } else if (nd instanceof DecimalNode) { 
       DecimalNode ndd = (DecimalNode) nd; 
       return ndd.getDecimalValue(); 
      } else if (nd instanceof BigIntegerNode) { 
       BigIntegerNode ndd = (BigIntegerNode) nd; 
       return ndd.getBigIntegerValue(); 
      } else if (nd instanceof TextNode) { 
       TextNode ndd = (TextNode) nd; 
       return ndd.getTextValue(); 
      } 

      throw new IllegalStateException("Failed while traversing the JSON tree at node: ||| " + nd.asText() + " |||"); 
     } 
+0

_私の目的にはこのような方法が必要です。 'JsonNode'とそのサブタイプはJSONツリーを表現するためのものなので、抽象クラスはJavaタイプではなくJSONタイプを表します。 –

+0

@SotiriosDelimanolis "したがって抽象概念はJava型ではなくJSON型を表しています。"まあ、JSON型はJava型にマップされています。 –

答えて

4

あなたはそれが

 JsonNode nodeBool = BooleanNode.TRUE; 
     Object objectBool = mapper.convertValue(nodeBool,Object.class); 
     Boolean returnValBool = (Boolean) objectBool; 
     System.err.println(returnValBool); 

     JsonNode nodeDouble = new DoubleNode(3.4); 
     Object objectDouble = mapper.convertValue(nodeDouble,Object.class); 
     Double returnValDouble = (Double) objectDouble; 
     System.err.println(returnValDouble); 

を働いていたし、それがようoutputedこの特定のテスト・ケースの場合、この

ObjectMapper mapper = new ObjectMapper(); 
return mapper.convertValue(nd,Object.class); 

のようなものを使用することができますObjectを戻ってきているので、予想:

true 
3.4 
+0

ありがとう、よく見えます。しかし、あなたはそれが私のコードのセマンティクスを保持すると確信していますか?つまり、これは私に以前にあったタイプの内部価値を与えるものです。ブール値の場合はブール値を維持しますか? –

+0

投稿する前に小さなテストを行い、うまくいきました。私はすべてのユースケースを保証することはできませんが、メソッドのいくつかの小さなユニットテストではこれを判断する必要があります –

2

これは興味深い問題です:)

全く一般的な方法はありませんなぜ私はわかりません。私はそれがオブジェクト型だけでなく、彼らが扱うという事実とは関係があると信じていますか?まあ、私は本当に彼らの設計決定を正当化する資格はありませんが、私はあなたの一般的な方法であなたを助けることができます。

あなたは正しいです、あなただけの値を()を呼び出すことはできませんが、あなただけのシリアル化(.. ..)

もっと詳しく呼び出すことができます。

は、すべての値のノードは、独自の値を保持します。すべての値ノードは、直列化の仕方を知っています。私たちはこれを利用することができます。

注:これはあなたがあなた自身のシリアライザを書き、それがそれらを取得するために、自分の価値観を保存することができ

少しハックのようになります

public static class MyGen extends GeneratorBase { 

     protected MyGen(int features, ObjectCodec codec) { 
      super(features, codec); 
     } 

     private Object currentObject = null; 

     @Override 
     public void flush() throws IOException { 
      // do nothing 
     } 

     @Override 
     protected void _releaseBuffers() { 
      // do nothing   
     } 

     @Override 
     protected void _verifyValueWrite(String typeMsg) throws IOException { 
      // do nothing 
     } 

     @Override 
     public void writeStartArray() throws IOException { 
      // do nothing 
     } 

     @Override 
     public void writeEndArray() throws IOException { 
     }   // do nothing 

     @Override 
     public void writeStartObject() throws IOException { 
      // do nothing 
     } 

     @Override 
     public void writeEndObject() throws IOException { 
      // do nothing 
     } 

     @Override 
     public void writeFieldName(String name) throws IOException { 
      // do nothing 
     } 

     @Override 
     public void writeString(String text) throws IOException { 
      currentObject = text; 
     } 

     @Override 
     public void writeString(char[] text, int offset, int len) throws IOException { 
      currentObject = new String(text); 
     } 

     @Override 
     public void writeRawUTF8String(byte[] text, int offset, int length) throws IOException { 
      currentObject = new String(text); 
     } 

     @Override 
     public void writeUTF8String(byte[] text, int offset, int length) throws IOException { 
      currentObject = new String(text); 
     } 

     @Override 
     public void writeRaw(String text) throws IOException { 
      currentObject = new String(text); 
     } 

     @Override 
     public void writeRaw(String text, int offset, int len) throws IOException { 
      currentObject = new String(text);   
     } 

     @Override 
     public void writeRaw(char[] text, int offset, int len) throws IOException { 
      currentObject = new String(text);   
     } 

     @Override 
     public void writeRaw(char c) throws IOException { 
      currentObject = new Character(c); 
     } 

     @Override 
     public void writeBinary(Base64Variant bv, byte[] data, int offset, int len) throws IOException { 
      currentObject = bv; 
     } 

     @Override 
     public void writeNumber(int v) throws IOException { 
      currentObject = new Integer(v); 
     } 

     @Override 
     public void writeNumber(long v) throws IOException { 
      currentObject = new Long(v); 
     } 

     @Override 
     public void writeNumber(BigInteger v) throws IOException { 
      currentObject = v; 
     } 

     @Override 
     public void writeNumber(double v) throws IOException { 
      currentObject = new Double(v); 
     } 

     @Override 
     public void writeNumber(float v) throws IOException { 
      currentObject = new Float(v); 
     } 

     @Override 
     public void writeNumber(BigDecimal v) throws IOException { 
      currentObject = v; 
     } 

     @Override 
     public void writeNumber(String encodedValue) throws IOException { 
      currentObject = encodedValue; 
     } 

     @Override 
     public void writeBoolean(boolean state) throws IOException { 
      currentObject = new Boolean(state); 
     } 

     @Override 
     public void writeNull() throws IOException { 
      currentObject = null; 
     } 

    } 

注、これは単なる-FOR-プロトタイプです楽しいテストとおそらくもう少し考えて行う必要があります。

しかし、それを、私が行うことができます。

印刷し
public static void main(String[] args) throws JsonProcessingException, IOException { 
     MyGen gen = new MyGen(0, new ObjectMapper()); 


     String test = "{ \"a\" : \"test\", \"b\" : 1, \"c\" : true, \"d\" : 2.5 }"; 

     JsonNode tree = new ObjectMapper().readTree(test); 

     Impl instance = new DefaultSerializerProvider.Impl(); 

     ObjectMapper m = new ObjectMapper(); 

     for(JsonNode node : tree) { 
      node.serialize(gen, instance); 
      Object currentObject = gen.currentObject; 
      System.out.println(currentObject); 
     } 

    } 

test 
1 
true 
2.5 

希望を助けること:)

アルトゥル

シモンズ:他の答えはかなりあるが短くて良い - しかし、私はこれもクールだと思ったので、とにかく投稿します。

編集:

あなたのコメントに関しては、ジェネレータは元の値を取得しますが、その値が保持されるのはあなた次第です。あなたはそれを完全に支配するでしょう。

+0

ありがとう、しかし、あなたが深刻なことはできません...月に戻って、むしろ戻ってきてください。何故なの? :)まだ...解決策を見つけようとしてくれてありがとう。 –

+0

haha​​ - いいえこれは理想的な解決策ではないと私は同意します。オブジェクトマッパーははるかに優れています。しかし、うーん..それは動作し、あなたが絶望的な場合は、それは..ええと何か:) – pandaadb

関連する問題