骆驼:不同系统上的奇怪 convertBodyTo 行为
Camel: strange convertBodyTo behaviour on different systems
这适用于 oracle-7-jdk
,icedtea-7-jdk
适用于 Gentoo linux kernel: 4.3.3-gentoo
:
.marshal().json(JsonLibrary.Jackson)
.setBody().jsonpath("$.listing")
.process(new Processor(){
@Override
public void process(Exchange ex){
LinkedHashMap<String, Object> map = (LinkedHashMap)ex.getIn().getBody();
map.put("_id", (Integer)map.get("id"));
map.remove("id");
}
})
.marshal().json(JsonLibrary.Jackson)
.convertBodyTo(String.class)
.to("mongodb:mongoBean?database=myDB&collection=myCol&operation=save");
同样的东西在 Ubuntu 14.4
under openjdk-7-jre
上不起作用
这东西也不行:
.marshal().json(JsonLibrary.Jackson)
.setBody().jsonpath("$.listing")
.process(new Processor(){
@Override
public void process(Exchange ex){
LinkedHashMap<String, Object> map = (LinkedHashMap)ex.getIn().getBody();
map.put("_id", (Integer)map.get("id"));
map.remove("id");
}
})
.marshal().json(JsonLibrary.Jackson)
.convertBodyTo(String.class)
.bean(org.bson.Document.class, "parse(${body})")
.to("mongodb:mongoBean?database=myDB&collection=myCol&operation=save");
考虑一下我在保存到 Mongo 之前添加了 .bean(org.bson.Document.class,"parse(${body})")
。
这是什么原因?
更新 1
使用 Camel 2.16.1
,没有容器。
第一个代码块抛出:
Caused by: org.apache.camel.InvalidPayloadException: No body available of type: com.mongodb.DBObject but has value: {"city":"Los Angeles","distance":null,....
第二个代码块抛出:
Caused by: org.apache.camel.NoTypeConversionAvailableException: No type converter available to convert from type: org.bson.Document to the required type: com.mongodb.DBObject
更新 2
对我有用的最终解决方案是:
.marshal().json(JsonLibrary.Jackson)
.setBody().jsonpath("$.listing")
.process(new Processor(){
@Override
public void process(Exchange ex){
LinkedHashMap<String, Object> map = (LinkedHashMap)ex.getIn().getBody();
map.put("_id", (Integer)map.get("id"));
map.remove("id");
Iterator<String> i = map.keySet().iterator();
while(i.hasNext()){
String key = i.next();
if(map.get(key) instanceof java.math.BigDecimal){
map.put(key, map.get(key).toString());
}
}
}
})
.convertBodyTo(com.mongodb.DBObject.class)
.to("mongodb:mongoBean?database=airbnb&collection=appartments&operation=save");
因为我收到 No type converter available
java.math.BigDecimal
;
更新 3
多环境没有区别。我假设 mvn exec:java
可以工作,但是在 maven-shade-plugin
的帮助下组装的 uberjar 没有,因为组件启动和(可能)类型转换器注册存在一些差异。
如果您的正文中有一个 Map
,您应该能够将它直接传递到 camel-mongodb
端点,因为该组件执行必要的类型转换以从以下位置转换:
Map
=> DBObject
(MongoDB 要求的类型)。
String
=> DBObject
.
File
=> DBObject
.
InputStream
=> DBObject
.
- 任何其他对象 =>
DBObject
首先使用 Jackson 将其转换为 Map
,然后再转换为 BasicDBObject
.
查看 available type conversions。
您可以尝试跳过编组到 JSON 和 convertBodyTo
吗?不过,请确保在类路径中保留 camel-jackson
+ 依赖项。
这适用于 oracle-7-jdk
,icedtea-7-jdk
适用于 Gentoo linux kernel: 4.3.3-gentoo
:
.marshal().json(JsonLibrary.Jackson)
.setBody().jsonpath("$.listing")
.process(new Processor(){
@Override
public void process(Exchange ex){
LinkedHashMap<String, Object> map = (LinkedHashMap)ex.getIn().getBody();
map.put("_id", (Integer)map.get("id"));
map.remove("id");
}
})
.marshal().json(JsonLibrary.Jackson)
.convertBodyTo(String.class)
.to("mongodb:mongoBean?database=myDB&collection=myCol&operation=save");
同样的东西在 Ubuntu 14.4
under openjdk-7-jre
上不起作用
这东西也不行:
.marshal().json(JsonLibrary.Jackson)
.setBody().jsonpath("$.listing")
.process(new Processor(){
@Override
public void process(Exchange ex){
LinkedHashMap<String, Object> map = (LinkedHashMap)ex.getIn().getBody();
map.put("_id", (Integer)map.get("id"));
map.remove("id");
}
})
.marshal().json(JsonLibrary.Jackson)
.convertBodyTo(String.class)
.bean(org.bson.Document.class, "parse(${body})")
.to("mongodb:mongoBean?database=myDB&collection=myCol&operation=save");
考虑一下我在保存到 Mongo 之前添加了 .bean(org.bson.Document.class,"parse(${body})")
。
这是什么原因?
更新 1
使用 Camel 2.16.1
,没有容器。
第一个代码块抛出:
Caused by: org.apache.camel.InvalidPayloadException: No body available of type: com.mongodb.DBObject but has value: {"city":"Los Angeles","distance":null,....
第二个代码块抛出:
Caused by: org.apache.camel.NoTypeConversionAvailableException: No type converter available to convert from type: org.bson.Document to the required type: com.mongodb.DBObject
更新 2
对我有用的最终解决方案是:
.marshal().json(JsonLibrary.Jackson)
.setBody().jsonpath("$.listing")
.process(new Processor(){
@Override
public void process(Exchange ex){
LinkedHashMap<String, Object> map = (LinkedHashMap)ex.getIn().getBody();
map.put("_id", (Integer)map.get("id"));
map.remove("id");
Iterator<String> i = map.keySet().iterator();
while(i.hasNext()){
String key = i.next();
if(map.get(key) instanceof java.math.BigDecimal){
map.put(key, map.get(key).toString());
}
}
}
})
.convertBodyTo(com.mongodb.DBObject.class)
.to("mongodb:mongoBean?database=airbnb&collection=appartments&operation=save");
因为我收到 No type converter available
java.math.BigDecimal
;
更新 3
多环境没有区别。我假设 mvn exec:java
可以工作,但是在 maven-shade-plugin
的帮助下组装的 uberjar 没有,因为组件启动和(可能)类型转换器注册存在一些差异。
如果您的正文中有一个 Map
,您应该能够将它直接传递到 camel-mongodb
端点,因为该组件执行必要的类型转换以从以下位置转换:
Map
=>DBObject
(MongoDB 要求的类型)。String
=>DBObject
.File
=>DBObject
.InputStream
=>DBObject
.- 任何其他对象 =>
DBObject
首先使用 Jackson 将其转换为Map
,然后再转换为BasicDBObject
.
查看 available type conversions。
您可以尝试跳过编组到 JSON 和 convertBodyTo
吗?不过,请确保在类路径中保留 camel-jackson
+ 依赖项。