Я думаю, что это самый простой способ сделать это, используя JSON stringify, и это может быть лучшим решением в некоторых ситуациях:
JSON.stringify(a1) === JSON.stringify(a2);
Это преобразует объекты a1
и a2
в чтобы их можно было сравнить. Порядок очень важен в большинстве случаев, поскольку он может сортировать объект с помощью алгоритма сортировки, показанного в одном из приведенных выше ответов.
Пожалуйста, обратите внимание, что вы больше не сравниваете объект, а строковое представление объект. Это может быть не совсем то, что вы хотите.
Вы используете право JAXB 2.0? (начиная с JDK6)
существует класс:
javax.xml.bind.annotation.adapters.XmlAdapter<ValueType,BoundType>
, который может разделить на подклассы, и переопределение в соответствии с методами:
public abstract BoundType unmarshal(ValueType v) throws Exception;
public abstract ValueType marshal(BoundType v) throws Exception;
Пример:
public class YourNiceAdapter
extends XmlAdapter<ReceiverPerson,Person>{
@Override public Person unmarshal(ReceiverPerson v){
return v;
}
@Override public ReceiverPerson marshal(Person v){
return new ReceiverPerson(v); // you must provide such c-tor
}
}
Использование сделано как следующее:
@Your_favorite_JAXB_Annotations_Go_Here
class SomeClass{
@XmlJavaTypeAdapter(YourNiceAdapter.class)
Person hello; // field to unmarshal
}
я вполне уверен, при помощи этого понятия, которое можно управлять процессом маршалинга/немаршалинга собой (включая выбор корректное [sub|super] тип для построения).
Следующий отрывок является методом теста Junit 4 с зеленым светом:
@Test
public void testUnmarshallFromParentToChild() throws JAXBException {
Person person = new Person();
int age = 30;
String name = "Foo";
person.name = name;
person.age= age;
// Marshalling
JAXBContext context = JAXBContext.newInstance(person.getClass());
Marshaller marshaller = context.createMarshaller();
StringWriter writer = new StringWriter();
marshaller.marshal(person, writer);
String outString = writer.toString();
assertTrue(outString.contains("</person"));
// Unmarshalling
context = JAXBContext.newInstance(Person.class, RecieverPerson.class);
Unmarshaller unmarshaller = context.createUnmarshaller();
StringReader reader = new StringReader(outString);
RecieverPerson reciever = (RecieverPerson)unmarshaller.unmarshal(reader);
assertEquals(name, reciever.name);
assertEquals(age, reciever.age);
}
важная часть является использованием JAXBContext.newInstance(Class... classesToBeBound)
метод для контекста немаршалинга:
context = JAXBContext.newInstance(Person.class, RecieverPerson.class);
С этим вызовом, JAXB вычислит ссылочное закрытие на определенных классах и распознает RecieverPerson
. Тестовые передачи. И если Вы измените порядок параметров, то Вы доберетесь java.lang.ClassCastException
(таким образом, они будут должны быть переданными в этом порядке).
Разделите Человека на подклассы дважды, однажды для получателя и однажды для отправителя, и только поместите XmlRootElement на эти подклассы (оставляющий суперкласс, Person
, без XmlRootElement). Обратите внимание, что отправитель и получатель оба совместно используют те же базовые классы JAXB.
@XmlRootElement(name="person")
public class ReceiverPerson extends Person {
// receiver specific code
}
@XmlRootElement(name="person")
public class SenderPerson extends Person {
// sender specific code (if any)
}
// note: no @XmlRootElement here
public class Person {
// data model + jaxb annotations here
}
[протестированный и подтвержденный для работы с JAXB]. Это обходит проблему, которую Вы отмечаете, когда несколько классов в иерархии наследования имеют аннотацию XmlRootElement.
Это - возможно также более опрятное и больше подхода OO, потому что он выделяет модель общих данных, таким образом, это не "обходное решение" вообще.
Так как у Вас действительно есть два отдельных приложения, скомпилируйте их с различными версиями класса "Человек" - с приложением для получателя, не имеющим @XmlRootElement(name="person")
на Person
. Мало того, что это ужасно, но и это побеждает пригодность для обслуживания, которую Вы хотели от использования того же определения Человека и для отправителя и для получателя. Его один плюс - то, что это работает.
Я не уверен, почему Вы хотели бы сделать это... это не кажется весь настолько безопасным мне.
Рассматривают то, что произошло бы в ReceiverPerson, имеет дополнительные переменные экземпляра... тогда Вы волновали бы с (я предполагаю), те переменные, являющиеся пустым, 0, или ложь... и что, если пустой указатель не позволяется или число должно быть больше, чем 0?
я думаю, что Вы, вероятно, хотите сделать, читается в Человеке, и затем создайте новый ReceiverPerson из того (вероятно, предоставляют конструктору, который берет Человека).