首页 > 解决方案 > 无法使用 Apache Camel 3.1.0 将 XML 转换为 JSON

问题描述

我正在通过 Jean-Baptiste 的 Mastering Apache Camel一书学习 Apache Camel 。我需要学习这个框架,以便在我目前的工作中使用它。

书中使用的 Apache Camel 版本是 2.12.4,但我无意中用 3.1.0 版本做了很多 PoC。

在这一刻,我正在尝试将 XML 文件转换为 JSON 文件,但没有任何结果。

我的pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.redhat</groupId>
    <artifactId>apachecamel-learning</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <dependencies>
        <!-- Apache CAMEL -->
        <dependency>
            <groupId>org.apache.camel</groupId>
            <artifactId>camel-core</artifactId>
            <version>3.1.0</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-simple</artifactId>
            <version>1.7.30</version>
        </dependency>

        <!-- MARSHALL AND UNMARSHALL -->
        <dependency>
            <groupId>org.apache.camel</groupId>
            <artifactId>camel-jackson</artifactId>
            <version>3.1.0</version>
        </dependency>


        <!-- Camel JMS -->
        <dependency>
            <groupId>org.apache.camel</groupId>
            <artifactId>camel-jms</artifactId>
            <version>2.5.0</version>
        </dependency>

        <!-- ActiveMQ -->
        <dependency>
            <groupId>org.apache.activemq</groupId>
            <artifactId>activemq-core</artifactId>
            <version>5.3.2</version>
        </dependency>

        <!-- OSGi -->
        <dependency>
            <groupId>org.osgi</groupId>
            <artifactId>org.osgi.core</artifactId>
            <version>4.3.1</version>
            <scope>provided</scope>
        </dependency>

    </dependencies>
</project>

我的Java 类

package com.redhat.pocs.camel.eip;


import org.apache.camel.CamelContext;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.impl.DefaultCamelContext;
import org.apache.camel.model.dataformat.JacksonXMLDataFormat;

public class TestMarshallAndUnmarshall {

    public static void main(String[] args) throws Exception {
        CamelContext context = new DefaultCamelContext();
        context.addRoutes(new RouteBuilder() {
            public void configure() {
                from("file:/tmp/in")
                .marshal(new JacksonXMLDataFormat())
                .to("file:/tmp/out");
            }
        });
        context.start();
        Thread.sleep(10000); // Prevent to Camel to shutdown and don't run the route
        context.stop();
        context.close();
    }

}

我尝试使用 XmlJsonDataFormat、JaxbDataFormat、JacksonXMLDataFormat 并且总是出现相同的错误:

Exception in thread "main" org.apache.camel.FailedToCreateRouteException: Failed to create route route1 at: >>> Marshal[org.apache.camel.model.dataformat.JacksonXMLDataFormat@6e4784bc] <<< in route: Route(route1)[From[file:/tmp/in] -> [Marshal[org.apache.came... because of Data format 'jacksonxml' could not be created. Ensure that the data format is valid and the associated Camel component is present on the classpath

有谁知道我做错了什么?

标签: javajsonxmlapache-camel

解决方案


骆驼 2

从 2.10.x 版本开始,就有了 camel-xmljson 组件。

我这样使用它(版本 2.22.2)

骆驼路线:

    final XmlJsonDataFormat xmlJsonFormat = new XmlJsonDataFormat();
    xmlJsonFormat.setRootName("result");
      
    CamelContext context = new DefaultCamelContext();
    context.addRoutes(new RouteBuilder() {
        public void configure() {
            from("file:/tmp?fileName=in.xml")
            .marshal(xmlJsonFormat)              
            .to("file:/tmp?fileName=out.json")
            .end();
        }
    });
    
    context.start();
    Thread.sleep(5000); // Prevent to Camel to shutdown and don't run the route
    context.stop();

Pom.xml:

...
    <dependency>
      <groupId>org.apache.camel</groupId>
      <artifactId>camel-core</artifactId>
      <version>${camel.version}</version>
    </dependency>
    <dependency>
      <groupId>org.apache.camel</groupId>
      <artifactId>camel-xmljson</artifactId>
      <version>${camel.version}</version>
    </dependency>
    <dependency>
      <groupId>xom</groupId>
      <artifactId>xom</artifactId>
      <version>1.2.5</version>
    </dependency>
...

对于骆驼 3

这个版本的骆驼不推荐使用 camel-xmljson 组件。我找不到从 xml 转换为 json 的直接方法。

不幸的是,我完成这项工作的唯一方法是使用中间 pojo。所以首先我从 xml 转换为 Pojo,然后从 Pojo 转换为 json。

骆驼路线:

      JacksonDataFormat jacksonDataFormat = new JacksonDataFormat();
      jacksonDataFormat.setPrettyPrint(true);
      jacksonDataFormat.enableFeature(SerializationFeature.WRAP_ROOT_VALUE);
            
      CamelContext context = new DefaultCamelContext();
      context.addRoutes(new RouteBuilder() {
          public void configure() {
              from("file:/tmp?fileName=in.xml")
              .unmarshal().jacksonxml(Order.class)
              .marshal(jacksonDataFormat)
              .to("file:/tmp?fileName=out.json")
              .end();
          }
      });
      context.start();
      Thread.sleep(10000); // Prevent to Camel to shutdown and don't run the route
      context.stop();
      context.close();

订单和项目类


public class Order {
  
  @JacksonXmlProperty(localName = "name")
  private String name;
  
  @JacksonXmlProperty(localName = "items")
  private List<Item> items;
 
  public Order() {
    
  }

  public String getName() {
    return name;
  }
  public void setName(String name) {
    this.name = name;
  }
  
  public List<Item> getItems() {
    return items;
  }

  public void setItems(List<Item> items) {
    this.items = items;
  }

}

public class Item {
  @JacksonXmlProperty(localName = "name")
  private String name;

  public Item() {
    
  }
  
  public String getName() {
    return name;
  }

  public void setName(String name) {
    this.name = name;
  }

}

订单.xml

<order>
    <name>123</name>
    <items>
        <item>
            <name>a</name>
        </item>
        <item>
            <name>b</name>
        </item>
    </items>
</order>

结果 Order.json

{
  "Order" : {
    "name" : "123",
    "items" : [ {
      "name" : "a"
    }, {
      "name" : "b"
    } ]
  }
}

希望能帮助到你。


推荐阅读