2013-10-15 58 views
5

我有一個Java項目,當前返回一個沒有任何嵌套的鍵,值對的駱駝地圖,傑克遜圖書館使用傑克遜圖書館將它很好地編入JSON。如何將嵌套的鍵值對與Camel和Jackson庫一起放入JSON中?

例如,如果我把下面的兩個鍵,值到一個demoMap:

Map<String,String> demoMap = new TreeMap<String,String> 
demoMap.put("key1","5"); 
demoMap.put("key2","10"); 

我得到以下JSON:

{"key1":"5","key2":"10"} 

不過,現在我的一些關鍵的,值的項有一個可選的可見性,我需要將其作爲嵌套鍵值放入我的地圖中。任何沒有可選可見性的鍵值都將使用默認值。因此,舉例來說,如果我指定鍵1和鍵2能見度,但不是KEY3我想JSON出來,看起來像這樣:

{"key1":"5", 
"key2":"10", 
"key3":"17", 
"visibility" : { "key1": "a&b&!c", "key2": "a&b", "_default": "a" } 
} 

我怎樣才能駱駝編組Java對象嵌套鍵,值對?我是一名視覺學習者,所以一個簡單的例子會很有幫助。

我試圖改變我的地圖有一個值作爲對象即,:

Map<String,Object> demoMap = new TreeMap<String,Object> 

,然後試圖將套疊的鍵,值使用http://examples.javacodegeeks.com/core-java/json/jackson/convert-java-map-to-from-json-using-jackson-example/參考一個ArrayList一些鍵,但後來發現這只是給我一個鍵下的一堆嵌套值,而不是一堆嵌套的鍵值對。

即使我嘗試了笑容,我從駱駝處理器與java.lang.ClassCastException說明java.util.ArrayList中的錯誤不能轉換爲java.lang.String

而且類似的,當我試圖窩我demoMap內的地圖,我得到這個ClassCastException異常:

3244 [hello.world.request.timer] ERROR org.apache.camel.processor.DefaultErrorHandler - Failed delivery for exchangeId: e6518e39-89b7-435e-96d9-ce26811ac67e. Exhausted after delivery attempt: 1 caught: java.lang.ClassCastException: java.util.HashMap cannot be cast to java.lang.String 

所以我知道怎麼不這樣做。 : -/

我重新閱讀了駱駝JSON文檔http://camel.apache.org/json.html,但在撰寫本文時並未指定嵌套鍵值對的示例。

更新:根據反饋湯姆我創建了兩個地圖即

Map<String,String> keyvalues = new TreeMap<String,String>(); 
Map<String,String> visibility = new TreeMap<String,String>(); 

這裏是我的課,我稱之爲SensorGenerator加載一個屬性文件成地圖:

package sample; 

import java.util.Map; 
import java.util.Properties; 
import java.util.TreeMap; 

import org.codehaus.jackson.annotate.JsonAnyGetter; 
import org.codehaus.jackson.annotate.JsonProperty; 

public class SensorGenerator { 

    private Properties sourceProperties; 

    // create a map of sensor keyvalues, and a map of sensor visibility 
    Map<String,String> keyvalues = new TreeMap<String,String>(); 
    @JsonProperty 
    Map<String,String> visibility = new TreeMap<String,String>(); 

    @JsonAnyGetter 
    public Map<String, String> getKeyvalues() { 

     for (Object key : sourceProperties.keySet()) { 

      // Separate out each of the field:datatype:visibility tuples as an entry in the 
      // values array 
      String[] values = sourceProperties.getProperty((String) key).split(
        ","); 
      // split the key between 'sensor' and the 'number' Ex: sensor1 -> sensor,1 
      String[] keyArray = key.toString().split("(?<=([a-zA-Z]++))"); 
      String keyNumber = keyArray[1]; // grab the number to append for each sensor 

      // define string buffer that appends sensor number for each sensor's 
      // keys. Ex: sensor1 would have s1make, s1makeDataType, etc. 
      StringBuffer sensorNumberStringBuffer = new StringBuffer(); 
      sensorNumberStringBuffer.append("s"); 
      sensorNumberStringBuffer.append(keyNumber); 

      // make, its data type, and visibility (with s# prefix) 
      StringBuffer makeStringBuffer = new StringBuffer(); 
      makeStringBuffer.append(sensorNumberStringBuffer); 
      makeStringBuffer.append("make"); 
      StringBuffer makeDataTypeStringBuffer = new StringBuffer(); 
      makeDataTypeStringBuffer.append(sensorNumberStringBuffer); 
      makeDataTypeStringBuffer.append("makeDataType"); 
      StringBuffer makeVizStringBuffer = new StringBuffer(); 
      makeVizStringBuffer.append(sensorNumberStringBuffer); 
      makeVizStringBuffer.append("makeViz"); 

      // model, its data type, and visibility (with s# prefix) 
      StringBuffer modelStringBuffer = new StringBuffer(); 
      modelStringBuffer.append(sensorNumberStringBuffer); 
      modelStringBuffer.append("model"); 
      StringBuffer modelDataTypeStringBuffer = new StringBuffer(); 
      modelDataTypeStringBuffer.append(sensorNumberStringBuffer); 
      modelDataTypeStringBuffer.append("modelDataType"); 
      StringBuffer modelVizStringBuffer = new StringBuffer(); 
      modelVizStringBuffer.append(sensorNumberStringBuffer); 
      modelVizStringBuffer.append("modelViz"); 

      // serialNumber, its data type, and visibility (with s# prefix) 
      StringBuffer serialNumberStringBuffer = new StringBuffer(); 
      serialNumberStringBuffer.append(sensorNumberStringBuffer); 
      serialNumberStringBuffer.append("serialNumber"); 
      StringBuffer serialNumberDataTypeStringBuffer = new StringBuffer(); 
      serialNumberDataTypeStringBuffer.append(sensorNumberStringBuffer); 
      serialNumberDataTypeStringBuffer.append("serialNumberDataType"); 
      StringBuffer serialNumberVizStringBuffer = new StringBuffer(); 
      serialNumberVizStringBuffer.append(sensorNumberStringBuffer); 
      serialNumberVizStringBuffer.append("serialNumberViz"); 

      // sensorType, its data type, and visibility (with s# prefix) 
      StringBuffer sensorTypeStringBuffer = new StringBuffer(); 
      sensorTypeStringBuffer.append(sensorNumberStringBuffer); 
      sensorTypeStringBuffer.append("sensorType"); 
      StringBuffer sensorTypeDataTypeStringBuffer = new StringBuffer(); 
      sensorTypeDataTypeStringBuffer.append(sensorNumberStringBuffer); 
      sensorTypeDataTypeStringBuffer.append("sensorTypeDataType"); 
      StringBuffer sensorTypeVizStringBuffer = new StringBuffer(); 
      sensorTypeVizStringBuffer.append(sensorNumberStringBuffer); 
      sensorTypeVizStringBuffer.append("sensorTypeViz"); 

      // put all the field:datatype keyvalues for this sensor in the keyvalues map 
      // and visibilities in the visibility map 

      // make, data type, and visibility 
      keyvalues.put(makeStringBuffer.toString(), values[0].split(":")[0]); 
      keyvalues.put(makeDataTypeStringBuffer.toString(), values[0].split(":")[1]); 
      visibility.put(makeVizStringBuffer.toString(), values[0].split(":")[2]); 

      // model, data type, and visibility 
      keyvalues.put(modelStringBuffer.toString(), values[1].split(":")[0]); 
      keyvalues.put(modelDataTypeStringBuffer.toString(), values[1].split(":")[1]); 
      visibility.put(modelVizStringBuffer.toString(), values[1].split(":")[2]); 

      // serialNumber, data type, and visibility 
      keyvalues.put(serialNumberStringBuffer.toString(), values[2].split(":")[0]); 
      keyvalues.put(serialNumberDataTypeStringBuffer.toString(), values[2].split(":")[1]); 
      visibility.put(serialNumberVizStringBuffer.toString(), values[2].split(":")[2]); 

      // sensorType, data type, and visibility 
      keyvalues.put(sensorTypeStringBuffer.toString(), values[3].split(":")[0]); 
      keyvalues.put(sensorTypeDataTypeStringBuffer.toString(), values[3].split(":")[1]); 
      visibility.put(sensorTypeVizStringBuffer.toString(), values[3].split(":")[2]); 

      // add in default visibility 
      visibility.put("_default", "a"); 

     } 
     return keyvalues; 
    } 

    public void setSourceProperties(Properties properties) { 
     this.sourceProperties = properties; 
    } 

} 

眼下我只是將默認可見性硬編碼爲「a」,但稍後會將其更改爲從屬性文件中提取。

回答

6

你的結構不僅僅是一張地圖。這是兩個不同序列化的地圖。代表這一種方法是:

public class Whatever{ 
    Map<String,String> keyvalues; 
    Map<String,String> visibility; 
} 

什麼你最終得到的是這樣,它雖然代表了數據很不理想:

{ 
"keyvalues" : { "key1": "5", "key2": "10", "key3": "17"}, 
"visibility" : { "key1": "a&b&!c", "key2": "a&b", "_default": "a" } 
} 

爲了得到你想要的東西,用@JsonAnyGetter 。像這樣的東西(它可以作出更容易使用):

public class Whatever{ 
    Map<String,String> keyvalues = new TreeMap<String,String>(); 
    @JsonProperty 
    Map<String,String> visibility = new TreeMap<String,String>(); 

    @JsonAnyGetter 
    public Map<String, String> getKeyvalues() { 
     return keyvalues; 
    } 
} 

主要生產:

  {"visibility":{"key1":"a&b&!c","key2":"a&b"},"key1":"5","key2":"10"} 

我今天這個一直纏鬥和你的問題啓發了我,使之血腥的工作:d註解在這裏:https://github.com/FasterXML/jackson-annotations/wiki/Jackson-Annotations

見的JUnit測試在這裏:https://gist.github.com/TomDemeranville/7009250

+0

湯姆,謝謝你的信息。我在你建議的代碼中添加了,但是當我運行該程序時,我只能看到JSON中的關鍵值。出於某種原因,我沒有看到嵌套的可視性字段。我會附上我的SensorGenerator.java類,也許我錯過了一些東西:-) – erj2code

+0

這裏是作爲JUnit測試。這個測試適用於我。傑克遜你在用什麼版本? https://gist.github.com/TomDemeranville/7009250 – tom

+0

我使用駱駝傑克遜2.12.1。我在我的pom.xml以下依賴性:\t \t \t \t \t org.apache.camel \t \t \t 駱駝傑克遜 \t \t \t $ {}駱駝 \t \t在哪裏定義上面的$ {camel}爲2.12.1 – erj2code

相關問題