我有以下两个Java类(SensorData和Visibility)来存储虚拟传感器数据,并将它们各自的可见性存储到两个对象中:
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;
}
}
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&period={{config.timeout}}" />
<camel:to uri="log:hello.world.request?level=INFO&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&showAll=true" />
</camel:route>
</camel:camelContext>
上周我在SO上发布了一个类似的问题,但在我发布之后意识到我必须更改我的实现以将列表返回给Camel而不是地图。 How do I marshall nested key,value pairs into JSON with Camel and Jackson library?
答案 0 :(得分:2)
我不确定您为什么需要使用@JsonAnySetter/@JsonAnyGetter
,但如果必须,请在两个类中尝试使用
@JsonAnySetter
public void add(String key, String value) {
keyValues.put(key, value);
}
同时,您的setKeyValues
应该采用Map
参数。正如您现在所拥有的那样,您已经扩展了JavaBean约定。
另外,将Camel排除在等式之外。编写单元测试来测试你的配置,并确保你的对象按照你的预期进行序列化/反序列化,然后再将它们集成到Camel中,并等到运行时爆炸。