Search code examples
javaxmlmarshalling

Unable to get the value of a parameter starting with capital letter while unmarshalling


I'm trying to use unmarshalling to create an object using xml string. This is the code that I'm using. But I'm unable to get the value of a parameter(MemResponse) that is not in camelcase, rest parameters are getting set properly.

Earlier I was not using the jsonproperty annotation, I googled for this issue and got to know about this annotation. However, after using the annotation also. MemResponse field is still getting null value.

JAXBContext jc = JAXBContext.newInstance(Transaction.class);
Unmarshaller unmarshaller = jc.createUnmarshaller();
StreamSource streamSource = new StreamSource(new StringReader(content));
JAXBElement<Transaction> jaxbElement = unmarshaller.unmarshal(streamSource, Transaction.class);

The transaction class is as follows

public class Transaction
{
    private String transType;

    private String xmlDate;

    private String source;

    private String xmlVersion;

    @JsonProperty("MemResponse")
    private MemResponse MemResponse;
}

This is the MemResponse class

public class MemResponse
{
    @JsonProperty("DependantDetail")
    private DependantDetail[] DependantDetail;

    @JsonProperty("Telephone")
    private Telephone Telephone;

    @JsonProperty("Address")
    private Address[] Address;

    @JsonProperty("MemberDetail")
    private MemberDetail MemberDetail;
}

This is my sml string

<Transaction>\n  
    <xmlVersion>1</xmlVersion>\n
    <xmlDate>25/11/2011</xmlDate>\n
    <source>MACROMOBI</source>\n
    <transType>MEMDETAIL</transType>\n
    <MemResponse>\n    
        <MemberDetail>\n      
            <joinDate>01/07/2007</joinDate>\n
            <leftDate>31/01/2008</leftDate>\n
            <employerCode></employerCode>\n
            <depCount>2</depCount>\n
            <langPref>ENG</langPref>\n
            <nextMemberNo/>\n
            <nextPlanCode/>\n
        </MemberDetail>\n
        <DependantDetail>\n      
            <depNum>01</depNum>\n
            <initials>G</initials>\n
            <depTitle>MR</depTitle>\n
            <gender>M</gender>\n
            <maritalStatus>S</maritalStatus>\n
            <joinDate>01/07/2007</joinDate>\n
            <leftDate>31/01/2008</leftDate>\n
            <relation>SELF</relation>\n
            <depType>PM</depType>\n
        </DependantDetail>\n
        <DependantDetail>\n      
            <depNum>02</depNum>\n
            <initials>S</initials>\n
            <depTitle>MRS</depTitle>\n
            <birthDate>20/11/1944</birthDate>\n
            <gender>F</gender>\n
            <maritalStatus>S</maritalStatus>\n
            <joinDate>01/07/2007</joinDate>\n
            <benefitStart>01/07/2007</benefitStart>\n
            <leftDate>31/01/2008</leftDate>\n
        </DependantDetail>\n
        <Telephone>\n      
            <contType>MVWORK</contType>\n
            <dialCode>+</dialCode>\n
            <dialNum>5</dialNum>\n
            <smsFlag/>\n
        </Telephone>\n
        <Address>\n      
            <contType>PM</contType>\n
            <addr02>MORNINGSIDE</addr02>\n
            <addr04/>\n
            <town>MUTARE</town>\n
            <postCode>0000</postCode>\n
        </Address>\n
        <Address>\n      
            <contType>RM</contType>\n
            <addr02>MORNINGSIDE</addr02>\n
            <addr03>MUTARE</addr03>\n
            <addr04/>\n
            <postCode>0000</postCode>\n
        </Address>\n
    </MemResponse>\n
</Transaction>\n

enter image description here


Solution

  • You can't use @JsonProperty to deserialize your transaction object because you are dealing with XML and @JsonProperty is specific to JSON.

    Instead, put an @XmlRootElement annotation on your Transaction class, and an @XmlElement annotation on all fields. Below is what your Transaction class should look like, I'll leave it up to you to make the same changes to MemResponse and other classes:

    import javax.xml.bind.annotation.XmlElement;
    import javax.xml.bind.annotation.XmlRootElement;
    
    @XmlRootElement
    public class Transaction {
        @XmlElement
        private String transType;
    
        @XmlElement
        private String xmlDate;
    
        @XmlElement
        private String source;
    
        @XmlElement
        private String xmlVersion;
    
        @XmlElement(name = "MemResponse")
        private MemResponse memResponse;
    }
    

    You don't have to specify the name within the @XmlElement annotation if the element name matches the field name. However, as an example, I've given the memResponse field an initial lower-case letter, to fit with the Java naming convention for fields, and specified that this should use the element name MemResponse in the annotation.