PROFESSOR
PROFESSOR

Reputation: 924

Spring Integration Jaxb Unmarshaller mapping Schema variable names instead of @XMLElement values

I have this JAXB-XJC Generated SCHEMA,

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "Response", propOrder = {
    "value",
    "account",
    "hash",
    "tstamp",
    "msg",
    "code",
    "authCode",
    "startBal",
    "endBal"
})
public class Response {

    protected Amount value;
    @XmlElement(required = true)
    protected Account account;
    protected String hash;
    protected TimeStamp tstamp;
    protected String msg;
    @XmlElement(required = true)
    protected String code;
    @XmlElement(name = "auth_code")
    protected String authCode;
    @XmlElement(name = "start_bal")
    protected Amount startBal;
    @XmlElement(name = "end_bal")
    protected Amount endBal;

And my Spring integration uses this unmarshaller

<oxm:jaxb2-marshaller id="abcMarshaller" context-path="com.abc.schema"/>

My Problem is during unmarshalling the XML Elements are mapped using variable name and >not @XMLElement. So 'account' works but 'end_bal' doesn't ( because its looking for >variable named end_bal, but found endBal).

I am on JAVA 17 , Spring 4 and likely on jakarta.xml.bind-api 4.0.2 API.

Please suggest how to fix this primarily within spring integration xml.

Upvotes: 0

Views: 43

Answers (1)

Artem Bilan
Artem Bilan

Reputation: 121462

This has nothing to do with Spring Integration, but rather with JAXB itself. Nevertheless it still works for me:

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType
@XmlRootElement(name = "person")
public class JaxbAnnotatedPerson {

    @XmlElement(name = "firstname")
    private String firstName;

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

}

and unit test against an XML config like this:

<si-xml:unmarshalling-transformer id="unmarshaller" input-channel="unmarshallIn" output-channel="unmarshallOut" unmarshaller="marshallerUnmarshaller" />

<oxm:jaxb2-marshaller id="marshallerUnmarshaller">
    <oxm:class-to-be-bound name="org.springframework.integration.xml.transformer.jaxbmarshaling.JaxbAnnotatedPerson"/>
</oxm:jaxb2-marshaller>>

(With a context-path it fails for me like this:

Caused by: jakarta.xml.bind.JAXBException: "org.springframework.integration.xml.transformer.jaxbmarshaling" doesnt contain ObjectFactory.class or jaxb.index

But I guess that has nothing to do with your problem.)

And junit test is:

@Test
public void testUnmarshalling() {
    StringSource source = new StringSource("<person><firstname>bob</firstname></person>");
    this.unmarshallIn.send(new GenericMessage<Source>(source));
    Message<?> res = this.unmarshallOut.receive(2000);
    assertThat(res).as("No response").isNotNull();
    assertThat(res.getPayload() instanceof JaxbAnnotatedPerson).as("Not a Person ").isTrue();
    JaxbAnnotatedPerson person = (JaxbAnnotatedPerson) res.getPayload();
    assertThat(person.getFirstName()).as("Wrong firstname").isEqualTo("bob");
}

Please, share with us a stack trace for an error you are observing.

Upvotes: 0

Related Questions