Непоследовательный демаршаллинг с МОКСИ - PullRequest
1 голос
/ 22 мая 2011

Я использую MOXy для демонтажа относительно простого XML-документа, но у меня непоследовательное поведение. Документ состоит из двух элементов с базовой информацией (имя и дата), за которыми следует список записей. Проблема в том, что имя и дата каждый раз корректно выводятся неверно, однако я часто не получаю никаких записей (это было проверено с помощью модульного теста, использующего одни и те же статические данные, но проходящего и терпящего неудачу без наблюдаемой предсказуемости). Все записи и утверждения подтверждают, что все выглядит хорошо, за исключением того, что иногда я получаю все 6 записей, а иногда я получаю 0 (никогда никаких других чисел). Такое противоречивое поведение не имеет для меня никакого смысла, есть идеи? Я пропустил аннотацию или что-то, что обеспечило бы правильное распаковывание?

Я пробовал несколько разных версий библиотеки eclipselink, все с одинаковыми результатами (в настоящее время я загружаю 2.2.0 из репозитория eclipselink maven).

Класс отчета

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>

1 Ответ

1 голос
/ 24 мая 2011

Проблема

Несоответствующее поведение связано с переопределением свойств в дочернем классе.MOXy считает, что свойства как родительского, так и дочернего класса сопоставляются, и в зависимости от обработанного порядка вы наблюдаете одно или другое поведение.

Solution # 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.Ниже приведен пример:

Пожалуйста, дайте мне знать, если вы заинтересованы в изучении этого варианта.

...