Groovy - игнорировать дополнительные атрибуты на карте во время создания объекта
Есть ли способ сделать groovy игнорировать дополнительные атрибуты на карте во время создания объекта? Пример:
class Banana{
String name
}
def params = [name:'someGuy', age:13]
new Banana(params)
В этом примере groovy выбрасывает такое свойство: исключение по возрасту (очевидно, потому что возраст не определен в классе Banana). Не прибегая к ручному отображению только желаемых атрибутов из карты в конструктор класса Banana, есть ли способ сказать Банане игнорировать дополнительные атрибуты?
Я заметил, что классы домена Grails не страдают от этой проблемы, и мне бы хотелось, чтобы здесь было такое же поведение!
Спасибо за вашу помощь и совет!
Ответы
Ответ 1
К сожалению, нет встроенного способа сделать это в groovy. Grails делает это, создавая собственные конструкторы для объектов домена. Простым обходным путем является использование такого конструктора:
Banana(Map map) {
metaClass.setProperties(this, map.findAll { key, value -> this.hasProperty(key) })
}
Ответ 2
Существует более простой способ справиться с этим случаем.
В вашем bean просто реализуйте признак
trait IgnoreUnknownProperties {
def propertyMissing(String name, value){
// do nothing
}
}
class Person implements IgnoreUnknownProperties {
String name
}
map = ["name": "haha", "extra": "test"]
Person p = new Person(map)
println p.name
Ответ 3
Другой способ, который не влияет на производительность, если присутствуют все свойства:
public static Banana valueOf(Map<String, Object> params) {
try {
return new Banana(source)
} catch (MissingPropertyException e) {
log.info(e.getMessage())
source.remove(e.property)
return valueOf(source)
}
}
Ответ 4
Как и @JiankuanXing ответ (который является идеальным ответом :)
), но вместо trait
ваш класс может расширять Expando
и добавьте метод propertyMissing
:
class Banana extends Expando {
String name
def propertyMissing(name, value) {
// nothing
}
}
def params = [name:'someGuy', age:13]
new Banana(params)
Использование trait
подходит, вероятно, лучше в этом случае, поскольку оно позволяет создавать поведенческую композицию, и вы можете добавить trait
ко всему объекту класса, который в этом нуждается. Я добавляю только эту альтернативу, так как Expando
можно использовать, так как groovy 1.5
версия, а traits
введены в groovy 2.3
.
Надеюсь, что это поможет,