Глубокая копия bean-компонента со стратегией создания экземпляров нулевого свойства - PullRequest
2 голосов
/ 02 июля 2010

Я ищу самый простой способ сделать глубокую копию плоской карты вложенных свойств для bean-компонента. Некоторые из вложенных свойств являются интерфейсами, для которых я хотел бы предоставить стратегию создания экземпляров. Например:

Map<String, String> customer = new Map<String, String>();
customers.put("id", "123");
customers.put("address.line1", "221B Baker St.");

public class Customer {
  private int id;
  private Address address; //address is an interface
  ... getters/setters ...
}

Обратите внимание, что я не хочу предоставлять явные сопоставления, а просто стратегию предоставления конкретного экземпляра для интерфейса. Я предполагал, что commons-beanutils должны это сделать, но это открытая JIRA заявка на функциональность. Библиотека с похожей функциональностью - Google GSON, которая предоставляет интерфейс под названием InstanceCreator .

.

Я реализовал решение поверх beanutils, но есть ли библиотека преобразования компонентов, в которую встроена эта функция?

Ответы [ 2 ]

0 голосов
/ 02 июля 2010

Я думаю, вы можете сделать это более трудным, чем могло бы быть.Что бы я сделал, это сериализовать в и из разметки или какой-то другой формат.Я не уверен, каковы ваши требования, но JAXB , XStream и т. Д. Все превосходные маршалеры, чтобы сделать это.

С JAXB вы могли бы сделать что-токак:

@XmlRootElement(name="customer")
public class Customer
{
    private int id;
    private Address address;
}

@XmlRootElement(name="address")
public class Address
{
    private String city;
}

И со следующим XML:

<customer>
    <id>1234</id>
    <address>
        <city>Kansas City</city>
    </address>
</customer>

... может быть маршалировано и не маршалировано туда-сюда.Кроме того, существует несколько других реализаций маршаллера JAXB (например, jersey-json), поэтому вы также можете маршалировать в других форматах:

{
    "customer": 
    {
        "id":1234,
        "address": 
        {
             "city":"Kansas City"
        }
    }
}

Есть ли конкретная причина, по которой вам нужно использовать Map?Если нет, то вы только разрешение - это какая-то сложная утилита Reflections, и мы надеемся, что что-то вроде библиотеки GSON может облегчить сложность.

Редактировать: Только что увидел, что вы не хотите отображений ... Я не оченьпонять это.После использования сериализации, любой другой способ сделать что-то похожее не имеет смысла.

0 голосов
/ 02 июля 2010

Вы как бы выражаете две разные вещи. проще всего сделать то, что вы, по-видимому, изначально описываете глубоко вложенные карты строк. Так

put("id", "1")  -> map.put("id", "1")
put("address.line1", "221b")  -> ((Map)map.get("address")).put("221B")

(для краткости я игнорирую фактические проверки безопасности - это карта там, если это так, инициализирую, йадда йадда, все те вещи, которые заставляют нас любить сжатый способ работы Java).

и поставьте "a.b.c.d ..." просто рекурсивно сверлит разделение на "."

Если вы действительно хотите «адрес». (поскольку вы ссылаетесь на класс Address в вашем примере) для ссылки на объект типа Address, это немного сложнее, вам понадобится что-то, что распознает префикс как класс, предпочтительно что-то пользовательское, которое отвечает на карту интерфейс, может быть легко создан при прохождении дерева и знает, как создавать свои объекты из входных строк.

Я не уверен насчет деталей реализации beanutils, первая, это не так уж сложно написать. Но вложенная карта строк очень проста. Вы можете легко упаковать это с помощью сериализации (так как hashmaps и строки сериализуют) или библиотекой json, которая должна принимать вложенную карту строк без каких-либо проблем (Google gson работает хорошо).

...