Apache Camel JAXB unmarshalling возвращает нулевые свойства после обновления с Camel с 2.20.4 до 2.21.2 или 2.22.1 - PullRequest
0 голосов
/ 09 октября 2018

После обновления Apache Camel с 2.20.4 до 2.21.2 или даже 2.22.1 модульный тест моих сбоев, и я не понимаю, почему.

У меня есть маршрут, который получает ответ XML,который я хочу разобрать в классе данных.Это не удалось, так как Apache Camel 2.21.2.

Контекст JAXB знает все классы данных в данном пакете и выбирает правильный класс.Сам правильный объект создается, но свойства остаются нулевыми.При отладке парсера SAX казалось, что парсер SAX намеренно игнорирует текст между тегами.

Я видел на веб-сайте Camel, что Camel 2.21.0 «Обновлен до JAXB 2.3.0».Я не знаю, что это значит для меня.

Мой маршрут выглядит следующим образом:

@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*/}
}

С Apache Camel2.20.4 мой модульный тест сработал.С 2.21.2 и 2.22.1 он ломается.Проблема в том, что демаршаллер не будет заполнять свойства.

Модульный тест просто отправляет действительный запрос в 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?

1 Ответ

0 голосов
/ 11 октября 2018

Я создал пользовательский DataFormat с более строгими Marshaller и 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();

Я попытался смоделировать ваш код, и он ведет себя точнокак вы описали (id и title пусто).Когда я добавил StrictJaxbDataFormat, он выбрасывает javax.xml.bind.UnmarshalException: unexpected element (uri:"http://www.w3.org/2005/Atom", local:"id"). Expected elements are <{}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;
...