2013-05-11 2 views
3

Я хочу выборочно сериализовать поля на основе запроса и пользователя.Как сообщить JAXB, какие поля сериализуются во время выполнения?

Например, пользователю admin будет предоставлен XML с некоторыми дополнительными полями. В то время как обычный пользователь получит XML без этих полей.

Во-вторых, в настоящее время я использую @XmlIDREF, чтобы предотвратить ненужное расширение ссылочных объектов или коллекций.

Но иногда пользователю могут понадобиться эти детали. Сделать второй запрос для ссылочного объекта нежелательно. Я хочу, чтобы пользователь сообщил серверу, что атрибут XYZ должен быть расширен (т. Е. Включать полный объект, а не только его ссылку)

Учитывая пользователя и запрос на основе бизнес-логики, я могу определить, какие поля должны быть сериализованы , Теперь, как мне передать эту информацию JAXB?

Насколько это возможно, я не хочу создавать XSD. Обратите внимание, что параметры запроса являются динамическими. Какие поля для сериализации определяются во время выполнения. Поэтому я не могу использовать то, что должно быть жестко закодировано - например, @Transient или @XmlIDREF аннотации.

ответ

2

Примечание: Я EclipseLink JAXB (MOXy) свинца и член группы экспертов JAXB (JSR-222).

В EclipseLink 2.5 (получите его здесь: http://www.eclipse.org/eclipselink/downloads/milestones.php) мы добавили новую функцию MOXy JAXB, называемую Object Graphs.Графики объектов позволяют программно или через метаданные выбирать подмножество свойств, которые вы хотите маршалировать/развязать. Ниже приведен пример создания графа объектов для получения подмножества данных из моделей Customer, Address и PhoneNumber.

// Create the Object Graph 
    ObjectGraph contactInfo = JAXBHelper.getJAXBContext(jc).createObjectGraph(Customer.class); 
    contactInfo.addAttributeNodes("name"); 
    Subgraph location = contactInfo.addSubgraph("billingAddress"); 
    location.addAttributeNodes("city", "province"); 
    Subgraph simple = contactInfo.addSubgraph("phoneNumbers"); 
    simple.addAttributeNodes("value"); 

    // Output XML - Based on Object Graph 
    marshaller.setProperty(MarshallerProperties.OBJECT_GRAPH, contactInfo); 
    marshaller.marshal(customer, System.out); 

Для получения более подробной информации

+0

Спасибо, это приятно. Работает хорошо. Однако у меня есть проблема с маршалингом полей ID в подграфе. У меня есть список объектов класса A (завернутый в JaxbList). Каждый объект класса А, в свою очередь, имеет список объектов класса В. Я создаю граф объектов, перейдя в JaxbList.class. Из этого я создаю подграф для B. A сериализуется, как ожидалось, но поле идентификатора подграфа не сериализуется. Если я попытаюсь выполнить маршалинг, удерживая B в качестве основного графика (вместо подграфа), тогда поле ID сериализуется, как ожидалось. Любая идея, что может быть неправильным? Я пробовал комментировать аннотацию XmlID. Это все еще происходит. – Dojo

1

Я также не буду пытаться копаться в XSD. Вот мой совет:

1- По умолчанию JAXB не должен сериализовать нулевые поля. Итак, вы можете просто аннулировать поля, вы не хотите сериализовать.

Чтобы быть немного более чистым, я бы рекомендовал вам аннулировать копии ваших бизнес-объектов. Просто убедитесь, что у вас не будет побочных эффектов в приложениях.


2- Вы также можете сделать ваши поля динамическим, используя карту и хранения <String, Object>. Это позволит вам полностью контролировать жизненный цикл ваших полей.

Редактировать: Ключ будет вашим именем переменной, и значение будет ссылкой на объект. Если ваше значение должно было быть примитивным, вы можете автоматически боксировать свое значение в ассоциированный контейнер объекта. Затем JAXB сериализует все существующие значения с карты.

Если вам нужно было разделить определение ключа на нескольких классах, я бы рекомендовал вам инкапсулировать создание/уничтожение (ключ, значение) в другой класс.


3- Если вы хотите обеспечить определенный набор атрибутов, которые могут быть либо пустыми или не в то же самое время, и если следующая абстракция имеет смысл для вашего приложения. Вы также можете определить подмножество дочернего класса с разными атрибутами. Родительский класс будет иметь обязательные атрибуты.

Успехов

+0

Спасибо. Я думал о том, чтобы сделать что-то похожее на пункт 1. Но это не очень аккуратно. Скажем, объекты A ссылаются на B. Я, очевидно, не буду использовать XmlIDREF для ссылки на B, поскольку это предотвратит расширение B. Но теперь, когда я не хочу расширять B, мне нужно установить все поля B в null, кроме поля, содержащего идентификатор. Не очень красиво, но может быть сделано и до сих пор выглядит как лучший вариант. Не могли бы вы уточнить пункт 2? – Dojo

+0

Я продумал пункт 2, чуть ниже него. Это также очень простой подход. Если вам интересно, вы можете искать другие способы реализации «динамических полей» (http://stackoverflow.com/questions/3127189/java-classes-with-dynamic-fields) – Cyril

Смежные вопросы