简体   繁体   English

如何编写 Apache 骆驼路线来检查 XML 内容并将其转换为 JSON 和 Z3418008FDD81C28 引导服务反之亦然

[英]How to write a Apache Camel route to check and convert XML contents to JSON and vice-versa for a Spring boot service

I am new to using Apache camel with Spring boot and try to implement a basic route in which, I want to filter out first whether the file has json contents or xml contents and based upon it, I want to save the file in some specific folder. I am new to using Apache camel with Spring boot and try to implement a basic route in which, I want to filter out first whether the file has json contents or xml contents and based upon it, I want to save the file in some specific folder .

I make my service instance up and then hit its post endpoint using postman with JSON content.我创建了我的服务实例,然后使用 postman 和 JSON 内容点击它的后端点。 My service saves that file to some folder location with txt extension.我的服务将该文件保存到具有 txt 扩展名的某个文件夹位置。 I have created the route in the service which picks up the file and checks if it is not empty, it will transform the contents in to XML format and store it to some folder.我在服务中创建了获取文件并检查它是否不为空的路由,它将内容转换为 XML 格式并将其存储到某个文件夹中。 Route for this thing is below:这件事的路线如下:

public class OutboundRoute extends RouteBuilder {

    Predicate p1=body().isNotNull();
    Predicate p2=body().isNotEqualTo("");

    Predicate predicateGroup=PredicateBuilder.and(p1,p2);

    String inputFilePath="file:C:\\Users\\StorageFolder\\Input?noop=true";

    String outputFilePathForJson="file:C:\\Users\\StorageFolder\\JsonFolderOutput?delete=true";

    @Override
    public void configure() throws Exception {
        from(inputFilePath)
                .routeId("readingJsonFromFile")
                .choice()
                .when(predicateGroup)
                        .log("Before converting to XML: ${body}")
                        .unmarshal().json(JsonLibrary.Jackson, Message.class)
                        .marshal().jacksonXml(true)
                        .log(LoggingLevel.INFO, "Payload after converting to xml = ${body}")
                        .to(outputFilePathForJson)
                .otherwise()
                .log("Body is Empty!!")
        .end();
    }
}

Now I want to implement this thing for xml also for better understanding.现在我想为 xml 实现这个东西也是为了更好地理解。 I want that I can hit my service using postman with either XML or JSON content.我希望我可以使用 postman 和 XML 或 JSON 内容来访问我的服务。 The route should pick the file and check it.路线应该选择文件并检查它。 If it has XML contents, route should convert its contents to JSON and store it to JSON folder but if it has JSON contents, route should convert its contents to XML and store it to XML folder. If it has XML contents, route should convert its contents to JSON and store it to JSON folder but if it has JSON contents, route should convert its contents to XML and store it to XML folder. I need help with this thing.我需要这件事的帮助。

Main thing is that when I hit the service using postman, service will always store the file with txt extension only.主要的是,当我使用 postman 访问服务时,服务将始终仅存储扩展名为 txt 的文件。 So, I need help with a way to find that content of file is of JSON format or XML format.所以,我需要帮助找到文件内容是 JSON 格式或 XML 格式的方法。

Also, I tried finding some content about learning apache camel but everywhere found basic tutorials only.另外,我尝试找到一些有关学习 apache 骆驼的内容,但到处都只能找到基本教程。 Can someone recommend some platform where I can learn how to write complex routes?有人可以推荐一些我可以学习如何编写复杂路线的平台吗?

Personally, I would use something like Apache Tika to make an educated guess on the file type and slap a Content-Type in the camel headers.就个人而言,我会使用Apache Tika之类的东西来对文件类型进行有根据的猜测,并在骆驼标题中添加 Content-Type。 Then you can handle any number of types of files by using theChoice Enterprise Integration Pattern.然后,您可以使用选择企业集成模式处理任意数量的文件类型。 This relies heavily on the Camel Direct Component , which I suggest learning about as it often used in Camel development for composable routes.这在很大程度上依赖于Camel Direct 组件,我建议学习它,因为它经常在 Camel 开发中用于可组合路线。 This would looks something like the following:这看起来如下所示:

from(inputFilePath)
    .process(exchange -> {
        Metadata metadata = new Metadata();
        File f = exchange.getIn().getBody(File.class)
        String mimetype = tika.getDetector().detect(TikaInputStream.get(f, metadata), metadata);
        exchange.setHeader("Content-Type", mimetype)
    })
    .to("direct:content-type-chooser")

// route that just determines routing using the 
from("direct:content-type-choose")
    .choice()
        .when(header("Content-Type").contains("application/xml")).to("direct:process-xml")
        .when(header("Content-Type").contains("application/json")).to("direct:process-json")
    .otherwise()
        .to("direct:unsupported-type")

// route for processing xml
from("direct:process-xml")
    ...

// route for processing json    
from("direct:process-json")
    ...

// route for giving an error because we don't support it, or doing whatever you do (like move it to another folder for later processing)
from("direct:unsupported-type")
    ...

Once you have gotten to a specific type, you can leverage Marshallers and Unmarhallers .获得特定类型后,您可以利用MarshallersUnmarhallers

Unfortunately, the only way to learn camel is to read the docs (thoroughly) and use it.不幸的是,学习骆驼的唯一方法是(彻底)阅读文档并使用它。 Because camel is really just an extension of java, using standardized communication patterns, it really can do anything, so the amount that it can do could fill the internet.因为骆驼其实只是java的一个扩展,使用标准化的通信模式,它真的可以做任何事情,所以它可以做的量可以填满互联网。 This problem is prevalent in all frameworks.这个问题在所有框架中都很普遍。 For example, if you learn Spring, there are a lot of "Hello World" projects, but not a ton that do really complicated things.例如,如果你学习 Spring,有很多“Hello World”项目,但真正复杂的事情却不多。 For that, you might have to scour GitHub codebases or do really targeted google searches.为此,您可能必须搜索 GitHub 代码库或进行真正有针对性的谷歌搜索。

I won't say its a good answer but an easy alternative I would say.我不会说这是一个很好的答案,但我会说一个简单的选择。

What I did is, I created a processor which will check first character of file and if its "{", then its json and if its "<", then its XML.我所做的是,我创建了一个处理器,它将检查文件的第一个字符,如果是“{”,则检查其 json,如果是“<”,则检查其 XML。 So, after detecting, I would add a header to camel route exchange as "Type": json or xml or unknown因此,在检测到之后,我会在骆驼路线交换中添加一个 header 作为“类型”:json 或 xml 或未知

And using camel's "simple" language,I will check the header and based on that, in the route, I will do the processing.并使用骆驼的“简单”语言,我将检查 header 并基于此,在路线中,我将进行处理。 I am adding below files for better reference.我正在添加以下文件以供更好的参考。

Predicates used in route:路由中使用的谓词:

private Predicate notNull=body().isNotNull();

    private Predicate notEmpty=body().isNotEqualTo("");

    private Predicate checkEmptyFile=PredicateBuilder.and(notNull,notEmpty);


    private Predicate checkIfJsonContents=header("Type").isEqualTo("json");

    private Predicate checkIfXmlContents=header("Type").isEqualTo("xml");

    private Predicate checkIfFileHasJsonContents=PredicateBuilder.and(checkEmptyFile,checkIfJsonContents);

    private Predicate checkIfFileHasXmlContents=PredicateBuilder.and(checkEmptyFile,checkIfXmlContents);

Route:路线:

from(inputFilePath)
                    .routeId("readingJsonFromFile")
                    .routeDescription("This route will assign a file type to file based on contents and then save it in different folder based on contents.")
                .process(fileTypeDetectionProcessor)
                .log("Added file type to header as: ${header.Type}")
                .choice()
                .when(checkIfFileHasJsonContents)
                    .log("Payload before converting to XML: ${body}")
                    .unmarshal().json(JsonLibrary.Jackson, Message.class)
                    .marshal().jacksonXml(true)
                    .log(LoggingLevel.INFO, "Payload after converting to xml = ${body}")
                    .to(outputFilePathForXml)
                .when(checkIfFileHasXmlContents)
                    .log("Payload before converting to JSON: ${body}")
                    .unmarshal().jacksonXml(Message.class,true)
                    .marshal().json(true)
                    .log(LoggingLevel.INFO, "Payload after converting to JSON = ${body}")
                    .to(outputFilePathForJson)
                .otherwise()
                    .log("Unreadable format or empty file!!")
                    .to(outputFilePathForBadFile)
                .end();

Processor:处理器:

public class FileTypeDetectionProcessor implements Processor {


    @Override
    public void process(Exchange exchange) throws Exception {

        if(exchange.getIn().getBody(String.class).startsWith("{"))
            exchange.getIn().setHeader("Type","json");
        else if(exchange.getIn().getBody(String.class).startsWith("<"))
            exchange.getIn().setHeader("Type","xml");
        else
            exchange.getIn().setHeader("Type","unknown");
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM