Карта JAXB XmlJavaTypeAdapter из списка: плюсы и минусы этого шаблона проектирования - PullRequest
2 голосов
/ 24 сентября 2010

Я написал отображение JAXB, которое сохранило подсписок внутри корневого элемента в LinkedHashMap<String, Object> вместо Collection<Object>, поддерживаемом через определенный XmlJavaTypeAdapter. Ниже приведен образец:

@XmlRootElement
public class Parent {
    @XmlJavaTypeAdapter(ListToMapAdapter.class)
    @XmlElement
    private LinkedHashMap<String, Child> children;

    ...
}

Ключ строится из атрибутов дочернего тега (например, <child id="key"> дает Map.Entry<String, Child>, как {key => child}.

Один из моих коллег говорит, что он плохо спроектирован, и что этот Map должен быть в объекте, отвечающем за демонтаж XML. Я не согласен с ним. Вот некоторые плюсы и минусы такого подхода. Какой дизайн вы считаете лучшим? И какие плюсы и минусы вы видели, чтобы завершить дискуссию?

Цель данного проекта:

  • Map дает возможность эффективно искать детей с критериями (ключ в моем образце) вместо поиска по итерации в Collecion.

Плюсы:

  • Ответственность за поиск и фильтрацию подсписка находится ближе всего к объекту, а родительский объект отвечает за извлечение и фильтрацию его дочернего элемента,
  • Построение Map автоматически выполняется JAXB при демаршаллинге: элегантный, эффективный и не позволяет построить Map с последующей обработкой списка после umarshalling (итерация) ,
  • один и тот же объект в разных читателях все еще имеет возможность фильтрации своих потомков,
  • субъективно, это действительно красивый способ сделать это :),
  • , если @XmlJavaTypeAdapter существует, это отчасти для этого (многочисленные примеры этого в Интернете).

Минусы (некоторые от моего коллеги) :

  • Ограничения ограничения JAXB для кода конкретной реализации вместо интерфейса: не удалось объявить Map<String, Child> в моем примере (не может быть создан JAXB во время демаршаллинга),
  • может быть (и это аргумент моего коллеги), это не роль отображающего объекта (по его словам, простой POJO), чтобы иметь такое поведение,
  • @XmlJavaTypeAdapter предназначен только для преобразования простого объекта в определенные типы: xs:date во время Joda *, например, 1059 *.

Заранее благодарим за ваши 2 цента.

Ответы [ 2 ]

6 голосов
/ 25 сентября 2010

Я всегда рекомендую, чтобы люди разработали наилучшую модель для своего применения.Затем позвольте JAXB справиться со сложностью сопоставления его с XML.В этом случае, если для родителя имеет смысл иметь карту детей, то во что бы то ни стало смоделируйте его таким образом.JAXB действительно имеет некоторую поддержку Map, но с описанным вами представлением XML вам нужно будет использовать XmlAdapter.Для получения дополнительной информации см .:

Все плюсы кажутся разумными.Ни один из минусов недействителен:

  • Как видно из приведенного выше примера при использовании @XmlJavaTypeAdaper, ваше свойство НЕ ограничено конкретной реализацией Map.
  • XmlAdapter является внешнимк модели POJO, поэтому модель не имеет списка поведения карты / из карты.
  • XmlAdapter предназначен для того, чтобы быть универсальным для любого сложного варианта использования карты.Он не ограничен только простыми объектами.Обычный вариант использования предназначен для отображения экземпляров Map.

Если вы хотите исключить элемент-оболочку, вы можете использовать расширение @XmlPath в реализации MOXy JAXB.Класс Foo из моей статьи в блоге будет немного изменен:

import java.util.HashMap;
import java.util.Map;
import javax.xml.bind.annotation.*;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import org.eclipse.persistence.oxm.annotations.XmlPath;

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Foo {
    @XmlJavaTypeAdapter(MyMapAdapter.class)
    @XmlPath(".")
    Map<Integer, String> map = new HashMap<Integer, String>();

    public Map<Integer, String> getMap() {
        return map;
    }

    public void setMap(Map<Integer, String> map) {
        this.map = map;
    }
}

Для получения дополнительной информации см .:

1 голос
/ 27 сентября 2010

Спасибо за ваши основные моменты.Теперь я убежден, что мой путь - это хороший путь, и что мой коллега должен пересмотреть свое мнение: -).

Я посмотрел ваш пост в блоге.Действительно, я успешно добился отмены соединения с адаптером на интерфейсах.Не знаю, почему я до сих пор не смог этого сделать.

Все еще остающаяся проблема, я все еще не могу отобразить список элементов, не вложенных в обертку элементов, как описано здесь: http://weblogs.java.net/blog/2005/04/22/xmladapter-jaxb-ri-ea. Как и вы, и как это объясняется в JavaDoc, мне нужно использовать промежуточный объект-обертку (MyMapType) в вашем примере.Можно ли напрямую создать XmlJavaTypeAdapter<List<WrappedObject>, Map<String, WrappedObject>> вместо помещения List в ListWrapper<WrappedObject>?Я, конечно, сделаю отдельную публикацию этого вопроса таким образом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...