使用MOXy进行不一致的解组

时间:2011-05-22 03:24:14

标签: java jaxb eclipselink unmarshalling moxy

我正在使用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);
    }
}

记录类     package 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>

1 个答案:

答案 0 :(得分:1)

<强>问题

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

解决方案#1

您需要告诉MOXy未映射父属性,您可以通过在@XmlAccessorType(XmlAccessType.NONE)AggregateRecord类上指定AggregateReport来执行此操作:

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

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

然后在@XmlAccessorType(XmlAccessType.PROPERTY)SpecificAggregateRecord类上指定SpecificAggregateReport

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

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

解决方案#2

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

如果您有兴趣探索此选项,请与我们联系。