Toon posts:

[java] Universele bean property setter mist in Java

Pagina: 1
Acties:

Verwijderd

Topicstarter
Ik was op zoek naar een stuk code in de Java API waarmee je makkelijk universeel properties van een bean kunt zetten, met name wanneer je je values als string hebt.

Het geheel zou ongeveer zo moeten werken:

Java:
1
BeanSetter.set( myBean, "property", value );


Waarbij de set functie dan ongeveer de volgende signature heeft:

Java:
1
public boolean set (Object bean, String propertyName, String value );


Hierbij wordt propertyName dan automatische omgezet in getPropertyName voor de method name, en wordt value geparsed naar het juiste type wat bij de setter hoort. Dergelijke code is eigenlijk enorm common. Elke situatie waarmee je met een XML file beans configed maakt zou zoiets gebruiken, alsmede EL implementaties en Java EE containers voor de <jsp:setProperty> tag.

Tot mijn verbazing blijkt dergelijke functionaliteit echter gewoon niet in de standaard Java library te zitten. Er is wel een java.bean package, maar de classes daarin zijn gewoon te wazig voor woorden. PropertyEditor lijkt het bijvoorbeeld te kunnen doen, maar is doorspekt van enorm vreemde methods (isPaintable in een non specific GUI package??? |:( ), en kan het dus gewoon niet.

Ik vraag me dus af wie deze functionaliteit nog meer mist in Java, en wie ook vind dat de java.beans package gewoon enorm vaag & onduidelijk opgezet is.

[ Voor 4% gewijzigd door Verwijderd op 21-12-2005 21:53 ]


  • Tubby
  • Registratie: Juni 2001
  • Laatst online: 23:59

Tubby

or not to be

Reflection, bekijk voor de gein de api van het Class object maar eens

[ Voor 75% gewijzigd door Tubby op 21-12-2005 21:57 ]

tubby.nl - Artes Moriendi - q1 - bf1942 - WoT - pubg - LinkedIN


  • Tubby
  • Registratie: Juni 2001
  • Laatst online: 23:59

Tubby

or not to be

Heb verder geen concrete ervaring met beans, maar het lijkt me dat je die setter niet als een static method in een util class wilt hebben maar in een superbean class waar je al je beans van extend.

tubby.nl - Artes Moriendi - q1 - bf1942 - WoT - pubg - LinkedIN


  • zneek
  • Registratie: Augustus 2001
  • Laatst online: 08-02-2025
Ik heb dit ooit eens met Apache BeanUtils gedaan (http://jakarta.apache.org/commons/beanutils/). Daar zit de door jouw beschreven methode in.

Op dit moment werken we met een eigen geschreven (op reflectie gebaseerde) oplossing, met configureerbare converters. Voor een String property is het relatief simpel, maar hoe zou die BeanSetter.set methode een in een HttpRequest aanwezig String weergave van een Entity object om moeten zetten naar de betreffende entity? Daarvoor moet je iets meer doen dan puur via reflectie een setter aanroepen.

Verwijderd

Topicstarter
Tubby schreef op woensdag 21 december 2005 @ 21:54:
Reflection, bekijk voor de gein de api van het Class object maar eens
Grapjas! :+

Dat is de methode waarmee je het doet. Je had net zo goed "method calls" kunnen roepen, want die gebruik je er ook voor. Heck, laten we de hele standard library van Java afschaffen, want (bijna) alles kun je met Java code zelf implementeren, dus waarom zou het in een library zitten? Integer.parseInt() ??? Kun je toch dmv van if's en loops doen??? 8)7

Waar het dus op neer komt is dat nu iedereen telkens een stuk code moet gaan schrijven die handmatig alle getter en setters afloopt, handmatig moet checken welk type de setter als argument heeft en dan handmatig voor alle types conversie code moet gaan oproepen, waar weer fouten in kunnen slopen etc etc...

Het universeel setten van bean properties lijkt me toch zo'n basic functie dat zoiets gewoon standaard in de library hoort.

Verwijderd

Topicstarter
zneek schreef op woensdag 21 december 2005 @ 23:22:
Ik heb dit ooit eens met Apache BeanUtils gedaan (http://jakarta.apache.org/commons/beanutils/). Daar zit de door jouw beschreven methode in.
BeanUtils heb ik inderdaad ook ooit bekeken. Helaas had deze dan weer wat dependencies op andere Apache code (oa voor logging als ik het me goed herinner), wat het toch weer net even te 'bloated' maakt.

edit:

Net even wezen kijken op de homepage van bean-utils, maar ze gaan dit probleem wat ik er eerder mee had gelukkig toch aanpakken. Alleen dat logging zit er dan toevallig nog steeds in.
Voor een String property is het relatief simpel, maar hoe zou die BeanSetter.set methode een in een HttpRequest aanwezig String weergave van een Entity object om moeten zetten naar de betreffende entity? Daarvoor moet je iets meer doen dan puur via reflectie een setter aanroepen.
Een major theme van Mustang is om de common case simple te maken en the rest possible. Een common case is het setten van alle verschillende primitive types voor een bean, wat jij noemt is dan de 'rest'. Laat standaard Java een "BeanSetter" class bevatten die deze common case afhandelt, met een simpele mogelijkheid om StringToObject<T> converters erin te pluggen.

Nu maakt echt iedereen z'n eigen code hiervoor. Grappig dat jij dus ook al weer zelf wat gemaakt hebt. Een vriend van heeft dit ook laatst gedaan, en ik zelf sta ook op het punt dit te doen.

[ Voor 10% gewijzigd door Verwijderd op 21-12-2005 23:40 ]


  • zneek
  • Registratie: Augustus 2001
  • Laatst online: 08-02-2025
Verwijderd schreef op woensdag 21 december 2005 @ 23:32:
[...]


BeanUtils heb ik inderdaad ook ooit bekeken. Helaas had deze dan weer wat dependencies op andere Apache code (oa voor logging als ik het me goed herinner), wat het toch weer net even te 'bloated' maakt.
Daarvoor hebben ze een 1.7 release gedaan, niets nieuws, maar wel een lading van die dependancies eruit gesloopt. Wist ik ook niet, jij zegt het nu, ik las het net toevallig :)
Een major theme van Mustang is om de common case simple te maken en the rest possible. Een common case is het setten van alle verschillende primitive types voor een bean, wat jij noemt is dan de 'rest'. Laat standaard Java een "BeanSetter" class bevatten die deze common case afhandelt, met een simpele mogelijkheid om StringToObject<T> converters erin te pluggen.

Nu maakt echt iedereen z'n eigen code hiervoor. Grappig dat jij dus ook al weer zelf wat gemaakt hebt. Een vriend van heeft dit ook laatst gedaan, en ik zelf sta ook op het punt dit te doen.
Dat kwam voornamelijk omdat we 2 dingen wilden: toegang via een propertypath met beperkingen op diepte e.d. Dus niet order.klant.rechten.godMode=true mee kunnen geven. En omdat we 100% controle over het proces wilden, met multilanguage/locale conversiefoutmeldingen.

  • Tubby
  • Registratie: Juni 2001
  • Laatst online: 23:59

Tubby

or not to be

Verwijderd schreef op woensdag 21 december 2005 @ 23:24:
[...]
Grapjas! :+

Dat is de methode waarmee je het doet. Je had net zo goed "method calls" kunnen roepen, want die gebruik je er ook voor. Heck, laten we de hele standard library van Java afschaffen, want (bijna) alles kun je met Java code zelf implementeren, dus waarom zou het in een library zitten? Integer.parseInt() ??? Kun je toch dmv van if's en loops doen??? 8)7
Het is wat lastig in het begin, maar je kunt er zo een xmlparser mee schrijven die iig de simple types (String, Integer, Boolean) automatisch via reflection kan setten.

Xml element, attributes loopen, per attribute aan de hand van de name de property in de class op zoeken. Daar de type van opvragen, de set method opvragen met de type en naam, invoken met de goede value (Integer.valueOf, Boolean.valueOf), klaar is klara :)

Kanttekening hierbij wel is dat je een goede naamconventie hanteerd voor je setters (lees: eclipse, generate getters and setters :P )

tubby.nl - Artes Moriendi - q1 - bf1942 - WoT - pubg - LinkedIN


  • Cuball
  • Registratie: Mei 2002
  • Laatst online: 16:24
Ik zou toch het common beanutils package gebruiken hoor, meer mensen zouden deze commons packages eens grondig moeten bekijken, je vindt er namelijk tal van functies die je anders zelf zou moeten schrijven !

Java:
1
BeanUtils.setProperty(java.lang.Object bean, java.lang.String name, java.lang.Object value) 

"Live as if you were to die tomorrow. Learn as if you were to live forever"


Verwijderd

Topicstarter
Cuball schreef op donderdag 22 december 2005 @ 08:15:
Ik zou toch het common beanutils package gebruiken hoor, meer mensen zouden deze commons packages eens grondig moeten bekijken, je vindt er namelijk tal van functies die je anders zelf zou moeten schrijven !

Java:
1
BeanUtils.setProperty(java.lang.Object bean, java.lang.String name, java.lang.Object value) 
Ik denk dat ik inderdaad bean utils ga gebruiken. Het ziet er een stuk beter uit als toen ik het eerder probeerde (wel 2 jaar terug ofzo, dus logisch dat het verbeterd is :) ).

Wat ik wel jammer vind van commons is dat het lijkt alsof het common collections team er mee gestopt is. Die heeft echt al lang geen update meer gehad (bijna 2 jaar nu), terwijl die ivm Java 5 generics juist erg nodig is. Het is zelfs zo erg dat er iemand een fork heeft gemaakt en zelf refactored heeft voor generics support.
Het is wat lastig in het begin, maar je kunt er zo een xmlparser mee schrijven die iig de simple types (String, Integer, Boolean) automatisch via reflection kan setten.
Ja, dat weet ik, maar daar gaat het niet om hier. Ik schrijf zo uit het losse handje nog wel 10x zo lastigere code op. Het punt dat ik probeerde te maken is dat zoiets in de standard library hoort. Iedereen gebruikt het, iedereen schrijft z'n eigen versie, en de bean conventie is een hoeksteen van het Java concept. Vanwege die 3 punten is het raar dat het niet in java.beans zit, terwijl die UBERVAGE andere classes er wel in zitten.

Nogmaals over java.beans gesproken, vinden er hier meer mensen dat die package onduidelijk in elkaar zit? Aan de ene kant doen veel classes veels te veel en veel te specificieke dingen, maar aan de andere kant zit er eigenlijk niks in wat je echt kunt gebruiken.

PropertyEditor had ik al genoemd. Dat lijkt meer op een class zoals je die in JFace zou verwachten of in een of andere andere Eclipse package/lib.

Statement is ook een onduidelijke class voor in de bean package. Je moet namelijk zelf het get of set prefix opgeven en de capitalisation doen. Ook moet je het type correct meegeven voor de setter. Het lijkt daarmee meer op z'n plaats in de java.reflect package dan in de beans package.

[ Voor 42% gewijzigd door Verwijderd op 22-12-2005 11:15 ]

Pagina: 1