当前位置: 首页 > 知识库问答 >
问题:

Apache Camel JAXB反编组在从Camel从2.20.4升级到2.21.2或2.22.1后返回null属性

鲁辉
2023-03-14

在将Apache Camel从2.20.4升级到2.21.2甚至2.22.1之后,我的单元测试失败了,我不知道为什么。

我有一个接收XML响应的路由,我希望将其解封到一个数据类中。这在Apache Camel 2.21.2之后失败。

JAXB上下文知道给定包中的所有数据类,并选择正确的类。创建了正确的对象本身,但属性保持为NULL。在调试SAX解析器时,SAX解析器似乎故意忽略了标记之间的文本。

@Component
public class NewsletterRoute extends RouteBuilder {

8<-------------------------------------------------

@Override
public void configure() {
    final DataFormat marshalFormat =
        new JacksonDataFormat(HybrisRequest.class);
    final JaxbDataFormat unmarshalFormat = new JaxbDataFormat();
    unmarshalFormat.setContextPath(
       SuccessResponse.class.getPackage().getName());

    from(URI)
        .routeId("subscribeRoute")
        // Fetch the auth token to send it as 'x-csrf-token' header.
        .setHeader(Exchange.HTTP_URI,
            method(this.backendUrlProvider, "getUrl"))
        .setHeader(Exchange.HTTP_PATH,
             constant(this.subscribeUnsubscribePath))
        .setHeader(Exchange.HTTP_METHOD, HttpMethods.POST)
        .setHeader(Exchange.CONTENT_TYPE, constant("application/json"))
        // Marshal body to JSON
        .marshal(marshalFormat)
        .to(String.format("https4:backend" +
                "?sslContextParameters=hybrisSslContextParams" +
                "&x509HostnameVerifier=hybrisHostnameVerifier" +
                // don't throw on 3XX/4XX/5XX since
                // we need the response body 
                "&throwExceptionOnFailure=false" +
                "&cookieStore=#hybrisCookieStore" +
                "&authUsername=%s" +
                "&authPassword=%s" +
                "&authenticationPreemptive=true" +
                "&httpClient.redirectsEnabled=true" +
                "&httpClient.maxRedirects=3" +
                "&httpClient.connectTimeout=%d" +
                "&httpClient.socketTimeout=%d",
            "RAW(" + username + ")",
            "RAW(" + password + ")",
            backendTimeoutMillis,
            backendTimeoutMillis))
        .convertBodyTo(String.class)
        // Store the received response as property before
        // trying to unmarshal it
        .setProperty(PROPERTY_RESPONSE_RAW, body())
        .unmarshal(unmarshalFormat);
    // @formatter:on
    }
}
@XmlRootElement(name = "entry", namespace = "http://www.w3.org/2005/Atom")
public class SuccessResponse {
    private String id;
    private String title;
    public String getId() { return id; }
    public void setId(String id) { this.id = id; }
    public String getTitle() { return title; }
    public void setTitle(String title) { this.title = title; }
    public String toString() { /*code cut out*/}
}

单元测试只是向Mockito发送一个有效的请求,Mockito返回XML。

<?xml version="1.0" encoding="utf-8"?>
<entry xml:base="https://xxx.xxx.xxx.xxx:44380/sap/opu/odata/sap/CUAN_IMPORT_SRV/"
    xmlns="http://www.w3.org/2005/Atom"
    xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata"
    xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices">  
<!-- 8<---------- Code cut out here ----------------------------------- --> 
    <id>bla</id>
    <title type="text">blub</title>
</entry>

有什么想法吗?camel-jaxb中的Bug?

共有1个答案

田焕
2023-03-14

我创建了自定义dataformat,并使用更严格的封送器unmarhaller来捕捉这种类型的错误。它可以帮助你找到真正的原因。

import org.apache.camel.converter.jaxb.JaxbDataFormat;

import javax.xml.bind.*;

public class StrictJaxbDataFormat extends JaxbDataFormat {

    @Override
    protected Unmarshaller createUnmarshaller() throws JAXBException {
        Unmarshaller unmarshaller = super.createUnmarshaller();
        unmarshaller.setEventHandler(new StrictValidationEventHandler());
        return unmarshaller;
    }

    @Override
    protected Marshaller createMarshaller() throws JAXBException {
        Marshaller marshaller = super.createMarshaller();
        marshaller.setEventHandler(new StrictValidationEventHandler());
        return marshaller;
    }

    private static class StrictValidationEventHandler implements ValidationEventHandler {
        @Override
        public boolean handleEvent(ValidationEvent event) {
            return false; // all validation events should throw exception
        }
    }
}

JAXBDataFormat替换为StrictJAXBDataFormat

final StrictJaxbDataFormat unmarshalFormat = new StrictJaxbDataFormat();

我尝试模拟您的代码,它的行为与您所描述的完全一致(IDtitle为空)。当我添加StrictJAXBDataFormat时,它会抛出javax.xml.bind.unmarshalException:意外元素(URI:“http://www.w3.org/2005/atom”,local:“id”)。预期的元素是<{}id>、<{}title>,所以这个问题可能是JAXB反编组错误:预期的元素是<{}root>,您应该将package-info.java添加到您的JAXB类包中。

@XmlSchema(namespace = "http://www.w3.org/2005/Atom", elementFormDefault = XmlNsForm.QUALIFIED)
package your.package;
import javax.xml.bind.annotation.XmlNsForm;
import javax.xml.bind.annotation.XmlSchema;
 类似资料:
  • 您好,我是Jaxb新手,已经花了3个多小时搜索这个NullPointerException和这个解编组的东西,但没有找到适合我的东西。我尝试了inputStream、StringReader和Buffered reader,但当我试图将XML文件解压缩到java对象时,所有这些都导致了空值,下面是一个例外: 这是XML文件:

  • 我在Spring XML中用动态路由器bean定义了路由,如下所示 下面补充日志...请注意“所有步骤都完成了...”声明出现了两次...

  • 我正在开发一个android应用程序,它有一个活动。该活动有一个ViewPager,它使用FragmentStatePagerAdapter加载两个片段。 正在活动的onResume方法上重新创建此适配器。 那是内存溢出错误吗?为什么getActivity()方法在片段似乎被正确加载的情况下返回null? 提前谢谢你

  • 我是springboot的新手,我正在尝试从application.properties文件的位置(src/main/resources)读取属性值。但它总是返回NULL。我也需要帮助。附加类和属性文件。请注意:我试过“https://www.baeldung.com/properties-with-spring”如何访问Spring Boot中application.properties文件中定

  • 为了帮助大伙儿升级,我们为现在的Apache用户提供了一份重要信息的文档说明。这些只是一些简要说明,你可以从新特性文档或src/CHANGES文件中得到更多信息。 这篇文档仅仅描述了从版本 2.0 到 2.2 的变化,如果你是从1.3版进行升级的,请查考从1.3升级到2.0文档。 编译时配置的改变 编译过程与2.0版本非常相似,你曾经使用过的configure命令行(在安装目录下的build/co

  • 为了帮助大伙儿升级,我们为现在的Apache用户提供了一份重要信息的文档说明。这些只是一些简要说明,你可以从新特性文档或src/CHANGES文件中得到更多信息。 编译时配置的改变 Apache现在使用autoconf和libtool系统来进行安装进程的配置。这个系统用起来很像Apache1.3的APACI系统,但并不相同。 在普通的选择编译模块的基础上,Apache2.0把请求进程的主要部分移到