骆驼:不同系统上的奇怪 convertBodyTo 行为

Camel: strange convertBodyTo behaviour on different systems

这适用于 oracle-7-jdkicedtea-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 + 依赖项。