0

我有以下两个 Java 类(SensorData 和 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; 
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; 
    } 

} 

可见性.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 键值对象。例如,假设我有两个来自传感器的键值对(品牌和型号),并且只有“品牌”键值对具有指定的可见性;“模型”键值对使用默认可见性:

    // 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"} 
}] 

但相反,我只看到将 SensorData 键值编组为 JSON 即:

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

为什么我看不到“s1make”和“_default”作为嵌套 JSON 的可见性?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 而不是地图。 如何使用 Camel 和 Jackson 库将嵌套的键、值对编组到 JSON 中?

4

1 回答 1

2

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

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

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

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

于 2013-10-21T15:19:06.887 回答