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

Он выполняет все, что я ищу, за исключением того, что для того, чтобы подклассы были правильно маршалированы и немаршалированы, они должны быть заключены в класс с определенным @XmlRootElement. Это не позволяет вам самостоятельно представлять классы как Xml.

Я хочу иметь такие классы:

import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;   

@XmlJavaTypeAdapter(ContactMethodAdapter.class) 
public abstract class ContactMethod {   

}

public class Address extends ContactMethod {       

    protected String street;      
    protected String city;   

}

public class PhoneNumber extends ContactMethod {       

    protected String number;   

}

И я хочу иметь возможность выполнять следующие действия:

Вход:

<contact-method>
   <street>Broadway</street>
   <city>Seattle</city>
</contact-method>

Основной:

public class Demo {       
   public static void main(String[] args) throws Exception  {         
      ContactMethod meth = (ContactMethod ) unmarshaller.unmarshal(xml);

      if(ContactMethod instanceof Address){
         Address addr = (Address) meth;

         addr.getStreet();

         // etc.
      }

      Address marshalAddr = new Address("Broadway", "Seattle");       

      Marshaller marshaller = jc.createMarshaller();         
      marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);         
      marshaller.marshal((ContactMethod) marshalAddr, System.out);     
   }   
}

Выход:

<contact-method>
   <street>Broadway</street>
   <city>Seattle</city>
</contact-method>

Кто-нибудь знает, как это можно сделать?

0
Jake B 6 Фев 2014 в 23:31
Какого XML-представления вы пытаетесь достичь? Вы пытаетесь определить подкласс, строго по каким элементам присутствуют?
 – 
bdoughan
7 Фев 2014 в 01:22
По сути, я хотел упорядочить либо номер телефона, либо адрес в корне и дать им возможность демаршалировать их в соответствующий подкласс без необходимости заключать их в список, как в вашем примере. Прочитав этот другой вопрос, вы сказали: «@XmlJavaTypeAdapter применяется только к полям / свойствам, ссылающимся на этот класс, а не тогда, когда экземпляр этого класса является корневым объектом в вашем XML-дереве». Это заставляет меня думать, что я должен сделать еще один класс AdapterContactMethod так же, как вы в XmlAdapter, аннотировать его с помощью XmlRootElement и самостоятельно обработать преобразование подкласса.
 – 
Jake B
7 Фев 2014 в 01:37

1 ответ

Лучший ответ

В итоге я использовал один класс (AdaptedContactMethod) для моделирования абстрактного класса. Затем я обработал маршалинг и демаршалинг для разных подклассов самостоятельно, а не через @XmlJavaTypeAdapter.

Это позволяет вам поместить @XmlRootElement в вашу реализацию AdaptedContactMethod без необходимости заключать его в список.

0
Jake B 13 Фев 2014 в 18:28