Установка полей объекта из HashMap
Есть ли библиотека, которая может делать следующее?:
Учитывая объект и HashMap, он перечисляет ключи Hashmap и просматривает сеттеры для этих ключей в объекте и устанавливает связанные значения. Что-то похожее на это:
public Object setData(Object object, HashMap<String, Object> fields) {
for (Entry<String, Object> entry : fields.entrySet()) {
Method m = object.getClass().getMethod("set" + entry.getKey(), entry.getValue().getClass());
if (m != null) {
m.invoke(object, entry.getValue());
}
}
return object;
}
Задача выглядит просто с первого взгляда, но есть некоторые нюансы, на которые я надеюсь, что кто-то уже позаботился. Как вы знаете, изобретать колесо (хорошее колесо) - плохой подход.
Ответы
Ответ 1
Посмотрите на Apache Commons BeanUtils
org.apache.commons.beanutils.BeanUtils.populate(Object bean, Map properties)
Javadoc:
Заполните свойства JavaBeans указанного bean на основе указанных пар имя/значение. Этот метод использует API-интерфейсы отражения Java для идентификации соответствующих имен методов "set setter" и рассматривает аргументы setter типа String, boolean, int, long, float и double.
Ответ 2
Лучше использовать BeanUtils
класс:
public Object setData(Object object, HashMap<String, Object> fields) {
for(Entry<String, Object> entry : fields.entrySet()) {
BeanUtils.setProperty(object, entry.getKey(), entry.getValue());
}
return object;
}
Ответ 3
У меня есть класс BeanAsMap
, который я написал давно. Метод asMap
возвращает Map
, который представляет собой представление на Java bean (POJO). Вы можете вызвать putAll
на Map
, передав ему Map
, из которого вы хотите скопировать данные.
Не стесняйтесь использовать мой код, упомянутый выше.
Пример:
MyClass bean = ...;
Map<String, Object> inputData = ...;
Map<String, Object> view = BeanAsMap.asMap(bean);
view.putAll(inputData);
Ответ 4
BeanUtils в порядке.
Но, как хорошая практика, я не буду писать код, который использует отражение. Или как последнее решение, которое у меня есть, если никто другой не найден.
Этот код нельзя отслеживать в среде IDE, например Eclipse (без иерархии вызовов), что заставляет разработчика думать, что сеттеры никогда не вызываются. Он может сломать ваш код и все еще будет компилироваться.
Слишком высокий уровень абстракции, подобный этому, затрудняет понимание кода.
Код, который обфускается, будет нарушен самим обфускатором при написании таких вещей.
Лучшим решением было бы переосмыслить использование отражения для установки полей объекта.
Ответ 5
Отметьте http://commons.apache.org/beanutils/, в частности BeanUtils.populate()
:
http://commons.apache.org/beanutils/v1.8.3/apidocs/index.html