camel-jackson 2.12.1是否支持将嵌套对象编组为嵌套JSON?

时间:2013-10-21 15:01:01

标签: json list jackson apache-camel

我有以下两个Java类(SensorData和Visibility)来存储虚拟传感器数据,并将它们各自的可见性存储到两个对象中:

SensorData.java

package com.data.world2; 

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

import com.fasterxml.jackson.annotation.JsonAnyGetter; 
import com.fasterxml.jackson.annotation.JsonAnySetter; 
import com.fasterxml.jackson.annotation.JsonProperty; 

public class SensorData { 

    private final Map<String, Object> keyvalues = new TreeMap<String, Object>(); 

    @JsonProperty 
    private Visibility visibility; 

    // getters and setters 
    @JsonAnyGetter 
    public Map<String, Object> getKeyvalues() { 
      return keyvalues; 
    } 

    @JsonAnySetter 
    public void setKeyvalues(final String key, final Object value) { 
      this.keyvalues.put(key, value); 
    } 

    // getters and setters 
    public Visibility getVisibility() { 
       return visibility; 
    } 

    public void setVisibility(Visibility visibility) { 
       this.visibility = visibility; 
    } 

} 

Visibility.java

package com.data.world2; 

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

import com.fasterxml.jackson.annotation.JsonAnyGetter; 
import com.fasterxml.jackson.annotation.JsonAnySetter; 

public class Visibility { 

    private final Map<String, Object> keyvalues = new TreeMap<String, Object>(); 

    // getters and setters 

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

    @JsonAnySetter 
    public void setKeyvalues(final String key, final Object value) { 
       this.keyvalues.put(key, value); 
    } 

} 

在我的SensorGenerator类中,我存储了SensorData和Visibility keyvalue对象。例如,假设我有一个来自传感器(品牌和型号)的两个键值对,并且只有“make”键值对具有指定的可见性; “model”键值对使用默认的可见性:

    // create a sensorData object, and a visibility object 
    SensorData sensorData = new SensorData(); 
    Visibility visibility = new Visibility(); 

    sensorData.setKeyValues("s1make", "Apple"); // set sensor 1 make 
    visibility.setKeyValues("s1make", "public"); // set sensor 1 make visibility 
    sensorData.setKeyValues("s1model", "iPhone5"); // set sensor 1 model 
    // sensor 1 model visibility not specified 

    // set default visibility 
    visibility.setKeyValues("_default", "private"); // set default visibility for sensor keyvalue pairs 

然后我将Visibility对象添加到SensorData对象以获得嵌套的可见性:

    // add the visibility to the SensorData object 
    sensorData.setVisibility(visibility); 

更新:

问题是我没有正确地将列表返回给Camel以便编组到JSON。

当我将代码更改为以下内容时,我将完整嵌套的JSON编组:

 List<SensorData> sensorDataList = new ArrayList<SensorData>();
 sensorDataList.add(sensorData);

以下是我之前的错误方法(仅供参考此历史信息)

然后我将一个SensorData对象列表返回给我的Camel线程,以便使用Jackson库(camel-jackson)编组到JSON:

    // Build a sensorDataList based on the keyvalues stored in the SensorData object 
    List<SensorData> sensorDataList = new ArrayList(sensorData.getKeyvalues().entrySet()); 

当我运行我的Java程序时,我希望从我的Camel路径中看到以下嵌套的JSON:

[{"key":"s1make","value":Apple"}, 
 {"key":"s1model","value":"iPhone5"}, 
 {"visibility": {"key":"s1make","value":"public", 
                 "key":"_default","value":"private"} 
}] 

但相反,我只看到将传感器数据关键值编组到JSON中,即:

[{"key":"s1make","value":Apple"}, 
 {"key":"s1model","value":"iPhone5"}] 

为什么我没有看到嵌套JSON的“s1make”和“_default”可见性? camel-jackson 2.12.1不支持将嵌套对象编组为嵌套JSON吗?

顺便说一句,这是我的applicationContext.xml的一个片段,我在其中指定编组为JSON:

      <camel:dataFormats>
         <camel:json id="jack" library="Jackson"/>
      </camel:dataFormats>

      <camel:route>

             <camel:from 
                     uri="timer://hello.world.request.timer?fixedRate=true&amp;period={{config.timeout}}" />
             <camel:to uri="log:hello.world.request?level=INFO&amp;showAll=true" />
             <camel:bean ref="helloWorld" />


             <camel:marshal ref ="jack"/>
             <camel:convertBodyTo type="java.lang.String" />
             <camel:log message="${body}"/>  


             <camel:log message="printing values read from config.properties file"/>
             <camel:log message="config.timeout= {{config.timeout}}"/>  
             <camel:log message="config.numSamples= {{config.numSamples}}"/>
             <camel:log message="config.defaultViz= {{config.defaultViz}}"/>


             <camel:to uri="log:hello.world.response?level=INFO&amp;showAll=true" />

       </camel:route>

 </camel:camelContext>

上周我在SO上发布了一个类似的问题,但在我发布之后意识到我必须更改我的实现以将列表返回给Camel而不是地图。 How do I marshall nested key,value pairs into JSON with Camel and Jackson library?

1 个答案:

答案 0 :(得分:2)

我不确定您为什么需要使用@JsonAnySetter/@JsonAnyGetter,但如果必须,请在两个类中尝试使用

@JsonAnySetter 
public void add(String key, String value) {
      keyValues.put(key, value);
}

同时,您的setKeyValues应该采用Map参数。正如您现在所拥有的那样,您已经扩展了JavaBean约定。

另外,将Camel排除在等式之外。编写单元测试来测试你的配置,并确保你的对象按照你的预期进行序列化/反序列化,然后再将它们集成到Camel中,并等到运行时爆炸。