简体   繁体   中英

Java JAXB unmarshaling null value from XML

I was having some problem when trying to extract values from XML into Java. My sample input of XML file:

<?xml version="1.0" encoding="UTF-8" ?>
 <TRB_TRX xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<HEADER ReqNotf="N" TransactionCode="L9_BLACKLIST_SET" PublisherApplID="CL" PublisherApplThreadID="1" EntityId="58241962" RoutingId="2626289" EntityType="ACCOUNT" IssueDate="2019-06-18T23:59:59" EffectiveDate="2019-06-18T23:59:59"/>
    <DATA>
        <BlacklistCodeSet>
            <TransactionHeaderInfoExt>
                <ApplicationId>CL</ApplicationId>
                <RequestDate>2019-06-18T23:59:59</RequestDate>
            </TransactionHeaderInfoExt>
            <ClEntityIdInfoExt>
                <EntityId>58241962</EntityId>
                <EntityType>ACCOUNT</EntityType>
            </ClEntityIdInfoExt>
            <GeneralCollectionEntityInfoExt>
                <BlacklistCode>D</BlacklistCode>
            </GeneralCollectionEntityInfoExt>
        </BlacklistCodeSet>
    </DATA>
</TRB_TRX>

My Java class for the XML file:

import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name="BlacklistCodeSet")
public class BlackListCode {
    String entityId;
String blackListCode;

public String getEntityId() {
    return entityId;
}

public void setEntityId(String entityId) {
    this.entityId = entityId;
}

public String getBlackListCode() {
    return blackListCode;
}

public void setBlackListCode(String blackListCode) {
    this.blackListCode = blackListCode;
}

@Override
public String toString() {
    return "BlackListCode{" +
            "entityId='" + entityId + '\'' +
            ", blackListCode='" + blackListCode + '\'' +
            '}';
}
}

My code to extract the values:

XMLInputFactory xif = XMLInputFactory.newFactory();

                FileReader reader = new FileReader("src/main/resources/xml/blacklistcode.xml");
                XMLStreamReader xsr = xif.createXMLStreamReader(reader);

                try {
                    JAXBContext jc = JAXBContext.newInstance(BlackListCode.class);
                    Unmarshaller unmarshaller = jc.createUnmarshaller();

                    while (xsr.hasNext()) {
                        while (xsr.hasNext() && (!xsr.isStartElement() || !xsr.getLocalName().equals("BlacklistCodeSet"))) {
                            xsr.next();
                        }
                        if (xsr.hasNext()) {
                            BlackListCode blacklistcode = (BlackListCode) unmarshaller.unmarshal(xsr);
                            log.debug("BLACKLIST CODE IS " + blacklistcode);
                            log.debug("ACCOUNT NO IS " + blacklistcode.getEntityId());
                        }
                    }
                }catch (Exception e){
                    e.printStackTrace();
                }

I did tried to loop the node until it matches "BlacklistCodeSet" before extracting the value. However, the values printed out are null and no error message were thrown.

Any ideas? Thanks!

In order for JAXB to parse into that class at that point, the XML of <BlacklistCodeSet> would have to be:

<BlacklistCodeSet>
    <blackListCode>D</blackListCode>
    <entityId>58241962</entityId>
</BlacklistCodeSet>

You can see this for yourself if you create an instance of BlackListCode and use JAXB to marshall to XML. That is the best way to "debug" JAXB.

BlackListCode blackListCode = new BlackListCode();
blackListCode.setEntityId("58241962");
blackListCode.setBlackListCode("D");

JAXBContext jaxbContext = JAXBContext.newInstance(BlackListCode.class);
Marshaller marshaller = jaxbContext.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(blackListCode, System.out);

As you can see, the XML needed by JAXB differs greatly from the actual XML you give to JAXB. The elements aren't even named right, starting with lowercase letters, so you need to specify @XmlElement annotations to name them correctly, and you need extra objects to get the more complex XML you have.

@XmlRootElement(name = "BlacklistCodeSet")
class BlackListCode {
    private ClEntityIdInfoExt clEntityIdInfoExt;
    private GeneralCollectionEntityInfoExt generalCollectionEntityInfoExt;

    @XmlElement(name = "ClEntityIdInfoExt")
    public ClEntityIdInfoExt getClEntityIdInfoExt() {
        return this.clEntityIdInfoExt;
    }

    public void setClEntityIdInfoExt(ClEntityIdInfoExt clEntityIdInfoExt) {
        this.clEntityIdInfoExt = clEntityIdInfoExt;
    }

    @XmlElement(name = "GeneralCollectionEntityInfoExt")
    public GeneralCollectionEntityInfoExt getGeneralCollectionEntityInfoExt() {
        return this.generalCollectionEntityInfoExt;
    }

    public void setGeneralCollectionEntityInfoExt(GeneralCollectionEntityInfoExt generalCollectionEntityInfoExt) {
        this.generalCollectionEntityInfoExt = generalCollectionEntityInfoExt;
    }

    @Override
    public String toString() {
        return "BlackListCode{entityId='" + this.clEntityIdInfoExt.getEntityId() + '\'' +
                           ", BlacklistCode='" + this.generalCollectionEntityInfoExt.getBlacklistCode() + '\'' + '}';
    }
}
class ClEntityIdInfoExt {
    private String entityId;

    public ClEntityIdInfoExt() {
    }

    public ClEntityIdInfoExt(String entityId) {
        this.entityId = entityId;
    }

    @XmlElement(name = "EntityId")
    public String getEntityId() {
        return this.entityId;
    }

    public void setEntityId(String entityId) {
        this.entityId = entityId;
    }
}
class GeneralCollectionEntityInfoExt {
    private String BlacklistCode;

    public GeneralCollectionEntityInfoExt() {
    }

    public GeneralCollectionEntityInfoExt(String blacklistCode) {
        this.BlacklistCode = blacklistCode;
    }

    @XmlElement(name = "BlacklistCode")
    public String getBlacklistCode() {
        return this.BlacklistCode;
    }

    public void setBlacklistCode(String blacklistCode) {
        this.BlacklistCode = blacklistCode;
    }
}

Test

BlackListCode blackListCode = new BlackListCode();
blackListCode.setClEntityIdInfoExt(new ClEntityIdInfoExt("58241962"));
blackListCode.setGeneralCollectionEntityInfoExt(new GeneralCollectionEntityInfoExt("D"));

JAXBContext jaxbContext = JAXBContext.newInstance(BlackListCode.class);
Marshaller marshaller = jaxbContext.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(blackListCode, System.out);

Output

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<BlacklistCodeSet>
    <ClEntityIdInfoExt>
        <EntityId>58241962</EntityId>
    </ClEntityIdInfoExt>
    <GeneralCollectionEntityInfoExt>
        <BlacklistCode>D</BlacklistCode>
    </GeneralCollectionEntityInfoExt>
</BlacklistCodeSet>

Now that the generated XML matches the expected XML, JAXB can correctly unmarshall the XML into the object.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM