marshal JAXB使用Apache camel

时间:2016-03-06 14:57:54

标签: jaxb apache-camel

为了使用Apache Camel编组jaxb类,jaxb类需要包含一个XmlRootElement注释。

从XSD生成jaxb类时,可能不会生成XmlRootElement注释。

这将在编组期间导致异常  “没有类型转换器可用于转换类型:”

一旦我手动添加@XmlRootElement,一切正常,但由于生成了这些Jaxb类,手动添加anntotation是没有选择。

根据这种情况下的Camel文档,JaxbDataFormat可以设置为'fragement(true)

JaxbDataFormat jaxbMarshal = new JaxbDataFormat();
jaxbMarshal.setContextPath(ObjectFactory.class.getPackage().getName());
jaxbMarshal.setFragment(true);

不幸的是,我仍然得到同样的例外。

有没有办法配置JaxbDataFormat不同,即定义作为根元素的JAXBElement,就像我在Java中做的那样

marshaller.marshal( new JAXBElement( new QName("uri","local"),
   MessageType.class, messageType ));

还是有其他策略可用于编组XML吗?

EDIT 使用的路线:

 from("file://inbox").unmarshal(jaxbDataFormat)
.marshal(jaxbDataFormat).to("file://outbox");

stacktrace:

  

java.io.IOException:org.apache.camel.NoTypeConversionAvailableException:无类型转换器   可以从类型:com.xyz.AddressType转换为必需的   type:java.io.InputStream,值为com.xyz.AddressType@32317e9d at   org.apache.camel.converter.jaxb.JaxbDataFormat.marshal(JaxbDataFormat.java:148)   〜[camel-jaxb-2.16.0.jar:2.16.0] at   org.apache.camel.processor.MarshalProcessor.process(MarshalProcessor.java:83)         

...

     

[na:1.8.0_25] at java.lang.Thread.run(Thread.java:745)[na:1.8.0_25]   引起:org.apache.camel.NoTypeConversionAvailableException:不   type转换器可以从类型:com.xyz.AddressType转换为   必需的类型:带有值的java.io.InputStream   com.xyz.AddressType@32317e9d at   org.apache.camel.impl.converter.BaseTypeConverterRegistry.mandatoryConvertTo(BaseTypeConverterRegistry.java:185)         

...

4 个答案:

答案 0 :(得分:1)

我遇到了JaxB的等效行为(生成的类中没有@XmlRootElement注释),我想它来自XML模式中定义根元素的方式。

例如:

<xsd:element name="DiffReport" type="DiffReportType" />
<xsd:complexType name="DiffReportType">
    ...
</xsd:complexType>

它会生成DiffReportType类,而不会生成@XmlRootElement注释。但是如果您直接将root元素定义为以下内容,那么您将在生成的类中获取注释集(在我的示例中,根类的名称为DiffReport)。

<xsd:element name="DiffReport">
    <xsd:complexType>
        ...

注意:我使用第一种方法在模式中定义复杂类型以保持类名一致性。

答案 1 :(得分:0)

您可以使用&#34; partClass&#34; camel的jaxb数据格式的选项。您的问题在camel docs for jaxb中得到了解答,其中描述了如何编组XML片段(或者在没有XmlRootElement批注的情况下生成的XML)。

答案 2 :(得分:0)

使用partClass并提供您希望编组的实际班级名称。在编组的情况下,您还必须提供partNamespace,它是所需XML对象的目标命名空间。

答案 3 :(得分:0)

在骆驼2.17中,不需要@XmlRootElement。从2.21版开始。除非...

org.apache.camel.converter.jaxb.FallBackTypeConverter从以下位置更改了其实现:

protected <T> boolean isJaxbType(Class<T> type) {
    return hasXmlRootElement(type) || JaxbHelper.getJaxbElementFactoryMethod(camelContext, type) != null;
}

收件人:

protected <T> boolean isJaxbType(Class<T> type) {
    if (isObjectFactory()) {
        return hasXmlRootElement(type) || JaxbHelper.getJaxbElementFactoryMethod(camelContext, type) != null;
    } else {
        return hasXmlRootElement(type);
    }
}

默认情况下,isObjectFactory()方法返回false。如果您将CamelJaxbObjectFactory上的属性CamelContext设置为true。那么JaxbHelper.getJaxbElementFactoryMethod(camelContext, type)将返回true,反序列化将像以前一样再次进行,而无需使用@XmlRootElement。为了完整性:

<camelContext xmlns="http://camel.apache.org/schema/spring" id="camelContext">
    <properties>
        <property key="CamelJaxbObjectFactory" value="true"/>
    </properties>
</camelContext>