如何在AggregationStrategy中将消息体转换为pojo

时间:2016-09-21 20:02:11

标签: java apache-camel

我有一条路线(骆驼2.17.3),它使用丰富的DSL调用休息服务并将结果聚合到消息体中。不过,我遇到了序列化问题。这是我正在尝试的。我的路线看起来像这样:

rest("myService").produces("application/json")
            .get("test")
            .param().name("text").required(true).type(RestParamType.query).description("The text to be processed.").endParam()
                .to("direct:StepA")
    ;

    from("direct:StepA")
            .removeHeader("CamelHttpQuery")
            .removeHeader("CamelHttpRawQuery")
            .enrich("netty4-http://myOtherService:8080/endpoint?input=${header.text}", new MyAggregator())
            .to("direct:StepB")
    ;

    from("direct:StepB")
            // not really implemented yet
            .transform().simple("Query: ${header.text}\nBody: ${body}")
    ;

如您所见,我想使用enrich()DSL调用某些现有服务并将这些结果聚合在一起以形成新的消息体以供进一步处理。我需要将休息调用的结果从Json转换为MyResponse。我想用这个:

.unmarshal().json(JsonLibrary.Jackson, MyResponse.class)

但我需要它已经在我的AggregationStrategy中解组,看起来像这样:

public class MyAggregator implements AggregationStrategy {
    @Override
    public Exchange aggregate(Exchange oldExchange, Exchange newExchange) {
        final MyResponse intermediateResponse = oldExchange.getIn().getBody(MyResponse.class);

        final MyAggregate response = new MyAggregate(oldExchange.getIn().getHeader("text", String.class), intermediateResponse);

        newExchange.getIn().setBody(response);
        return newExchange;
}

当我说getBody(..)时,返回null。所以我了解了TypeConverters并尝试使用它,以便系统可以自动转换为我的类型:

public class MyConverter extends TypeConverterSupport {

    private static final ObjectMapper MAPPER =
        new ObjectMapper().enable(SerializationFeature.INDENT_OUTPUT);

    @Override
    public <T> T convertTo(Class<T> type, Exchange exchange, Object value) throws TypeConversionException {
        try {
            return (T)MAPPER.readValue(value.toString(), MyResponse.class);
        } catch (IOException e) {
           throw new TypeConversionException(value, type, e);
        }
}

然后在我的主要:

    public static void main(String... args) throws Exception {
        Main main = new Main();
        main.setApplicationContextUri("classpath:app-ctx.xml");

        for (final CamelContext ctx : main.getCamelContexts()) {
           ctx.getTypeConverterRegistry().addTypeConverter(MyResponse.class, String.class, new MyConverter());
        }

        main.run(args);
    }

但这似乎不会改变结果。在我的聚合器中,MyResponse仍为空。我错过了关于如何设置此类型转换的希望,并希望有人能指出我正确的方向。

1 个答案:

答案 0 :(得分:0)

好的,当我意识到我可以只是丰富一个执行unmarshall调用的子路由然后汇总那个......时,我最终完成了这个工作。

from("direct:StepA")
        .removeHeader("CamelHttpQuery")
        .removeHeader("CamelHttpRawQuery")
        .enrich("direct:StepAEnricher", new MyAggregator())
        .to("direct:StepB")
;

from("direct:StepAEnricher")
    .toD("netty4-http://myOtherService:8080/endpoint?input=${header.text}")
    .unmarshal().json(JsonLibrary.Jackson, MyResponse.class)
;

这完美无缺!我很好奇一个经验丰富的骆驼开发者会怎么想这个。使用这种“额外”路线来处理解扰这样的响应是否代价高昂?我仍然很好奇我将如何克服自定义类型转换器方法。