标签:json java spring jackson apache-camel
我有一个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"}
但是,现在我的一些键值条目将具有可选的可见性,我需要将其作为嵌套键值放在我的地图中.任何没有可选可见性的键值都将使用默认值.所以,例如,如果我指定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/添加嵌套键,一些键的值使用http://examples.javacodegeeks.com/core-java/json/jackson/convert-java-map-to-from-json-using-jackson-example/作为参考,但意识到这只是给了我一堆嵌套值在一个键下,而不是一堆嵌套键,值对.
即使我尝试使用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文档,但在撰写本文时,它没有使用嵌套键,值对指定示例.
更新:根据汤姆的反馈我创建了两个地图,即
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”,但稍后会将其更改为也从属性文件中提取.
解决方法:
您的结构不仅仅是一张地图.这是两个不同序列化的地图.表示这一点的一种方法是:
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
标签:json,java,spring,jackson,apache-camel 来源: https://codeday.me/bug/20190517/1121247.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。