0

我的要求是根据我从平面文件中吐出的正文内容进行 GET api 调用。并将 api 响应与原始正文聚合并生成 xml。

输入:

0150519821|0000000078|0000004892|US| .   
0150519822|0000000078|0000004896|US| .  
0150519824|0000000078|0000004893|US| .  
0150519826|0000000078|0000004898|US|

如果输入源中为“US”,则基于第四个位置。我必须进行 GET api 调用才能获得响应。

例子:

GET: return --> { "iD" : 1,"total" :23,"carrier" : "UPS" }

我必须生成 XML,其中包括 GET api 与输入源一起返回的字段。

示例输出:

<?xml version="1.0" encoding="UTF-8"?>

<TEST>
  <NUM>0150519821</NUM>
  <ID>0000000078</ID>
  <TOTAL>23</TOTAL>
  <CARRIER>UPS</CARRIER>
</TEST>

上面给出的 xml 输出确实有来自平面文件和 api 响应的两个字段。我正在使用 apache camel bindy 进行拆分并生成一个 xml。我必须根据我正在拆分的内容进行 api 调用,并聚合 api 返回的响应并生成输出 xml。

这是我实现的路由逻辑,请帮助我如何进行api调用和聚合。

转换器路由.java

 public class ConverterRoute implements RoutesBuilder {

        private Logger logger = LoggerFactory.getLogger(ConverterRoute.class);

        private static final String SOURCE_INPUT_PATH = "file://inbox?fileName=test.txt";

        private static final String SOURCE_OUTPUT_PATH = "file://outbox?fileName=file_$simple{date:now:yyyyMMddHHmmssSSS}.xml";

        BindyBeanConfig bindyBeanConfig = new BindyBeanConfig();

        @Override
        public void addRoutesToCamelContext(CamelContext context) throws Exception {

            context.addRoutes(new RouteBuilder() {
                public void configure() {
                    try {

from(SOURCE_INPUT_PATH)
    .split().tokenize(System.lineSeparator())
        .log("After Split input from file and body is ${body}")
        .choice()
            .when(method(MySplitterBean.class,"splitBody").isEqualTo("IN"))
                .unmarshal(bindyBeanConfig())
                .log("After Unmarshal and body is ${body}")
                .marshal()
                .log("After Marshalling and body is ${body}")
                .to(SOURCE_OUTPUT_PATH)
                .log("Finished Transformation")
            .when(method(MySplitterBean.class,"splitBody").isEqualTo("UK"))
                .unmarshal(bindyBeanConfig())
                .marshal()
                .log("After Marshalling and body is ${body}")
                .to(SOURCE_OUTPUT_PATH)
                .log("Finished Transformation")
            .when(method(MySplitterBean.class,"splitBody").isEqualTo("US"))
                .unmarshal(bindyBeanConfig())
                .log("Before Marshalling and body is ${body}")
                .setHeader(Exchange.HTTP_METHOD,constant("GET"))
                .setHeader(Exchange.CONTENT_TYPE, constant("application/json"))
                .to("http://localhost:8081/US")
                .process(exchange -> log.info("The response is: {}", exchange.getIn().getBody()))
                .marshal()
                .log("After Marshalling and body is ${body}")
                .to(SOURCE_OUTPUT_PATH)
                .log("Finished Transformation")
        .end();

                    } catch (Exception e) {
                        logger.info(e.getMessage());
                        e.printStackTrace();
                    }
                }
            });
            context.suspend();
            context.stop();
            }
    }

日志:

 2020-01-03 10:20:29.339  INFO 57630 --- [ - file://inbox] route1                                   : Finished Transformation
    2020-01-03 10:20:29.339  INFO 57630 --- [ - file://inbox] route1                                   : Before making api call <?xml version="1.0" encoding="UTF-8"?>

    <TEST>
      <NUM>0150519821</NUM>
      <ID>0000000078</ID>
    </TEST>
    2020-01-03 10:20:29.459  INFO 57630 --- [ - file://inbox] c.s.l.routes.ConverterRoute$1     : The response code is: org.apache.camel.converter.stream.CachedOutputStream$WrappedInputStream@1a7ebbd1

我能够在没有从 GET api 调用中获得的新字段(TOTAL,CARRIER)的情况下生成 XML。我得到了输出流对象,我想用新的两个字段来丰富 xml,所以 xml 如下所示。

从 GET API 调用添加新的两个字段后的预期输出。

<?xml version="1.0" encoding="UTF-8"?>

<TEST>
  <NUM>0150519821</NUM>
  <ID>0000000078</ID>
  <TOTAL>23</TOTAL>
  <CARRIER>UPS</CARRIER>
</TEST> 
4

1 回答 1

1

因此,如果我理解正确,您已经获得了这个 XML

<TEST>
    <NUM>0150519821</NUM>
    <ID>0000000078</ID>
</TEST>

但是您需要使用来自 API 调用的数据来丰富它以获取它

<TEST>
    <NUM>0150519821</NUM>
    <ID>0000000078</ID>
    <TOTAL>23</TOTAL>
    <CARRIER>UPS</CARRIER>
</TEST>

例如,您可以使用Camel Enrich EIP。这个页面上有一个很好的例子

在你的情况下,你可以

  • 将 API 调用外部化到专用路由
  • 从主路由调用新路由以使用 API 响应丰富当前消息体

消息体的合并方式在enrich. 您可以使用 POJO 作为聚合策略,请参阅链接示例。

您可以使用聚合中的新数据直接丰富 XML 正文。或者您可以保留旧的消息正文并将新数据保存为聚合中的消息头。然后,您可以在附加步骤中丰富 XML 正文。哪种更适合您的情况。

.when(method(MySplitterBean.class,"splitBody").isEqualTo("US"))
    ...        
    .enrich("direct:getCarrierData", aggregationStrategy)
    ...;

from("direct:getCarrierData")
    .setHeader(Exchange.HTTP_METHOD,constant("GET"))
    .setHeader(Exchange.CONTENT_TYPE, constant("application/json"))
    .to("http://localhost:8081/US")
于 2020-01-06T08:30:24.530 回答