Camel 如何从XSD模式生成JAXB数据格式?

kzmpq1sx  于 2022-11-07  发布在  Apache
关注(0)|答案(1)|浏览(133)

当我尝试使用JAXB并提供XSD模式来编组从ApacheCamel中的数据库获得的数据时,出现以下错误
异常错误:没有类型转换器可用于从类型转换:将java.util.LinkedHashMapMap到所需类型:值为{id=5,编号=5599,类型=B3,...}的java.io.输入流
当我尝试将消息发送到ActiveMQ时,会出现这种情况。我是集成的新手,这是我的实习生Camel项目。当我将消息编组到json时,一切都正常。我曾想过将消息转换为json,然后再转换为XML,但在我看来,这不是我应该做的事情。我已经准备好了一个XSD模式,如下所示:

<?xml version="1.0" encoding="UTF-8" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
       xmlns:pc="com.release11.packages"
       targetNamespace="com.release11.materials">
<xs:import schemaLocation="packages.xsd"
           namespace="com.release11.packages"/>

<xs:simpleType name="materialTypeType">
    <xs:restriction base="xs:string">
        <xs:enumeration value="A1"/>
        <xs:enumeration value="A2"/>
        <xs:enumeration value="A3"/>
        <xs:enumeration value="B1"/>
        <xs:enumeration value="B2"/>
        <xs:enumeration value="B3"/>
        <xs:enumeration value="C1"/>
        <xs:enumeration value="C2"/>
        <xs:enumeration value="C3"/>
    </xs:restriction>
</xs:simpleType>

<xs:complexType name="materialType">
    <xs:sequence>
        <xs:element name="Id" type="xs:integer"/>
        <xs:element name="Number" type="xs:integer"/>
        <xs:element name="Type" type="materialTypeType"/>
        <xs:element name="Name" type="xs:string"/>
        <xs:element name="Description" type="xs:string"/>
        <xs:element name="Is_deleted" type="xs:boolean"/>
        <xs:element ref="pc:Packages" minOccurs="0"/>
    </xs:sequence>
</xs:complexType>

<xs:complexType name="materialsType">
    <xs:sequence>
        <xs:element name="Material" type="materialType" maxOccurs="unbounded"/>
    </xs:sequence>
</xs:complexType>

<xs:element name="Materials" type="materialsType"/>

</xs:schema>

我试着在网上找到答案,但是我没有找到任何有用的东西,或者我不能理解答案,所以我需要有人给我解释一下。请帮助我。
下面是我的代码:

public class InputAdapter {

public static void main(String[] args) throws Exception {

    BasicDataSource dataSource = new BasicDataSource();
    dataSource.setDriverClassName("com.mysql.jdbc.Driver");
    dataSource.setUrl("jdbc:mysql://localhost:3306/Packages");
    dataSource.setUsername("uname");
    dataSource.setPassword("passwd");
    SimpleRegistry registry = new SimpleRegistry();
    registry.bind("dataSource", dataSource);

    ActiveMQConnectionFactory activeMQConnectionFactory = new ActiveMQConnectionFactory();
    activeMQConnectionFactory.setBrokerURL("tcp://127.0.0.1:61616");

    Connection connection = activeMQConnectionFactory.createConnection();
    connection.start();

    Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
    Destination destination = session.createQueue("MESSAGES_RAW");

    MessageProducer producer = session.createProducer(destination);
    producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);

    CamelContext context = new DefaultCamelContext(registry);
    context.addComponent("activemq", JmsComponent.jmsComponentAutoAcknowledge(activeMQConnectionFactory));

    context.addRoutes(new RouteBuilder() {
        @Override
        public void configure() {
            JaxbDataFormat dataFormat = new JaxbDataFormat();
            dataFormat.setSchemaLocation("material.xsd");

            from("timer://foo?repeatCount=1")
                    .setBody(constant("SELECT * FROM material;"))
                    .to("jdbc:dataSource")
                    .split(body())
                    .marshal(dataFormat)
                    .to("activemq:queue:MESSAGES_RAW");
        }
    });
    context.start();
    Thread.sleep(1000);
    context.stop();
}
}
jdgnovmf

jdgnovmf1#

使用CLI工具从XSD生成类

您可以使用JDK 8中预安装的xjc命令行工具来生成jaxb类。

范例:

xjc material.xsd

# With groupId

xjc -p <groupId> material.xsd

# With groupId and bindings configuration file

xjc -p <groupId> -b bindings.xjb material.xsd

使用maven插件从XSD生成类

或者你也可以使用maven插件来做同样的事情。默认情况下,插件会从src/main/xsd中查找模式xsd文件,从src/main/xjb中查找绑定xjb文件

<build>
    <plugins>
        <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>jaxb2-maven-plugin</artifactId>
            <version>2.5.0</version>
            <executions>
                <execution>
                    <id>xjc</id>
                    <goals>
                        <goal>xjc</goal>
                    </goals>
                </execution>
            </executions>
            <configuration>
                <packageName>com.example.group</packageName>
            </configuration>
        </plugin>
    </plugins>
</build>

如果您使用的是JDK 11或更高版本,则还必须包含JDK中不再包含的几个相关依赖项。

<dependencies>
    <dependency>
        <groupId>jakarta.xml.bind</groupId>
        <artifactId>jakarta.xml.bind-api</artifactId>
        <version>2.3.3</version>
    </dependency>
    <dependency>
        <groupId>com.sun.xml.bind</groupId>
        <artifactId>jaxb-xjc</artifactId>
        <version>2.3.6</version>
    </dependency>
</dependencies>

使用这些maven应该在运行mvn clean install后生成target/generated-sources/jaxb文件夹中的类。使用maven插件,您最好为这些创建单独的api项目,并将其作为依赖项添加到您的camel集成项目中。

用于camel

您可以通过使用JAXBContext示例创建JaxbDataFormat来将jaxb与camel结合使用。

JAXBContext jaxbContext = JAXBContext.newInstance(Materials.class);
JaxbDataFormat jaxbDataformat = new JaxbDataFormat(jaxbContext);

from("direct:marshalMaterials")
    .routeId("marshalMaterials")
    .marshal(jaxbDataformat)
    .log("${body}");

由于您要查询的数据库默认返回Map列表,因此您必须将其转换为适当的Jaxb对象。您可以使用生成的ObjectFactory类生成不同的jaxb类示例。
对于JDK 11,您可能还需要以下依赖项

<dependency>
    <groupId>jakarta.xml.bind</groupId>
    <artifactId>jakarta.xml.bind-api</artifactId>
    <version>2.3.3</version>
</dependency>

<!-- versions obtained from dependency-management camel-bom -->
<dependency>
    <groupId>com.sun.xml.bind</groupId>
    <artifactId>jaxb-impl</artifactId>
</dependency>
<dependency>
    <groupId>com.sun.xml.bind</groupId>
    <artifactId>jaxb-core</artifactId>
</dependency>

名称空间从javax更改为jakarta

较新版本的jaxb使用jakarta命名空间而不是javax**,但在编写**时,使用jakarta命名空间有点问题,因为jaxb 2-maven-plugin版本3.0.0+还没有在maven中央存储库中提供,虽然有一些替代方案,但它们仍在进行中。
如果您的xsd不经常更改,则可能只生成类并手动将名称空间更改为jakarta。

绑定XJB文件

通过绑定xjb文件,你可以调整类的生成方式,比如改变类或属性名,防止嵌套类混乱等等。

示例:空绑定文件模板

<?xml version="1.0" encoding="UTF-8"?>
<jaxb:bindings xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" 
    xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    version="2.1" 
    xsi:schemaLocation="http://java.sun.com/xml/ns/jaxb http://java.sun.com/xml/ns/jaxb/bindingschema_2_0.xsd">

    ...

</jaxb:bindings>

相关问题