java - Java JAXB 从 XML 中解组 null 值
问题描述
尝试将 XML 中的值提取到 Java 中时遇到了一些问题。我的 XML 文件的示例输入:
<?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>
我的 XML 文件的 Java 类:
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 + '\'' +
'}';
}
}
我提取值的代码:
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();
}
在提取值之前,我确实尝试循环节点直到它与“BlacklistCodeSet”匹配。但是,打印出来的值是 null 并且没有抛出错误消息。
有任何想法吗?谢谢!
解决方案
为了让 JAXB 在那时解析到该类,XML<BlacklistCodeSet>
必须是:
<BlacklistCodeSet>
<blackListCode>D</blackListCode>
<entityId>58241962</entityId>
</BlacklistCodeSet>
如果您创建一个实例BlackListCode
并使用 JAXB 编组为 XML,您可以自己看到这一点。这是“调试”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);
如您所见,JAXB 所需的 XML 与您提供给 JAXB 的实际 XML 大不相同。这些元素甚至没有正确命名,以小写字母开头,因此您需要指定@XmlElement
注释以正确命名它们,并且您需要额外的对象来获得更复杂的 XML。
@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;
}
}
测试
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);
输出
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<BlacklistCodeSet>
<ClEntityIdInfoExt>
<EntityId>58241962</EntityId>
</ClEntityIdInfoExt>
<GeneralCollectionEntityInfoExt>
<BlacklistCode>D</BlacklistCode>
</GeneralCollectionEntityInfoExt>
</BlacklistCodeSet>
现在生成的 XML 与预期的 XML 匹配,JAXB 可以正确地将 XML 解组到对象中。
推荐阅读
- gradle - gradle maven 发布插件:无法通过“发布”上传 zip
- django - CreateView 错误 NOT NULL 约束失败:members_experience.CustomUser_id
- flutter - Flutter 中类似 Laravel 的路由模式
- r - 从句子转换器创建对象时 GPU 内存泄漏
- java - 快速提问,为什么我的指数有上限?
- loopback - 如何将服务注入 Loopback JS 中的其他服务?
- c# - Entity Framework 3.1 一对多插入数据
- java - Sparkcontext 在侦听器内停止
- python - 使用单个刮板获取多个产品的数据
- vue.js - Vuetify:带有字符串数组的数据表