1

我正在使用 MOXy 解组一个相对简单的 XML 文档,但我的行为不一致。该文档由两个元素组成,基本信息(姓名和日期)后跟记录列表。问题是名称和日期每次都正确解组,但是我经常没有得到任何记录(这已经通过单元测试反复使用相同的静态数据进行验证,但通过和失败却没有观察到可预测性)。所有日志记录和断言验证一切看起来都不错,除了有时我得到所有 6 条记录,有时我得到 0(从来没有任何其他数字)。这种不一致的行为对我来说完全没有意义,有什么想法吗?我是否缺少注释或可以确保正确解组的内容?

我尝试了几个不同版本的 eclipselink 库,结果都相同(目前我正在从 eclipselink maven 存储库加载 2.2.0)。

报告类

package com.company.report_parser.model;

import org.eclipse.persistence.oxm.annotations.XmlPath;

import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import java.util.List;

@XmlRootElement(name="feedback")
public class SpecificAggregateReport extends AggregateReport {
    @XmlPath("submitter/org_name/text()")
    protected void setPartnerName(String partnerName) {
        super.setPartnerName(partnerName);
    }

    @XmlPath("date_range/end/text()")
    protected void setDate(String date) {
        super.setDate(date);
    }

    public List<AggregateRecord> getRecords() {
        return super.getRecords();
    }
    @XmlPath("authstats/record")
    @XmlElement(type=SpecificAggregateRecord.class) // This is the element class which implements the AggregateRecord Interface used in the List
    protected void setRecords(List<AggregateRecord> records) {
        super.setRecords(records);
    }
}

记录类 包com.company.report_parser.model;

import org.eclipse.persistence.oxm.annotations.XmlPath;

public class SpecificAggregateRecord extends AggregateRecord {
    @XmlPath("row/@source_ip")
    protected void setSourceIp(String sourceIp) {
        super.setSourceIp(sourceIp);
    }

    @XmlPath("row/@count")
    protected void setCount(String count) {
        super.setCount(count);
    }

    @XmlPath("identities/@envelope_from")
    protected void setSmtpFrom(String envelope_from) {
        super.setSmtpFrom(envelope_from);
    }

    @XmlPath("identities/@header_from")
    protected void setHeaderFromDomain(String header_from) {
        super.setHeaderFromDomain(header_from);
    }

    @XmlPath("auth_results/dkim/@result")
    protected void setDkimResult(String result) {
        super.setDkimResult(result);
    }

    @XmlPath("auth_results/dkim/@d")
    protected void setDkimDomain(String d) {
        super.setDkimDomain(d);
    }

    @XmlPath("auth_results/spf/@result")
    protected void setSpfResult(String result) {
        super.setSpfResult(result);
    }
}

样本数据

<?xml version="1.0" encoding="UTF-8" ?>
<feedback>
  <submitter>
    <org_name>specific</org_name>
    <email>support@specific.com</email>
  </submitter>
  <date_range>
    <begin>20110511</begin>
    <end>20110511</end>
  </date_range>
  <report_id>682417472261065178</report_id>
  <authstats>
    <record>
      <row source_ip="184.106.220.108" count="8" policy_domain="test.net" policy="none" action_taken="none" />
      <identities envelope_from="test.net" header_from="test.net" />
      <auth_results>
        <dkim result="neutral" d="test.net" />
        <spf domain="test.net" identity="spf_envelope_from" result="pass" />
      </auth_results>
    </record>
    <record>
      <row source_ip="50.56.76.41" count="6" policy_domain="test.net" policy="none" action_taken="none" />
      <identities envelope_from="test.net" header_from="test.net" />
      <auth_results>
        <dkim result="neutral" d="test.net" />
        <spf domain="test.net" identity="spf_envelope_from" result="softfail" />
      </auth_results>
    </record>
    <record>
      <row source_ip="50.56.76.41" count="6" policy_domain="test.net" policy="none" action_taken="none" />
      <identities envelope_from="test.net" header_from="test.net" />
      <auth_results>
        <dkim result="none" d="" />
        <spf domain="test.net" identity="spf_envelope_from" result="softfail" />
      </auth_results>
    </record>
    <record>
      <row source_ip="184.106.220.108" count="6" policy_domain="test.net" policy="none" action_taken="none" />
      <identities envelope_from="test.net" header_from="test.net" />
      <auth_results>
        <dkim result="pass" d="test.net" />
        <spf domain="test.net" identity="spf_envelope_from" result="pass" />
      </auth_results>
    </record>
    <record>
      <row source_ip="50.56.76.41" count="8" policy_domain="test.net" policy="none" action_taken="none" />
      <identities envelope_from="test.net" header_from="test.net" />
      <auth_results>
        <dkim result="pass" d="test.net" />
        <spf domain="test.net" identity="spf_envelope_from" result="softfail" />
      </auth_results>
    </record>
    <record>
      <row source_ip="184.106.220.108" count="6" policy_domain="test.net" policy="none" action_taken="none" />
      <identities envelope_from="test.net" header_from="test.net" />
      <auth_results>
        <dkim result="none" d="" />
        <spf domain="test.net" identity="spf_envelope_from" result="pass" />
      </auth_results>
    </record>
  </authstats>
</feedback>
4

1 回答 1

1

问题

不一致的行为是由于子类中的属性被覆盖。MOXy 认为父类和子类中的属性都被映射,并且根据处理的顺序,您会看到一种行为或另一种行为。

解决方案#1

你需要告诉 MOXy 父属性没有被映射,你可以通过@XmlAccessorType(XmlAccessType.NONE)AggregateRecordAggregateReport类上指定来做到这一点:

import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAccessType;

@XmlAccessorType(XmlAccessType.NONE)
public class AggregateRecord {
   ...
}

然后指定@XmlAccessorType(XmlAccessType.PROPERTY)SpecificAggregateRecordSpecificAggregateReport

import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAccessType;

@XmlAccessorType(XmlAccessType.PROPERTY)
public class SpecificAggregateRecord extends AggregateRecord {

解决方案#2

如果您只是为了应用映射而覆盖子类上的访问器,您可能需要考虑使用 MOXy 的外部映射文件。下面是一个例子:

如果您有兴趣探索此选项,请告诉我。

于 2011-05-24T14:14:54.527 回答