gpt4 book ai didi

java - 如何使用 Camel 和 Jackson 库将嵌套的键值对编码到 JSON 中?

转载 作者:搜寻专家 更新时间:2023-10-31 19:55:46 24 4
gpt4 key购买 nike

我有一个 Java 项目,它当前返回一个映射到 Camel,没有任何嵌套的键、值对,并且 Jackson 库使用 Jackson 库将它编码到 JSON 中。

例如,如果我将以下两个键、值放入 demoMap 中:

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

我得到以下 JSON:

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

但是,现在我的一些键值条目将具有可选的可见性,我需要将其作为嵌套键值放入我的 map 中。任何没有可选可见性的键值都将使用默认值。因此,例如,如果我为 key1 和 key2 指定了可见性,但没有为 key3 指定可见性,我想得到如下所示的 JSON:

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

如何让 Camel 编码具有嵌套键值对的 Java 对象?我是一个视觉学习者,所以一个简单的例子会很有帮助。

我尝试更改我的 Map 以将值作为对象,即:

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 的某些键添加嵌套键和值供引用,但意识到这只是给了我一个键下的一堆嵌套值,而不是一堆嵌套的键值对。

即使当我为了 grins 尝试它时,我也从 Camel 处理器收到一个错误,带有 java.lang.ClassCastException 声明 java.util.ArrayList 无法转换为 java.lang.String

同样,当我试图在我的 demoMap 中嵌套一个 Map 时,我得到了这个 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

所以我知道如何不这样做。 :-/

我在 http://camel.apache.org/json.html 重新阅读了 Camel JSON 文档但在撰写本文时,它并未指定具有嵌套键值对的示例。

更新:根据 Tom 的反馈,我创建了两个 map ,即,

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

这是我称为 SensorGenerator 的类,它将属性文件加载到 map 中:

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”,但稍后会更改为也从属性文件中提取。

最佳答案

您的结构不仅仅是一张 map 。这是两张不同序列化的 map 。一种表示方式是:

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

关于java - 如何使用 Camel 和 Jackson 库将嵌套的键值对编码到 JSON 中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19389696/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com